/*
 * @Author: walker.liu
 * @Date: 2022-05-24 10:51:56
 * @Copyright（C）:  2019-2020 ZP Inc.   All rights reserved.
 */
import store from '@/store';
import request from '@/utils/request';
import { PriceAccuracy, computedTime } from './tool';
declare const TradingView: any;

/**
 * @key Server ding字段 supported_resolutions
 */
// 1min, 5min, 15min, 30min, 60min, 4hour, 1day, 1mon, 1week, 1year
export const intervalMap = {
  '1min': '1',
  '5min': '5',
  '15min': '15',
  '30min': '30',
  '60min': '60',
  '4hour': '240',
  '1day': 'D',
  '1week': 'W',
  '1mon': 'M',
};
/** trading-view 的時間區間 */
export const supportedResolutions = [
  '1',
  '5',
  '15',
  '30',
  '60',
  '240',
  'D',
  'W',
  'M',
];

export class DataFeed {
  private symbolInfo: any;
  private subscribers: any[] = [];
  private interval: any = null;
  private resolution = '1';
  // 每个时间段都要给5次重试次数
  private RetryTime: any = {
    r1: 0,
    r5: 0,
    r15: 0,
    r60: 0,
    r240: 0,
    r1D: 0,
  };
  private KPirce: any = null;
  constructor(symbolInfo: any, timeInterval = 1000) {
    this.KPirce = symbolInfo.KPirce;
    // 将传过来的多余参数剔除
    delete symbolInfo.KPirce;
    this.symbolInfo = symbolInfo;
    this.intervalGetBars(symbolInfo.ticker, timeInterval);
  }
  public onReady(onGameLoad: any) {
    new Promise((resolve) => {
      resolve(void 0);
    }).then(() => {
      onGameLoad({
        supported_resolutions: supportedResolutions,
      });
    });
  }
  public searchSymbols() {}
  public resolveSymbol(
    symbolName: any,
    onSymbolResolvedCallback: any,
    onResolveErrorCallback: any
  ) {
    new Promise((resolve) => {
      resolve(void 0);
    }).then(() => {
      let PriceNum = 10000000000;
      PriceNum = PriceAccuracy(this.KPirce);
      onSymbolResolvedCallback({
        session: '24x7',
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        supported_resolutions: supportedResolutions,
        has_intraday: true,
        has_daily: true,
        // has_no_volume: true,
        minmov: 1,
        // minmove2:0,
        // 最多支持16位小数
        pricescale: PriceNum,
        ...this.symbolInfo,
      });
    });
  }
  /**
   * 订阅K线数据。图表库将调用onRealtimeCallback方法以更新实时数据
   */
  public subscribeBars(
    symbolInfo: any,
    resolution: string,
    onRealtimeCallback: any,
    subscriberUID: any,
    onResetCacheNeededCallback: () => void
  ) {
    if (this.subscribers[subscriberUID]) {
      return;
    }
    this.resolution = resolution;
    this.subscribers[subscriberUID] = {
      lastBarTime: null,
      listener: onRealtimeCallback,
      resolution: resolution,
      symbolInfo: symbolInfo,
    };
  }

  /**
   * 取消订阅K线数据
   */
  public unsubscribeBars(subscriberUID: any) {
    if (!this.subscribers[subscriberUID]) {
      return;
    }
    delete this.subscribers[subscriberUID];
  }

