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

export default {

  // 组件名称
  name: scatterChart,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${scatterChart}" class="${scatterChart}"></div>
    `
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${scatterChart} {
          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 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" ><path d="M919.02234754 866.64803899H97.91122992V166.91054351a30.40682525 30.40682525 0 1 0-60.8136505-1e-8v415.77902932a31.14941125 31.14941125 0 0 0 0 12.22269002v302.17719365A30.42758091 30.42758091 0 0 0 67.49287392 927.5078125h851.52947362a30.44141751 30.44141751 0 0 0 0-60.85977351z m-661.43204475-60.42160182a68.33175808 68.33175808 0 1 0-68.30869658-68.33175809 68.32483978 68.32483978 0 0 0 68.30869658 68.33175809z m207.90104542-116.46148385a68.33175808 68.33175808 0 1 0-68.30869659-68.33175807 68.32483978 68.32483978 0 0 0 68.30869659 68.33175807z m324.31640625-181.19562019a68.33175808 68.33175808 0 1 0-68.30869659-68.33175809 68.32483978 68.32483978 0 0 0 68.30869659 68.33175809z m126.51637621-162.95383121a42.68716979 42.68716979 0 1 0-42.68716979-42.6871698 42.67563904 42.67563904 0 0 0 42.68716979 42.6871698z m-360.86916875 162.95383121a107.25987408 107.25987408 0 1 0-107.21375031-107.25987408 107.2368118 107.2368118 0 0 0 107.21375031 107.25987408z" p-id="49964"></path></svg>
        <div class="gjs-block-label">连续型<br>散点图</div>
      `
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: '连续型散点图',
      icon: 'globe',
      docUrl: 'https://www.yuque.com/docs/share/3581d49a-adca-4f46-814c-b492780dcaa6#',
      author: '秋水',
      email: 'qiushui.smy@xuelangyun.com',
      inPorts: [
        {
          uuid: 'in1',
          subType: 'json',
          description: {
            zh_CN: '输入1'
          }
        }
      ]
    }
  },

  // 组件属性
  componentOptions() {
    return {
      name: scatterChart,
      resizable: true,
      dmode: 'absolute',
      droppable: false,
      traits: [
        {
          name: 'xAxisName',
          label: 'x轴名称',
          changeProp: 1
        }, {
          name: 'yAxisName',
          label: 'y轴名称',
          changeProp: 1
        }, {
          name: 'axisColor',
          label: '坐标轴颜色',
          changeProp: 1,
          type: 'color'
        }, {
          name: 'xAxisSplitLine',
          label: 'x轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'yAxisSplitLine',
          label: 'y轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'gridPadding',
          label: '容器边距(左,上,右,下)',
          changeProp: 1
        }, {
          name: 'xLabelRotate',
          label: 'x轴标签旋转',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'xDimession',
          label: 'X轴维度',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1,
        }, {
          name: 'yDimession',
          label: 'Y轴维度',
          changeProp: 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: '节点大小',
          changeProp: 1,
          type: 'number',
          min: 1,
          step: 1
        }, {
          name: 'visualPosition',
          label: '视觉映射',
          changeProp: 1,
          type: 'select',
          options: [
            { id: 'none', name: '无' },
            { id: 'top-left', name: '顶部居左' },
            { id: 'top-right', name: '顶部居右' },
            { id: 'center-left', name: '中部居左' },
            { id: 'center-right', name: '中部居右' },
            { id: 'bottom-left', name: '底部居左' },
            { id: 'bottom-right', name: '底部居右' },
          ]
        }, {
          name: 'visualDimension',
          label: '视觉映射维度',
          changeProp: 1,
          min: 0,
          type: 'number'
        }, {
          name: 'visualText',
          label: '视觉映射文本',
          changeProp: 1
        }, {
          name: 'visualMin',
          label: '视觉最小值',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'visualMax',
          label: '视觉最大值',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'symbolMin',
          label: '图元最小(px)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'symbolMax',
          label: '图元最大(px)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'colorAlpha',
          label: '颜色透明度',
          changeProp: 1,
        }, {
          name: 'colorLightness',
          label: '颜色明暗度',
          changeProp: 1,
        }, {
          name: 'colorSaturation',
          label: '颜色饱和度',
          changeProp: 1,
        }, {
          name: 'colorHue',
          label: '颜色色调',
          changeProp: 1,
        }, {
          name: 'inRangeColor',
          label: '范围内颜色',
          changeProp: 1
        }, {
          name: 'outRangeColor',
          label: '范围外颜色',
          changeProp: 1,
          type: 'color'
        }, {
          name: 'controllerColor',
          label: '控制器颜色',
          changeProp: 1
        }, {
          name: 'zoomStart',
          label: '放大镜开始(%)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'zoomEnd',
          label: '放大镜结束(%)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'setAllOption',
          label: '全量更新',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'csv',
          label: '示例数据',
          changeProp: 1,
          type: 'csvDownload',
          preFileName: '连续型散点图',
          datas: [
            [18.78,22365],[49.26,18271],[70.58,20545],[75.67,21806],[108.88,19747],[123.31,19464],[173.62,16704],[206.54,22272],[222.57,22016],[278.52,21543],[293.35,22158],[310.46,18038],[18.06,25471],[53.06,24878],[60.03,24988],[86.35,28373],[96.01,27081],[122.11,29482],[139.06,28046],[160.23,28709],[173.2,26559],[192.45,25877],[213.91,28985],[237.83,25649],[251.01,24701],[294.77,26801],[321.42,28623],[368.52,25779],[35.98,34742],[51.11,35219],[60.59,34660],[93,31721],[102.55,35983],[114.76,36250],[137.57,36709],[159.87,35029],[175.44,33630],[194.76,35942],[211.19,35514],[235.4,29737],[259.57,36599],[273.19,36166],[292.21,31827]
          ]
        }, {
          name: 'defaultData',
          changeProp: 1,
          type: 'hide'
        }
      ],
      'defaultData':JSON.stringify([
        ["x","y"],[18.78,22365],[49.26,18271],[70.58,20545],[75.67,21806],[108.88,19747],[123.31,19464],[173.62,16704],[206.54,22272],[222.57,22016],[278.52,21543],[293.35,22158],[310.46,18038],[18.06,25471],[53.06,24878],[60.03,24988],[86.35,28373],[96.01,27081],[122.11,29482],[139.06,28046],[160.23,28709],[173.2,26559],[192.45,25877],[213.91,28985],[237.83,25649],[251.01,24701],[294.77,26801],[321.42,28623],[368.52,25779],[35.98,34742],[51.11,35219],[60.59,34660],[93,31721],[102.55,35983],[114.76,36250],[137.57,36709],[159.87,35029],[175.44,33630],[194.76,35942],[211.19,35514],[235.4,29737],[259.57,36599],[273.19,36166],[292.21,31827]
      ]).replace(/\"/g, "\\\""),
      'xAxisName': null,
      'yAxisName': null,
      'axisColor': '#333333',
      'xAxisSplitLine': false,
      'yAxisSplitLine': true,
      'gridPadding': '10%,60,10%,60',
      'xLabelRotate': null,
      'xDimession': 0,
      'yDimession': '1',
      'symbol': 'circle',
      'symbolSize': 10,
      'visualPosition': 'none',
      'visualDimension': 1,
      'visualText': null,
      'visualMin': 10000,
      'visualMax': 50000,
      'inRangeColor': null,
      'symbolMin': 10,
      'symbolMax': 10,
      'colorAlpha': null,
      'colorLightness': null,
      'colorSaturation': null,
      'colorHue': null,
      'outRangeColor': 'rgba(0,0,0,0.2)',
      'controllerColor': null,
      'setAllOption': false,
      'zoomStart': -1,
      'zoomEnd': 100,
    }
  },

  onModelScript() {
    const dataSource = '{[ dataSource ]}';
    const bgColor = '{[ bgColor ]}';
    const borderColor = '{[ borderColor ]}';
    const fontColor = '{[ fontColor ]}';
    let colors = '{[ colors ]}';
    let legendPosition = ('{[ legendPosition ]}').toString();
    const legendOrient = ('{[ legendOrient ]}').toString();
    const titleText = '{[ titleText ]}';
    const titleColor = '{[ titleColor ]}';
    const titlePosition = ('{[ titlePosition ]}').toString();
    const xAxisName = '{[ xAxisName ]}';
    const yAxisName = '{[ yAxisName ]}';
    const axisColor = '{[ axisColor ]}';
    const xAxisSplitLine = Boolean('{[ xAxisSplitLine ]}');
    const yAxisSplitLine = Boolean('{[ yAxisSplitLine ]}');
    let gridPadding = '{[ gridPadding ]}';
    const xLabelRotate = '{[ xLabelRotate ]}';
    const xDimession = Number('{[ xDimession ]}');
    let yDimession = Boolean('{[ yDimession ]}') ? ('{[ yDimession ]}').toString() : '1';
    const symbol = ('{[ symbol ]}').toString();
    const symbolSize = Number('{[ symbolSize ]}');
    const visualPosition = ('{[ visualPosition ]}').toString();
    const visualDimension = Number('{[ visualDimension ]}');
    let visualText = ('{[ visualText ]}').toString();
    const visualMin = Number('{[ visualMin ]}');
    const visualMax = Number('{[ visualMax ]}');
    const inRangeColor = '{[ inRangeColor ]}';
    const symbolMin = Number('{[ symbolMin ]}');
    const symbolMax = Number('{[ symbolMax ]}');
    const colorAlpha = '{[ colorAlpha ]}';
    const colorLightness = '{[ colorLightness ]}';
    const colorSaturation = '{[ colorSaturation ]}';
    const colorHue = '{[ colorHue ]}';
    const outRangeColor = ('{[ outRangeColor ]}').toString();
    const controllerColor = '{[ controllerColor ]}';
    const zoomStart = Number('{[ zoomStart ]}');
    const zoomEnd = Number('{[ zoomEnd ]}');
    const setAllOption = Boolean('{[ setAllOption ]}');
    let legendMap = Boolean('{[ legendMap ]}') && ('{[ legendMap ]}').toString();
    const defaultData = JSON.parse('{[ defaultData ]}'.replace(/\\\"/g, "\""));
    
    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 (yDimession.indexOf(',') > -1) {
      yDimession = yDimession.split(',').map(item => parseInt(item.trim()))
    } else if (Boolean(yDimession)) {
      yDimession = [parseInt(yDimession.trim())]
    }

    const grid = {
      containLabel: true
    };
    if (gridPadding.indexOf(',') > -1) {
      gridPadding = gridPadding.split(',').map(item => item.trim());
      grid.left = gridPadding[0];
      grid.top = gridPadding[1];
      grid.right = gridPadding[2] || gridPadding[0];
      grid.bottom = gridPadding[3] || gridPadding[1];
    } else if (Boolean(gridPadding)) {
      grid.left = gridPadding;
      grid.top = gridPadding;
      grid.right = gridPadding;
      grid.bottom = gridPadding;
    }

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

    const legendShow = legendOrient != 'null';
    const legend = {
      show: legendShow,
      type: 'scroll',
      textStyle: {
        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;
    }

    const xAxis = {
      type: 'value',
      name: xAxisName,
      boundaryGap: false,
      axisLine: {
        lineStyle: {
          color: axisColor
        }
      },
      axisLabel: {
        color: fontColor,
        rotate: xLabelRotate
      },
      splitLine: {
        show: xAxisSplitLine,
        lineStyle: {
          color: axisColor,
          opacity: 0.4
        }
      }
    };
    const yAxis = {
      type: 'value',
      name: yAxisName,
      axisLine: {
        lineStyle: {
          color: axisColor
        }
      },
      axisLabel: {
        color: fontColor
      },
      splitLine: {
        show: yAxisSplitLine,
        lineStyle: {
          color: axisColor,
          opacity: 0.4
        }
      }
    };

    const tooltip = {
      // trigger: 'axis',
      axisPointer: {
        type: 'line',
        lineStyle: {
          color: axisColor,
          opacity: 0.6
        }
      }
    };

    const dataZoom = [
      {
        show: false,
        // borderColor: fontColor,
        start: zoomStart,
        end: zoomEnd
      }, {
        type: 'inside',
        start: zoomStart,
        end: zoomEnd
      }
    ];
    if (zoomStart < 0 || zoomEnd < 100) {
      dataZoom[1].disabled = true
    } else {
      dataZoom[1].disabled = false
    };
    
    if (visualText.indexOf(',') > 0) {
      visualText = visualText.split(',').map(function(t) { return t.trim() }).slice(0, 2);
    } else if (Boolean(visualText)) {
      visualText = [visualText];
    }
    const visualMap = {
      type: 'continuous',
      dimension: visualDimension,
      min: visualMin,
      max: visualMax,
      range: [visualMin, visualMax],
      calculable: true,
      inRange: {
        symbol: symbol,
        symbolSize: [symbolMin, symbolMax]
      },
      outOfRange: {
        symbol: symbol,
        symbolSize: [symbolMin, symbolMax]
      },
      textGap: 24,
      text: visualText,
      textStyle: {
        color: fontColor
      }
    }
    if (Boolean(inRangeColor)) {
      const _inRangeColor = inRangeColor.indexOf(',') > 0 ? inRangeColor.split(',').map(function(color) { return  color.trim() }) : [inRangeColor];
      visualMap.color = _inRangeColor;
      visualMap.inRange.color = _inRangeColor;
    }
    if (Boolean(outRangeColor)) {
      visualMap.outOfRange.color = [outRangeColor];
    }
    if (Boolean(colorAlpha)) {
      const _colorAlpha = colorAlpha.indexOf(',') > 0 ? colorAlpha.split(',').map(function(color) { return  Number(color.trim()) }) : [Number(colorAlpha)];
      visualMap.inRange.colorAlpha = _colorAlpha;
    }
    if (Boolean(colorLightness)) {
      const _colorLightness = colorLightness.indexOf(',') > 0 ? colorLightness.split(',').map(function(color) { return  Number(color.trim()) }) : [Number(colorLightness)];
      visualMap.inRange.colorLightness = _colorLightness;
    }
    if (Boolean(colorSaturation)) {
      const _colorSaturation = colorSaturation.indexOf(',') > 0 ? colorSaturation.split(',').map(function(color) { return  Number(color.trim()) }) : [Number(colorSaturation)];
      visualMap.inRange.colorSaturation = _colorSaturation;
    }
    if (Boolean(colorHue) && colorHue.indexOf(',') > 0) {
      const _colorHue = colorHue.split(',').map(function(color) { return  Number(color.trim()) });
      visualMap.inRange.colorHue = _colorHue;
    }
    if (Boolean(controllerColor)) {
      const _controllerColor = controllerColor.indexOf(',') > 0 ? controllerColor.split(',').map(function(color) { return  color.trim() }) : [controllerColor];
      visualMap.controller = {
        inRange: {
          color: _controllerColor
        }
      }
    }
    
    if (visualPosition == 'none') {
      visualMap.show = false;
    } else{
      const visualPositionArr = visualPosition.split('-');
      if (visualPositionArr == 'center' && visualPositionArr[1] == 'right') {
        visualMap[visualPositionArr[1]] = visualPositionArr[1];
      } else {
        visualMap.left = visualPositionArr[1];
      }
      visualMap.top = visualPositionArr[0];
    }

    if (legendMap && legendMap.indexOf(',') > 0) {
      legendMap = legendMap.split(',').map(function(leg) {
        return leg.trim();
      });
      legendMap.unshift('x');
    } else if (Boolean(legendMap)) {
      legendMap = ['x', legendMap];
    }

    const serieTemp = {
      type: 'scatter',
      symbol: symbol,
      symbolSize: symbolSize,
    };
    const myChart = window.echarts.init(this);
    const self = this;

    function initChart(source) {
      myChart.clear();
      const series = yDimession.map(function(yIndex) {
        return Object.assign({}, serieTemp, { encode: {
            x: xDimession,
            y: yIndex,
            seriesName: yIndex
          }
        });
      });
      const option = {
        title: title,
        tooltip: tooltip,
        legend: legend,
        grid: grid,
        xAxis: xAxis,
        yAxis: yAxis,
        dataset: {
          source: source
        },
        dataZoom: dataZoom,
        series: series
      };
      if (legendMap) {
        option.dataset.dimensions = legendMap;
      }
      if (visualPosition !== 'none' && yDimession.includes(visualDimension)) {
        option.visualMap = visualMap;
      }

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

      myChart.setOption(option);
      myChart.resize();
    }

    initChart(defaultData);

    window.addEventListener('resize', function () {
      myChart.resize();
    }, false)
    let hasTransfer = false;
    // 有 dashboardHost 说明是运行模式
    if (window.spSocket) {
      var eventName = `call-` + self.getAttribute('id');
      window.spSocket.subscribe({
        eventName: eventName,
        callback: function (_data) {
          let _in1Str = _data.data.in1;
          if (_in1Str) {
            const source = JSON.parse(_in1Str);
            if (!hasTransfer || setAllOption) {
              initChart(source);
              hasTransfer = true
            } else {
              myChart.setOption({
                dataset: {
                  source: source
                },
              })
            }
          }
        }
      });
    }

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

  onViewInit() {
    this.updateScript();
    const evn = echartsBasicListen + `
    change:defaultData 
    change:xAxisName
    change:yAxisName
    change:axisColor
    change:xAxisSplitLine
    change:yAxisSplitLine
    change:gridPadding
    change:xLabelRotate
    change:multiSeries
    change:xDimession
    change:yDimession
    change:symbol
    change:symbolSize
    change:visualPosition
    change:visualDimension
    change:visualText
    change:visualMin
    change:visualMax
    change:inRangeColor
    change:symbolMin
    change:symbolMax
    change:colorAlpha
    change:colorLightness
    change:colorSaturation
    change:colorHue
    change:outRangeColor
    change:controllerColor
    change:setAllOption
    change:zoomStart
    change:zoomEnd`;

    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)));
  }
}
