import { Widget } from "./Widget";
import * as echarts from "echarts";
import { List } from "../dataType/List";
import { PrintObject } from "../models/PrintObject";
import { Http } from "../Http";
import { AstHelper } from "@gvol-org/geovis-brain-core";
/**
 * @class ui.Chart
 * @since ui
 */
export class Chart extends Widget {
  chartType: string = 'scatter';; //图表类型:bar,line,pie,scatter,radar,gauge等
  options: object; //选项
  seriesNames: any;
  cht: any;
  values: Array<object>;
  axis: number;
  xLabels: any;

  /**
   * 图表组件
   * @hideconstructor
   * @param {Array<Array<object>>} [dataTable] 构造图表的数组数据
   * @param {string} [chartType] 图表类型,如:bar,line,pie等
   * @param {object} [options] 图表选项
   * @returns ui.Chart
   */
  constructor(dataTable?: Array<Array<any>> | List<any>, chartType?: string, options?: object) {
    let div;
    if (typeof process === 'undefined') {
      //浏览器环境
      div = document.createElement("div");
      div.style.width = "100%";
      div.style.height = "300px";
      div.classList.add('ui-chart-div');
    }

    super(div);
    if (!(this instanceof Chart)) {
      return new Chart(dataTable, chartType, options);
    }
    if (typeof process === 'undefined') {
      let myChart = echarts.init(this.el as HTMLElement);
      this.cht = myChart;
      if (dataTable instanceof PrintObject) {
        if (dataTable["order"]) {
          dataTable['chain'] = AstHelper.relativeChain(dataTable["order"]);
        }
        this.cht.showLoading({
          text: '图表生成中...',
          color: '#ccc',
          textColor: '#000',
          maskColor: 'rgba(255, 255, 255, 0.3)',
          zlevel: 0,
        });
        //请求接口
        // let codeContent = "print(" + dataTable['expressions'] + ");";
        // Http.getPrintRequest(codeContent).then(response => {
        //   console.log("chart构造函数获取数据", response);

        //   if (response) {
        //     this.cht.hideLoading();
        //     dataTable=response.prints[0];
        Http.getPrintRequest(dataTable['chain']).then(response => {
          console.log("chart构造函数获取数据", response);

          if (response && response.data.status == 'success') {
            this.cht.hideLoading();
            dataTable = response.data.detail;
            /* 返回数据需为以下格式
            dataTable= [
               [{ "label": "year", "type": "string" }, { "label": "0.0-1.22:裸地", "type": "number" }, { "label": "1.23-1.50:低等植被长势", "type": "number" }, { "label": "1.5-1.75:中等植被长势", "type": "number" }, { "label": "1.75-2.0:较高植被长势", "type": "number" }, { "label": "2.0-4.0:高等植被长势", "type": "number" }],
               ["2020", 2.578709716809507, 33.32349489165202, 48.01429897591766, 9.752853693549952, 6.361170965907709],
               ["2021", 2.284657853412817, 25.774618916786412, 46.651513046034715, 13.76110115428395, 11.561510519406642],
               ["2022", 2.208449727129774, 19.796828302278143, 49.17050662898666, 17.880108798682926, 10.97386249845042]
           ];*/
            this.setVasAndLabel(dataTable);
            this.setChartType(this.chartType);
          }
        });
        this.values = [[]];
        this.xLabels = [];
      }
      else {
        this.setVasAndLabel(dataTable);
      }

      if (chartType) {
        this.setChartType(chartType);
      }
      if (options) {
        this.setOptions(options);
      }
    }
  }



  /**
   * 获取图表类型
   * @return {String} String
   */
  getChartType() {
    return this.chartType;
  }
  /**
   * 获取图表选项
   * @return {String} Object
   */
  getOptions() {
    return this.options;
  }
  /**
   * 设置图表类型
   * @param {String} chartType 设置的图表类型
   * @return ui.Chart
   */
  setChartType(chartType: string) {
    this.chartType = chartType;
    this.set();
    return this;
  }
  /**
   * 设置图表的选项
   * @param {Object} options 设置的图表的选项
   * @return ui.Chart
   */
  setOptions(options: object) {
    this.options = options;
    this.set();
    return this;
  }

  /**
   *  设置图表图例
   * @param {any} seriesNames  设置图表图例的内容
   * @return ui.Chart
   */
  setSeriesNames(seriesNames: any) {
    this.seriesNames = seriesNames;
    this.set();
    return this;
  }