  public updateKLine(bar: any) {
    for (const listenerGuid in this.subscribers) {
      const subscriptionRecord = this.subscribers[listenerGuid];
      if (
        subscriptionRecord.lastBarTime !== null &&
        bar.time < subscriptionRecord.lastBarTime
      ) {
        continue;
      }
      subscriptionRecord.lastBarTime = bar.time;
      subscriptionRecord.listener(bar);
    }
  }
  public async getBars(
    symbolInfo: any,
    resolution: any,
    periodParams: any,
    onHistoryCallback: any,
    onErrorCallback: any
  ) {
    try {
      const token = store.getters['user/token'];
      let params = {
        ...periodParams,
        resolution,
        symbol: symbolInfo.ticker,
      };
      params.from = params.from * 1000;
      params.to = params.to * 1000;
      // 是否第一次請求歷史數據
      if (periodParams.firstDataRequest) {
        params.to = Date.now();
        params.is_first = true;
        // 添加limit
        params.limit = params.countBack + 50;
        delete params.firstDataRequest;
        delete params.countBack;
      } else {
        params.is_first = false;
        delete params.firstDataRequest;
        // 添加limit
        params.limit = params.countBack;
        delete params.countBack;
      }
      request
        .get(`/api/currencies/kline`, {
          params: params,
          headers: {
            authorization: `Bearer ${token}`,
          },
        })
        .then((res: any) => {
          let result = {
            bars: [],
            meta: { noData: false },
          };
          if (
            res.data.list &&
            res.data.list.length > 0 &&
            this.RetryTime[`r${resolution}`] < 5
          ) {
            result.meta.noData = false;
            result.bars = res.data.list.map((item: any) => {
              return {
                time: item.ts,
                open: item.open,
                high: item.high,
                low: item.low,
                close: item.close,
                volume: item.volume,
              };
            });
            store.commit(
              'token/setTradePrice',
              res.data.list[res.data.list.length - 1].close
            );
          } else {
            if (this.RetryTime[`r${resolution}`] < 5) {
              this.RetryTime[`r${resolution}`] += 1;
            } else {
              result.meta.noData = true;
            }
          }
          onHistoryCallback(result.bars, result.meta);
        });
    } catch (error) {
      onHistoryCallback({
        bars: [],
        meta: { noData: true },
      });
    }
  }
  public intervalGetBars(symbol: any, timeInterval: number) {
    this.interval = setInterval(() => {
      const token = store.getters['user/token'];
      let from = computedTime(this.resolution);
      let current = new Date().getTime();
      let params = {
        resolution: this.resolution,
        to: current,
        // from: current - timeInterval,
        from: from ? from : current - timeInterval,
        // from: current - 5000,
        symbol: symbol,
        is_first: false,
        limit: 2,
      };
      request
        .get(`/api/currencies/kline`, {
          params: params,
          headers: {
            authorization: `Bearer ${token}`,
          },
        })
        .then((res: any) => {
          if (res && res.data.list.length) {
            res.data.list.forEach((item: any) => {
              this.updateKLine({
                time: item.ts,
                open: item.open,
                high: item.high,
                low: item.low,
                close: item.close,
                volume: item.volume,
              });
            });
            store.commit(
              'token/setTradePrice',
              res.data.list[res.data.list.length - 1].close
            );
          }
        });
    }, 5000);
  }
  public clearIntervalGetBars() {
    window.clearInterval(this.interval);
  }
}
export class Widget {
  private options: any;
  public widget = null;
  constructor(options = {}) {
    const mode = store.getters['theme/getTheme'];
    // 语言
    const language = store.getters['language/getLang'];
    // 获取当前语言
    let CurLanguage = 'zh';
    if (language == 'cn') {
      CurLanguage = 'zh';
    } else if (language == 'es') {
      CurLanguage = 'es';
    } else if (language == 'en') {
      CurLanguage = 'en';
    }
    let VITE_MODE = import.meta.env.MODE;
    this.options = {
      // debug: true,
      library_path:
        VITE_MODE == 'app' ? './charting_library/' : '/charting_library/',
      // 主题
      theme: mode,
      locale: CurLanguage,
      autosize: 1,
      container: 'tv_chart_container',
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      interval: '1',
      // toolbar_bg: '#ffffff', //左侧工具栏背景色
      favorites: {
        intervals: ['1', '5', '15', '60', '240', 'D', 'W', 'M'],
        chartTypes: ['Candles', 'Line'],
      },
      // enabled_features: ['study_templates'],
      disabled_features: [
        'header_symbol_search',
        'left_toolbar', // 隐藏左侧工具栏
        'timeframes_toolbar', //底部tab
        'header_compare',
        'header_saveload',
        'header_fullscreen_button',
        'header_screenshot', //截图相机
        'vert_touch_drag_scroll', //垂直移动
        // 禁用本地存储功能
        // 'use_localstorage_for_settings',
        'save_chart_properties_to_local_storage',
      ],
      overrides: {
        // 默认展示的图表
        'mainSeriesProperties.style': 1,
        // 'mainSeriesProperties.highLowAvgPrice.highLowPriceLinesVisible': true, //高低线值
        // 'mainSeriesProperties.highLowAvgPrice.highLowPriceLabelsVisible': true, //高低线名称
        // 'mainSeriesProperties.highLowAvgPrice.averageClosePriceLineVisible':
        //   true, //均线
        // 'mainSeriesProperties.highLowAvgPrice.averageClosePriceLabelVisible':
        //   true, //均线
      },
      custom_css_url:
        VITE_MODE == 'app'
          ? './src/style/tradingview.less'
          : '/src/style/tradingview.less',
      ...options,
    };
    this.initWidget();
  }
  public initWidget() {
    try {
      this.widget = window.tvWidget = new TradingView.widget(this.options);
    } catch (e) {
      console.log(e);
      console.log('TradingView--bug');
    }
  }
}
