<template>
  <div id="tradingview_1355aw2"></div>
</template>

<script>
// import pako from "pako";
import VDatafeed from "./VDatafeed";
import Option from "@/api/option";
import Contract from "@/api/contract";
import Socket from "@/api/server/Socket.js";
import tvStyle from "@/assets/js/tvStyle.js";
import bus from "@/components/bus.js";
import { mapState } from "vuex";
let exchangeAjax = {
  getKline: Option.getKline,
  getSymbol(name) {
    return name.split("/").join("").toLowerCase();
  },
  msg: "Kline_",
};
let contractAjax = {
  getKline: Contract.getKline,
  getSymbol(name) {
    return name.split("/")[0];
  },
  msg: "swapKline_",
};
export default {
  props: {
    contract: {
      default: false,
      type: Boolean,
      required: false,
    },
    activeCoin: {
      default: {},
      type: Object,
      required: false,
    },
    wsUrl: {
      default: "",
      type: String,
      required: false,
    },
  },
  watch: {
    activeCoin(n, o) {
      if (!n) return;
      let boo = this.contract
        ? n.pair_name != o.pair_name
        : n.pair_time_name != o.pair_time_name;
      if (boo) {
        // 获取准备取消订阅的消息的精度值
        let timer = this.timer;
        this.page[n.pair_name] = 1;
        this.TView.setSymbol(n.pair_name, this.timer);
        // 取消订阅
        if (n.pair_id != o.pair_id) {
          this.unsub(o.pair_id, timer);
        }
      }
    },
    symbol(n, o) {
      if (n != o && o) {
        this.unsub(this.ajaxTv.getSymbol(o), this.timer);
      }
    },
  },
  computed: {
    lang() {
        let local;
        if (localStorage.lang) {
            if (localStorage.lang == "tw") {
            local = "zh_TW";
            } else if (localStorage.lang == "cn") {
            local = "zh";
            } else if (localStorage.lang == "kor") {
            local = "ko";
            } else if (localStorage.lang == "jp") {
            local = "ja";
            } else if (localStorage.lang == "de") {
            local = "de_DE";
            } else if (localStorage.lang == "fra") {
            local = "fr";
            } else if (localStorage.lang == "it") {
            local = "it";
            } else if (localStorage.lang == "pt") {
            local = "pt";
            } else if (localStorage.lang == "spa") {
            local = "es";
            } else if (localStorage.lang == "en") {
            local = "en";
            }else {
            local = "en";
            }
        }
        return local;
    },
    symbol() {
      return this.activeCoin.pair_name;
    },
    ...mapState({
      theme: "theme",
    }),
    ajaxTv() {
      return this.contract ? contractAjax : exchangeAjax;
    },
    msg() {
        return `${this.ajaxTv.msg}${this.ajaxTv.getSymbol(
            this.symbol
        )}_${this.resolution(this.interval)}`;
    },
  },
data() {
    return {
        TView: undefined,
        ws: undefined,
        onLoadedCallback: undefined,
        onRealtimeCallback: undefined,
        timer: "15",
        // timer: "1D",
        sub: "",

        isCreateSocket: false,
        page: {},
        tt:undefined
    };
},
methods: {
    reconnect() {
      if(this.isCreateSocket) {
        return;
      };
      let msgObj = {
          cmd: "sub",
          msg: this.sub,
      };
      this.isCreateSocket = true;
      //没连接上会一直重连，设置延迟避免请求过多
      this.tt && clearTimeout(this.tt);
      let th=this
      th.tt = setTimeout(function () {
            th.isCreateSocket = false;
            th.linkSocket(() => {
                th.ws.send(msgObj);
            });

      }, 4000);
    },
    // 链接socket
    linkSocket(call) {
        const ws = new Socket(this.wsUrl);
        ws.on("open", () => {
            this.ws = ws;
            call && call();
        });

        ws.on("message", (res) => {
            let { data, msg, code, sub, type, status, req, cmd } = res;
            if (sub == this.sub && this.onRealtimeCallback) {
                if(sub.indexOf("BTC")!= -1) (data.close).toFixed(1)
                this.onRealtimeCallback(this.getMap(data));
                bus.$emit('collapse', data);
            } else if (type == "ping" || cmd == "ping") {
            this.ws.send({
                cmd: "pong",
            });
            }
        });
        ws.on('close',()=>{
            console.log('链接关闭');
            this.reconnect();
        })
        ws.on('error',()=>{
            console.log('发生异常了');
            this.reconnect();
        })

    },
    // 取消订阅
    unsub(pair_id, timer) {
        let msgObj = {
            cmd: "unsub",
            msg: `${this.ajaxTv.msg}${pair_id}_${this.resolution(timer)}`,
        };
        this.ws.send(msgObj);
    },
    getConfig() {
        return {};
    },
    getSymbol() {
        return {};
    },
    getMap(data) {
        return {
            time: data.id * 1000,
            close: data.close,
            open: data.open,
            high: data.high,
            low: data.low,
            volume: data.vol,
        };
    },
    resolution(resolution) {
        let T = "";
        if (isNaN(resolution * 1)) {
            T = resolution
            .replace("D", "day")
            .replace("W", "week")
            .replace("M", "mon");
        } else {
            if (resolution > 60) {
            T = Math.floor(resolution / 60) + "hours";
            } else {
            T = resolution + "min";
            }
        }
        return T;
    },
    // 解压
    unzip(b64Data) {
        let u8 = window.atob(b64Data);
        let jiya =  window.pako.inflate(u8)
        let str = this.Uint8ArrayToString(jiya);
        return JSON.parse(str);
        },
        Uint8ArrayToString(fileData) {
        var dataString = "";
        for (var i = 0; i < fileData.length; i++) {
            dataString += String.fromCharCode(fileData[i]);
        }
        return dataString;
    },
    getBars(
        symbolInfo,
        resolution,
        rangeStartDate,
        rangeEndDate,
        onLoadedCallback,
        onErrorCallback
        ) {
            // handleClick
        this.page[this.symbol] = this.page[this.symbol] || 1;
        let page = this.page[this.symbol] > 3 ? 3 : this.page[this.symbol];
        let data = {
            symbol: this.ajaxTv.getSymbol(symbolInfo.name),
            period: this.resolution(resolution),
            form: rangeStartDate,
            to: rangeEndDate,
            size: page * 200,
            zip: 1,
        };

        this.onLoadedCallback = onLoadedCallback;
        //   检测接口币种是不是后台返回的
        if (!this.activeCoin.pair_name) {
            onLoadedCallback([]);
            return;
        }
        // 取消订阅
        if (this.timer && this.timer != resolution) {
            this.unsub(
            this.ajaxTv.getSymbol(this.activeCoin.pair_name),
            this.timer
            );
        } else {
        }

        this.timer = resolution;
        this.ajaxTv.getKline(data).then((res) => {
            let arr = this.unzip(res.data).map((item) => {
            return this.getMap(item);
            });
            this.page[this.symbol]++;
            onLoadedCallback(arr);
            setTimeout(() => {
            if (this.page[this.symbol] > 3) {
                onLoadedCallback([]);
            }
            }, 60);
        });
        // 发送消息
        let msgObj = {
            cmd: "sub",
            msg: `${this.ajaxTv.msg}${data.symbol}_${data.period}`,
        };
        this.sub = msgObj.msg;
        let send = (msgObj) => {
            if (this.ws) {
            this.ws.send(msgObj);
            } else {
            if (this.isCreateSocket) {
                setTimeout(() => {
                send(msgObj);
                }, 200);
                return;
            }
            this.isCreateSocket = true;
            this.linkSocket(() => {
                this.isCreateSocket = false;
                this.ws.send(msgObj);
            });
            }
        };
        send(msgObj);
    },
    subscribeBars(
        symbolInfo,
        resolution,
        onRealtimeCallback,
        subscriberUID,
        onResetCacheNeededCallback
        ) {
        this.onRealtimeCallback = onRealtimeCallback;
        if (!this.activeCoin.pair_name) {
            setTimeout(() => {
            onResetCacheNeededCallback();
            }, 100);
        }
    },
    initView() {
        let _this = this;
        let Tdata = new VDatafeed(this);
        let widget=(_this.TView = new TradingView.widget({
            width: "100%",
            height: 610,//合约页面K线图的宽高设置
            interval: _this.timer,
            // timezone: "Asia/Shanghai",
            timezone: "America/Toronto",
            theme: "dark", // 自定义主题
            style: "1",
            library_path: "/static/Kline/charting_library/",
            datafeed: Tdata,
            locale: _this.lang,
            // toolbar_bg: _this.theme == "black" ? "#f1f3f6" : "#222e3d",
            toolbar_bg: _this.theme == "black" ? "#f1f3f6" : "#fff",
            enable_publishing: false,
            withdateranges: true,
            hide_side_toolbar: false,
            allow_symbol_change: true,
            show_popup_button: true,
            popup_width: "1000",
            popup_height: "650",
            container_id: "tradingview_1355aw2",
            disabled_features: [
                "header_symbol_search",
                "widget_logo",
                "header_compare",
                "volume_force_overlay",
                'timeframes_toolbar',
                "control_bar",
                "main_series_scale_menu",
                "header_resolutions",
                "legend_context_menu",
                "symbol_search_hot_key",
                "symbol_info",
                "pane_context_menu",
                // "header_widget_dom_node",
                'timeframes_toolbar',
            ],
            enabled_features:['header_indicators'],
            supported_resolutions: ["5", "15", "30", "60", "240", "1D", "1W", "1M"],
            overrides: tvStyle[_this.theme],
            custom_css_url: `/static/Kline/charting_library/static/css/tradingview_${
            _this.theme == "black" ? "white" : "black"
            }.css`,
            drawings_access: {
                type: "black",
                tools: [
                    { name: "Trend Line", grayed: true },
                    { name: "Trend Angle", grayed: true }
                ]
            },
        }));
        widget.onChartReady(function () {
            let buttonArr = [
                {
                title: "1" + _this.$t("exchange.min"),
                resolution: "1",
                chartType: 1
                },
                {
                title: "5" + _this.$t("exchange.min"),
                resolution: "5",
                chartType: 1
                },
                {
                title: "15" + _this.$t("exchange.min"),
                resolution: "15",
                chartType: 1
                },
                {
                title: "30" + _this.$t("exchange.min"),
                resolution: "30",
                chartType: 1
                },
                {
                title: "1" + _this.$t("exchange.hour"),
                resolution: "60",
                chartType: 1
                },
                {
                title: "1" + _this.$t("exchange.day"),
                resolution: "1D",
                chartType: 1
                },
                {
                title: "1" + _this.$t("exchange.week"),
                resolution: "1W",
                chartType: 1
                },
                {
                title: "1" + _this.$t("exchange.month"),
                resolution: "1M",
                chartType: 1
                }
            ];
            let btn = {};
            let nowTime = "";

            buttonArr.forEach((v, i) => {
                let button = widget.createButton();
                button.attr("title", v.title).addClass("my-date").text(v.title);
                if (v.resolution === _this.timer) {
                    button.css({
                        color: "#5786d2",
                        "border-bottom": "1px solid #5786d2",
                    });
                    // localStorage.setItem("tim", v.resolution);
                }
                btn = button.on("click", function (e) {
                    $(this).parents(".left").children().find(".my-date").removeAttr("style");
                    handleClick(e, v.resolution);
                    button.css({
                        color: "#5786d2",
                        "border-bottom": "1px solid #5786d2",
                    });
                    // _this.$store.commit("upType", v.type);
                    localStorage.setItem("tim", v.resolution);
                    widget.chart().setChartType(v.chartType); //改变K线类型
                });
            });
            let handleClick = (e, value) => {
                _this.setSymbol = function (symbol, value) {
                    gh.chart().setSymbol(symbol, value);
                };
                widget.chart().setResolution(value, function onReadyCallback() {}); //改变分辨率
                $(e.target)
                .addClass("mydate")
                .closest("div.space-single")
                .siblings("div.space-single")
                .find("div.button")
                .removeClass("mydate");
            };
            widget.chart().createStudy(
                "Moving Average",
                false,
                true,
                [5, "close", 0],
                null,
                {
                  "Plot.color": "#e843da",
                }
              );
            widget.chart().createStudy(
                "Moving Average",
                false,
                true,
                [10, "close", 0],
                null,
                {
                  "Plot.color": "#53b987",
                }
              );
            widget.chart().createStudy(
                "Moving Average",
                false,
                true,
                [30, "close", 0],
                null,
                {
                  "Plot.color": "#ff231f",
                }
              );
        });
    },
  },
    created(){
        let tim=localStorage.getItem("tim");
        if(tim){
            this.timer=tim
        }
    },
  mounted() {
    this.initView();
  },
};
</script>
<style scoped lang="scss">

</style>
