import { radarChart, CATEGORIES } from '../../configuration/constants'
import { echartsBasicListen } from '../../feature/traits/common'
import { throttle } from '../../utils'

export default {

  // 组件名称
  name: radarChart,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${radarChart}" class="${radarChart}"></div>
    `
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${radarChart} {
          position: absolute;
          border-radius: 5px;
          border-style: solid;
          border-width: 1px;
          border-color: transparent;
          padding: 10px;
          width: 600px;
          height: 400px;
        }
      </style>
    `
  },

  // 编辑器右侧块管理器中显示属性配置
  blockOptions() {
    return {
      category: CATEGORIES.ECHARTS,
      label: `
        <svg class="gjs-block-svg" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path class="gjs-block-svg-path" d="M697.856 842.432l-147.36-210.464A95.68 95.68 0 0 1 512 640a95.68 95.68 0 0 1-38.496-8.032l-147.36 210.464h371.712z m45.92-46.016L851.2 465.824l-243.2 79.04c-0.128 15.36-3.872 29.888-10.432 42.72l146.24 208.832z m-463.552 0l146.24-208.832A95.552 95.552 0 0 1 416 544.832l-243.2-79.04 107.424 330.624zM544 453.472c17.152 6.08 32.096 16.864 43.2 30.848l242.112-78.688L544 198.4v255.104z m-64 0V198.368l-285.312 207.264 242.112 78.688A96.192 96.192 0 0 1 480 453.44zM512 96l426.08 309.568-162.752 500.864H248.672L85.92 405.568 512 96z" fill="#333333"></path></svg>
        <div class="gjs-block-label">雷达图</div>
      `,
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: '雷达图',
      icon: 'globe',
      docUrl: 'https://www.yuque.com/docs/share/18c632c1-7153-4f20-9910-94dfa1f13c47#',
      author: '宗介',
      email: 'zongjie.wxt@xuelangyun.com',
      inPorts: [
        {
          uuid: 'in1',
          subType: 'json',
          description: {
            zh_CN: '输入1'
          }
        }],
      outPorts: [{
          uuid: 'out1',
          subType: 'json',
          description: {
            zh_CN: '输出1'
          }
        }
      ]
    }
  },

  // 组件属性
  componentOptions() {
    return {
      name: radarChart,
      resizable: true,
      dmode: 'absolute',
      droppable: false,
      traits: [
        {
          name: 'center',
          label: '中心(h,v)',
          changeProp: 1
        }, {
          name: 'outRadius',
          label: '半径(%)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'shape',
          label: '类型',
          changeProp: 1,
          type: 'select',
          options: [{id: 'polygon', name: '多边形'}, {id: 'circle', name: '圆形'}]
        }, { 
          name: 'axisLineShow',
          label: '坐标轴线',
          changeProp: 1,
          type: 'checkbox',
        }, { 
          name: 'indicatorNameShow',
          label: '指示器名称',
          changeProp: 1,
          type: 'checkbox',
        }, { 
          name: 'indicatorColor',
          label: '指示器名称颜色',
          type: 'color',
          changeProp: 1,
        }, { 
          name: 'splitLineColor',
          label: '分割线颜色',
          type: 'color',
          changeProp: 1,
        }, { 
          name: 'splitAreaColor',
          label: '分割区域颜色',
          type: 'color',
          changeProp: 1,
        }, { 
          name: 'indicatorMaxValueMap',
          label: '指示器最大值映射',
          changeProp: 1,
        }, {
          name: 'labelPosition',
          label: '标签',
          type: 'select',
          changeProp: 1,
          options: [
            { id: 'null', name: '无标签' }, 
            { id: 'top', name: '顶部' }, 
            { id: 'left', name: '左部' },
            { id: 'right', name: '右部' },
            { id: 'bottom', name: '底部' },
            { id: 'inside', name: '内部' }
          ]
        }, {
          name: 'labelFormatter',
          label: '标签模板',
          type: 'select',
          changeProp: 1,
          options: [{ id: '{b}', name: '数据名' }, { id: '{c}', name: '数据值' }, { id: '百分比', name: '百分比' }]
        }, {
          name: 'labelColor',
          label: '标签颜色',
          type: 'color',
          changeProp: 1,
        }, {
          name: 'labelDistance',
          label: '标签距离',
          type: 'number',
          min: 5,
          step: 1,
        }, {
          name: 'symbol',
          label: '节点',
          type: 'select',
          changeProp: 1,
          options: [{ id: 'emptyCircle', name: '空心圆' }, { id: 'circle', name: '圆形' }, { id: 'rect', name: '矩形' }, { id: 'roundRect', name: '圆角矩形' }, { id: 'triangle', name: '三角形' }, { id: 'diamond', name: '菱形' }, { id: 'pin', name: '大头针' }, { id: 'arrow', name: '箭头' }, { id: 'none', name: '无' }]
        }, {
          name: 'symbolSize',
          label: '节点大小(px)',
          changeProp: 1,
          type: 'number',
          min: 1,
          step: 1
        }, {
          name: 'itemBorderWidth',
          label: '边框宽度',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1,
        }, {
          name: 'itemBorderColor',
          label: '边框颜色',
          changeProp: 1,
          type: 'color',
        }, {
          name: 'shadowBlur',
          label: '阴影模糊',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1,
        }, {
          name: 'shadowColor',
          label: '阴影颜色',
          changeProp: 1,
          type: 'color',
        },{
          name: 'areaStyleFill',
          label: '区域填充',
          changeProp: 1,
          type: 'checkbox',
        },{
          name: 'areaStyleColor',
          label: '区域填充颜色',
          changeProp: 1,
          type: 'color',
        }, {
          name: 'inLoader',
          label: '包含Loading',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'clickEvent',
          label: '鼠标事件',
          changeProp: 1,
          type: 'select',
          options: [{id: 'null', name: '无'}, {id: 'click', name: '单击'}, {id: 'dblclick', name: '双击'}, {id: 'mousedown', name: '按下'}, {id: 'mouseup', name: '松开'}, {id: 'mouseover', name: '滑过'}, {id: 'mouseout', name: '滑出'}]
        }, {
          name: 'csv',
          label: '示例数据',
          changeProp: 1,
          type: 'csvDownload',
          preFileName: '雷达图',
          datas: [['name', '指标1', '指标2', '指标3', '指标4', '指标5', '指标6'], ['demo1', 20, 18, 90, 70, 99, 30], ['demo2', 80, 98, 68, 100, 99, 70]]
        }, {
          name: 'defaultData',
          changeProp: 1,
          type: 'hide'
        }
      ],
      defaultData:JSON.stringify([['name', '指标1', '指标2', '指标3', '指标4', '指标5', '指标6'], ['demo1', 20, 18, 90, 70, 99, 30], ['demo2', 80, 98, 68, 100, 99, 70]]).replace(/\"/g, "\\\""),
      'center': '50%,50%',
      'outRadius': 60,
      'shape': 'polygon',
      'axisLineShow': true,
      'indicatorNameShow': true,
      'indicatorColor': '#333',
      'splitLineColor': '#ccc',
      'splitAreaColor': 'rgba(250,250,250,0.3)&rgba(200,200,200,0.3)',
      'indicatorMaxValueMap': '100,100,100,100,100,100',
      'symbol': 'emptyCircle',
      'symbolSize': 4,
      'labelPosition': 'top',
      'labelColor': '#333',
      'labelFormatter': '{c}',
      'labelDistance': 5,
      'clickEvent': 'null',
      'itemBorderWidth': 0,
      'itemBorderColor': null,
      'shadowBlur': 0,
      'shadowColor': 'rgba(0,0,0,0.5)',
      'areaStyleFill': false,
      'areaStyleColor': 'rgba(0,0,0,0.5)&rgba(200,200,200,0.8)',
      'inLoader': false,
    }
  },

  onModelScript() {
    const dataSource = '{[ dataSource ]}';
    const bgColor = '{[ bgColor ]}';
    const borderColor = '{[ borderColor ]}';
    const fontSize = Boolean('{[ fontSize ]}') ? Number('{[ fontSize ]}') : 0;
    const fontColor = '{[ fontColor ]}';
    let center = '{[ center ]}';
    let colors = '{[ colors ]}';
    const titleText = '{[ titleText ]}';
    const titleColor = '{[ titleColor ]}';
    const titlePosition = ('{[ titlePosition ]}').toString();
    let legendPosition = ('{[ legendPosition ]}').toString();
    const legendOrient = ('{[ legendOrient ]}').toString();
    const legendIcon = ('{[ legendIcon ]}').toString();
    const legendItemGap = Number('{[ legendItemGap ]}');
    const legendItemWidth = Number('{[ legendItemWidth ]}');
    const legendItemHeight = Number('{[ legendItemHeight ]}');
    const legendFontSize = Number('{[ legendFontSize ]}');
    const outRadius = ('{[ outRadius ]}').toString() + '%';
    const axisLineShow = Boolean('{[ axisLineShow ]}');
    const indicatorNameShow = Boolean('{[ indicatorNameShow ]}');
    const indicatorColor = ('{[ indicatorColor ]}').toString();
    const labelPosition = ('{[ labelPosition ]}').toString();
    const labelFormatter = ('{[ labelFormatter ]}').toString();
    const labelColor = ('{[ labelColor ]}').toString();
    const labelDistance = Number('{[ labelDistance ]}');
    const legendMap = ('{[ legendMap ]}').toString();
    const clickEvent = ('{[ clickEvent ]}').toString();
    const shape = ('{[ shape ]}').toString();
    const shadowBlur = Boolean('{[ shadowBlur ]}') ? Number('{[ shadowBlur ]}') : 0;
    const shadowColor = '{[ shadowColor ]}';
    const itemBorderWidth = Boolean('{[ itemBorderWidth ]}') ? Number('{[ itemBorderWidth ]}') : 0;
    const inLoader = Boolean('{[ inLoader ]}');
    let splitAreaColor = ('{[ splitAreaColor ]}').toString();
    let splitLineColor = ('{[ splitLineColor ]}').toString();
    let indicatorMaxValueMap = ('{[ indicatorMaxValueMap ]}').toString();
    const symbol = ('{[ symbol ]}').toString();
    const symbolSize = Number('{[ symbolSize ]}');
    const areaStyleFill = Boolean('{[ areaStyleFill ]}');
    let areaStyleColor = ('{[ areaStyleColor ]}').toString();
    const defaultData = JSON.parse('{[ defaultData ]}'.replace(/\\\"/g, "\""));

    let extraData = null;
    let extraIndex = -1;

    const itemBorderColor = '{[ itemBorderColor ]}';

    Boolean(bgColor) ? $(this).css({ backgroundColor: bgColor }) : $(this).css({ backgroundColor: 'transparent' });
    Boolean(borderColor) ? $(this).css({ borderColor: borderColor }) : $(this).css({ borderColor: 'transparent' });
    if (colors.indexOf(',') > -1) {
      colors = colors.split(',').map(item => item.trim())
    } else if (Boolean(colors)) {
      colors = [colors]
    }
    if (center.indexOf(',') > -1) {
      center = center.split(',').map(item => item.trim())
    } else if (Boolean(colors)) {
      center = [center, center]
    } else {
      center = ['50%', '50%'];
    }

    if (splitAreaColor.indexOf('&') > -1) {
      splitAreaColor = splitAreaColor.split('&').map(item => item.trim())
    } else if (Boolean(splitAreaColor)) {
      splitAreaColor = [splitAreaColor]
    } else {
      splitAreaColor = ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'];
    }

    if (areaStyleColor.indexOf('&') > -1) {
      areaStyleColor = areaStyleColor.split('&').map(item => item.trim())
    } else if (Boolean(areaStyleColor)) {
      areaStyleColor = [areaStyleColor]
    } else {
      areaStyleColor = [colors];
    }

    if (splitLineColor.indexOf(',') > -1) {
      splitLineColor = splitLineColor.split(',').map(item => item.trim())
    } else if (Boolean(splitLineColor)) {
      splitLineColor = [splitLineColor]
    } else {
      splitLineColor = ['#ccc'];
    }

     if (Boolean(indicatorMaxValueMap)) {
      indicatorMaxValueMap = indicatorMaxValueMap.split(',').map(item => parseInt(item.trim(),10))
    } else {
      indicatorMaxValueMap = [];
    }

    let dataMaxValueMap = [];

    const titlePositionArr = titlePosition.split(',');
    const title = {
      text: titleText,
      left: titlePositionArr[0],
      top: titlePosition.indexOf(',') > 0 ? titlePositionArr[1] : titlePositionArr[0],
      textStyle: {
        fontSize: Math.floor(fontSize * 4 / 3),
        color: titleColor || fontColor
      }
    };

    const legendShow = legendOrient != 'null';
    const legend = {
      show: legendShow,
      type: 'scroll',
      icon: legendIcon,
      itemGap: legendItemGap,
      itemWidth: legendItemWidth,
      itemHeight: legendItemHeight,
      textStyle: {
        fontSize: legendFontSize,
        color: fontColor,
      }
    };
    if (Boolean(legendPosition)) {
      legendPosition.split(',').forEach((item, i) => {
        if (item.indexOf(':') > 0) {
          const key = item.split(':')[0].trim();
          const value = item.split(':')[1].trim();
          legend[`${key}`] = value;
        } else {
          legend[`${i ? 'top' : 'left'}`] = item.trim();
        }
      });
    }
    if (legendShow) {
      legend.orient = legendOrient;
    } else {
      legend.show = false;
    }

    let _legendMap;
    if (legendMap.indexOf(':') > 0) {
      _legendMap = {};
      let _legendArr;
      if (legendMap.indexOf(',') > 0) {
        _legendArr = legendMap.split(',');
      } else {
        _legendArr = [legendMap]
      }
      _legendArr.forEach(function (item) {
        if (item.indexOf(':') > 0) {
          const _item = item.trim().split(':').map(v => v.trim());
          _legendMap[_item[0].toString().toLocaleLowerCase()] = _item[1];
        }
      });
      legend.formatter = function (name) {
        return _legendMap[name.toString().toLocaleLowerCase()] || name
      }
    } else {
      legend.formatter = null
    }

    const labelShow = labelPosition != 'null';
    let label = {
      show: labelShow,
      color: labelColor,
      fontSize: fontSize
    }
    if (labelShow) {
      label.position = labelPosition;
      label.formatter = labelFormatter;
      label.distance = labelDistance;
    }
    if(labelFormatter === '百分比') {
      label.formatter = (params) => {
        let maxVal = indicatorMaxValueMap[params.dimensionIndex] // 取用户设置的最大值
        if(maxVal === undefined) { // 如果用户没有设置最大值，则取数据中的最大值
          maxVal = dataMaxValueMap[params.dimensionIndex]
        }
        return `${(parseInt(params.value,10)*100/parseInt(maxVal,10)).toFixed(2)}%`
      }
    }
    if (_legendMap && labelFormatter == '{b}') {
      label.formatter = function (params) {
        return _legendMap[params.name.toString().toLocaleLowerCase()] || params.name
      }
    }

    const tooltip = {
      trigger: 'item'
    };
    if (_legendMap) {
      tooltip.formatter = function(params) {
        const name = _legendMap[params.name.toString().toLocaleLowerCase()] || params.name;
        const value = params.value[params.encode.value[0]];
        const list = "<span style='display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:" + params.color + "'></span>" + name + ": " + value;
        return list
      }
    }

    const radarTmp = {
      type: 'radar',
      radius: outRadius,
      center: center,
      shape: shape,
      name: {
        show: indicatorNameShow,
        color: indicatorColor,
        fontSize: fontSize,
      },
      axisLine: {
        show: axisLineShow,
      },
      splitLine: {
        lineStyle: {
          color: splitLineColor
        }
      },
      splitArea: {
        areaStyle: {
          color: splitAreaColor
        }
      }
    }

    const seriesTmp = {
      type: 'radar',
      selectedMode: clickEvent == 'click' ? 'single' : false,
      symbol: symbol,
      symbolSize: symbolSize,
      itemStyle: {
        borderWidth: itemBorderWidth,
        borderColor: itemBorderColor,
        shadowBlur: shadowBlur,
        shadowColor: shadowColor
      },
      emphasis: {
        label: { show: labelShow }
      }
    }

    const getSeries = function(source) {
      let sourceNew = JSON.parse(JSON.stringify(source));
      var indicatorLabelList = sourceNew.shift();
      var series = JSON.parse(JSON.stringify(seriesTmp));
      series.label=label; // 方法拷贝
      if (indicatorLabelList) {
        indicatorLabelList = indicatorLabelList.slice(1);
      }
      if (sourceNew.length > 0) {
        let seriesData = sourceNew.map((elData,i) => {
          return {
            name:elData[0],
            value:elData.slice(1),
            areaStyle: {
              color: areaStyleFill ? areaStyleColor[i] : 'rgba(0,0,0,0)'
            },
          }
        })
        series.data = seriesData;
      }
      return [indicatorLabelList,series];
    }

    const setDataMaxValueMap = function(source) {
      dataMaxValueMap = [];
      let sourceNew = JSON.parse(JSON.stringify(source));
      if(sourceNew.length > 1) {
        sourceNew = sourceNew.slice(1); // 去掉header
        const sourceNewData = sourceNew.map(data=> data.slice(1)) // 去掉name
        dataMaxValueMap = sourceNewData[0];
        sourceNewData.forEach((data) => {
          data.forEach((el, index)=> {
            if(el > dataMaxValueMap[index]){
              dataMaxValueMap[index] = el;
            }
          })
        })
      }
    }

    const getRadar = function(labelList) {
      var indicator = [];
      labelList.forEach((label,index) => {
        var objIndicator = {
          name: label
        }
        if(indicatorMaxValueMap[index]) {
          objIndicator.max = indicatorMaxValueMap[index];
        } else if (dataMaxValueMap[index]) {
          objIndicator.max = dataMaxValueMap[index];
        }
        indicator.push(objIndicator)
      })
      const obj = Object.assign({}, radarTmp, {indicator: indicator});
      return obj;
    }

    const self = this;
    const _id = self.getAttribute('id');
    const eventName = `call-${_id}`;
    //const defaultSource = [['name', '指标1', '指标2', '指标3', '指标4', '指标5', '指标6'], ['demo1', 20, 18, 90, 70, 99, 30], ['demo2', 50, 98, 68, 100, 99, 170]]
    const myChart = window.echarts.init(self);
    inLoader ? $(self).attr('loader', 'in') : $(self).removeAttr('loader');

    function initChart(source) {
      myChart.clear();
      setDataMaxValueMap(source);
      const dataInfo = getSeries(source);
      const indicatorLabelList = dataInfo[0];
      const series = dataInfo[1];
      const radar = getRadar(indicatorLabelList);
      const option = {
        title: title,
        tooltip: tooltip,
        legend: legend,
        radar: radar,
        series: series
      };

      if (Boolean(colors)) option.color = colors;

      myChart.setOption(option);
      myChart.resize();
      
      if (window.prevEventType && window.prevEventType[eventName]) {
        myChart.off(window.prevEventType[eventName]);
      }
      if (clickEvent != 'null') {
        myChart.on(clickEvent, function(params) {
          var _data = params.data;
          if (extraIndex > -1 && extraData && extraData.length) {
            _data.splice(extraIndex, 0, extraData[params.dataIndex + 1]);
          }
          if (window.spSocket && clickEvent != 'null') {
            inLoader && window.loader && window.loader.add(_id);
            window.spSocket.send({
                eventName: eventName,
                data: {
                    success :true,
                    out1: JSON.stringify(_data)
                }
            });
          }
        });
        if (!window.prevEventType) {
          window.prevEventType = {};
        }
        window.prevEventType[eventName] = clickEvent;
      }
    }

    initChart(defaultData);

    window.addEventListener('resize', function () {
      myChart.resize();
    }, false)

    // 有 dashboardHost 说明是运行模式
    let hasTransfer = false;
    if (window.spSocket) {
      inLoader && window.loader && $(self).append($(window.loader.ele));
      window.spSocket.subscribe({
        eventName: eventName,
        callback: function (_data) {
          if(_data.data.in1) {
            const data = JSON.parse(_data.data.in1);
            let source = data;
            inLoader && window.loader && window.loader.remove(_id);
            if (!hasTransfer) {
              initChart(source);
              hasTransfer = true
            } else {
              setDataMaxValueMap(source);
              const dataInfo = getSeries(source);
              const indicatorLabelList = dataInfo[0];
              const series = dataInfo[1];
              const radar = getRadar(indicatorLabelList);
              myChart.setOption({
                radar: radar,
                series: series
              })
            }
          }
        }
      });
    }

    Boolean(dataSource) && $.get(dataSource, function (ds) {
      myChart.hideLoading();
      initChart(JSON.parse(ds))
    });
  },

  onViewInit() {
    this.updateScript();
    const evn = echartsBasicListen + `
      change:defaultData
      change:center
      change:shape
      change:outRadius
      change:axisLineShow
      change:indicatorNameShow
      change:indicatorColor
      change:splitLineColor
      change:splitAreaColor
      change:indicatorMaxValueMap
      change:labelColor
      change:labelDistance
      change:labelPosition
      change:labelFormatter
      change:symbol
      change:symbolSize
      change:areaStyleFill
      change:areaStyleColor
      change:clickEvent change:itemBorderColor change:itemBorderWidth change:shadowColor change:shadowBlur change:inLoader`;

    this.listenTo(this.model, evn, this.updateScript);
    this.listenTo(this.model, evn, this.em.handleUpdates.bind(this.em));
    this.listenTo(this.em, 'update:component:style:height update:component:style:width', throttle.bind(this, this.updateScript.bind(this)));
  }
}