  private set() {
    if (this.cht) {
      let option = {
        toolbox: {
          show: true,
          feature: {
            saveAsImage: { title: "保存为图片" },
            dataView: { title: "数据视图", lang: ['数据视图', '关闭', '刷新'] },
          },
        },
        legend: {
          bottom: 0,
          type: 'scroll'
        },
        grid: {
          left: '20%',
          right: '20%'
        },
      };

      if (this.chartType === "pie") {
        option["tooltip"] = {
          trigger: "item",
          formatter: "{a} <br/>{b} : {c} ({d}%)",
        };
      } else {
        option["tooltip"] = {
          trigger: "axis",
          valueFormatter: (value: any) => {
            value = parseFloat(value);
            return value.toFixed(3);
          }
        };
        if (this.chartType === "radar") {
          option["radar"] = {
            center: ["50%", "50%"],
            radius: 80,
            indicator: this.generateData(this.xLabels),
          };
        } else {
          option["xAxis"] = {
            type: "category",
            data: this.xLabels,
          };
          option["yAxis"] = {
            type: "value",
            axisLine: {
              show: true,
            },
          };
        }
      }

      if (this.values) {
        let ses: any[] = [];
        let k: number = 0;

        this.values.forEach((item: any) => {
          if (this.chartType === "pie") {
            item = this.generateData(this.xLabels, item);
          }

          if (this.chartType === "radar") {
            item = {
              value: item,
              name: this.seriesNames != null ? this.seriesNames[k] : "",
            };
            ses.push(item);
          } else {
            ses.push({
              data: item,
              type: this.chartType,
              radius: "65%",
            });
          }
          k++;
        });
        if (this.chartType === "radar") {
          option["series"] = {
            type: "radar",
            tooltip: {
              trigger: "item",
            },
            data: ses,
          };
        } else {
          option["series"] = ses;
        }
      }
      if (this.seriesNames) {
        if ( option["series"]) {
          for (let index = 0; index < option["series"].length; index++) {
            const element = option["series"][index];
            element["name"] = this.seriesNames[index];
          }
        }
      }
      if (this.options) {
        if (this.options["title"]) {
          option["title"] = {
            text: this.options["title"],
            left: "center",
          };
        }
        if (this.options["xAxis"]) {
          option["xAxis"] = this.options["xAxis"];
          if (this.xLabels) {
            option["xAxis"]['type'] = "category";
            option["xAxis"]['data'] = this.xLabels;
          }
        }
        if (this.options["yAxis"]) {
          option["yAxis"] = this.options["yAxis"];
        }

        if (this.options["series"]) {
          if (option["series"]) {
            for (const key in this.options["series"]) {
              let obj = this.options["series"][key];
              if (option["series"][key]) {
                for (const item in obj) {
                  if (item == "color") {
                    option["series"][key]["itemStyle"] = {};
                    option["series"][key]["itemStyle"][item] = obj[item];
                  }
                  else if (item == "lineColor" || item == "lineWidth") {
                    option["series"][key]["lineStyle"] = {};
                    option["series"][key]["lineStyle"][item.replace('line', '').toLowerCase()] = obj[item];
                  }
                  else {
                    option["series"][key][item] = obj[item];
                  }
                }
              }
              //  option["series"][key] = option["series"][key];
            }
          }
          else {
            option["series"] = this.options["series"];
          }
        }

        if (this.options["isStacked"]) {
          //堆叠
          option["series"].forEach((element: any) => {
            element["stack"] = "total";
          });
        }
        if (this.options["colors"]) {
          //颜色
          for (let index = 0; index < this.options["colors"].length; index++) {
            const color = this.options["colors"][index];
            if (option["series"][index]) {
              option["series"][index]["itemStyle"] = {};
              option["series"][index]["itemStyle"]["color"] = color;
            }
          }
        }
      }
      // console.log("option",JSON.stringify(option));
      if (this.chartType == "radar" || this.chartType == "pie") {
        this.cht.clear();
      }
      this.cht.setOption(option);
    }
  }

  private generateData(labels: [], data?: []) {
    let res = [];
    for (let index = 0; index < labels.length; index++) {
      const name = labels[index];
      if (data && data[index]) {
        const value = data[index];
        res.push({ name: name, value: value });
      } else {
        res.push({ name: name });
      }
    }
    return res;
  }

  private transposition(arr: any) {
    //数组行列互换
    const newArr = arr[0].map((col: any, i: any) => arr.map((row: any) => row[i]));
    return newArr;
  }

  private getSeries(labels: any) {
    let arrs: any = [];
    let maxLegth = 0;
    labels.forEach((label: any) => {
      let arr = [];
      for (let index = 0; index < this.xLabels.length; index++) {
        const element = this.xLabels[index];
        if (element == label) {
          arr.push(index);
        }
      }
      arrs.push(arr);
      if (arr.length > maxLegth) {
        maxLegth = arr.length;
      }
    });
    let series = [];
    for (let j = 0; j < maxLegth; j++) {
      let sers: any = [];
      arrs.forEach((a: any) => {
        if (j < a.length) {
          sers.push(this.values[0][a[j]]);
        }
        else {
          sers.push(0);
        }
      });
      series.push(sers);
    }
    console.log("去重后的series", series);
    return series;
  }

  private setVasAndLabel(dataTable: any) {
    if (dataTable && dataTable['length'] > 0) {
      //创建
      let values = [];
      this.axis = 0;
      let labels = [];
      for (let index = 0; index < dataTable['length']; index++) {
        const element = dataTable[index];
        if (index == 0) {
          //表头
          let seriesNames = element.map((item: any) => { return item['label'] });
          let names = seriesNames.slice(0);
          names.shift();
          this.seriesNames = names;
        }
        else {
          labels.push(element[0]);
          let ele = element.slice(0);
          ele.shift();
          values.push(ele);
        }
      }
      this.values = this.transposition(values);
      this.xLabels = labels;
    }
  }

}