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

export default {

  // 组件名称
  name: piecescatterChart,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${piecescatterChart}" class="${piecescatterChart}"></div>
    `
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${piecescatterChart} {
          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 d="M855.98 812.8H188.272V202.653c0-12.664-10.36-23.025-23.024-23.025s-23.024 10.361-23.024 23.025v656.195h713.758c12.662 0 23.023-10.361 23.023-23.024S868.642 812.8 855.98 812.8z" p-id="22864"></path><path d="M633.397 608.445a68.058 68.058 0 1 0 139.289 0 68.058 68.058 0 1 0-139.29 0zM580.224 445.94c34.188 0 61.906-27.719 61.906-61.906 0-34.189-27.718-61.907-61.906-61.907s-61.907 27.718-61.907 61.907c0 34.187 27.718 61.906 61.907 61.906zM726.256 331.5c34.187 0 61.905-27.719 61.905-61.907 0-34.19-27.717-61.907-61.905-61.907s-61.906 27.718-61.906 61.907c0 34.188 27.718 61.907 61.906 61.907z m52.46 160.871c34.189 0 61.908-27.719 61.908-61.907s-27.719-61.906-61.907-61.906c-34.188 0-61.907 27.717-61.907 61.906 0.001 34.189 27.72 61.907 61.907 61.907zM215.539 654.875c0 29.917 24.258 54.167 54.167 54.167s54.167-24.251 54.167-54.167c0-29.918-24.256-54.168-54.167-54.168-29.909-0.002-54.167 24.249-54.167 54.167m154.763-85.12c42.74 0 77.382-34.64 77.382-77.385 0-42.732-34.64-77.381-77.382-77.381-42.742 0-77.382 34.646-77.382 77.381 0 42.742 34.64 77.385 77.382 77.385z m15.475 147.027c0 29.917 24.257 54.167 54.17 54.167 29.908 0 54.168-24.25 54.168-54.167 0-29.918-24.259-54.17-54.169-54.17-29.91-0.001-54.169 24.251-54.169 54.17zM532.8 662.61c29.909 0 54.167-24.25 54.167-54.167 0-29.916-24.258-54.165-54.167-54.165s-54.165 24.249-54.165 54.165c0 29.918 24.257 54.167 54.164 54.167z" ></path></svg>
        <div class="gjs-block-label">离散型<br>散点图</div>
      `
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: '离散型散点图',
      icon: 'globe',
      docUrl: 'https://www.yuque.com/docs/share/33c150c8-6f7f-4485-a24a-9b58989e022f#',
      author: '秋水',
      email: 'qiushui.smy@xuelangyun.com',
      inPorts: [
        {
          uuid: 'in1',
          subType: 'json',
          description: {
            zh_CN: '输入1'
          }
        }
      ]
    }
  },

  // 组件属性
  componentOptions() {
    return {
      name: piecescatterChart,
      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: 'axisLineType',
          label: '坐标轴线类型',
          type: 'select',
          changeProp: 1,
          options: [{ id: 'solid', name: '实线' },{id:'dashed', name:'虚线'},{id:'dotted', name:'点线'}]
        }, {
          name: 'xAxisSplitLine',
          label: 'x轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'xAxisTick',
          label: 'x轴刻度线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'yAxisSplitLine',
          label: 'y轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'yAxisTick',
          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: 'splitNumber',
          label: '分段',
          changeProp: 1,
          type: 'number',
          min: 2,
          step: 1
        }, {
          name: 'pieces',
          label: '分段详情',
          changeProp: 1
        }, {
          name: 'categories',
          label: '枚举型数据',
          changeProp: 1
        }, {
          name: 'rangeSymbolSize',
          label: '图元大小(px)',
          changeProp: 1
        }, {
          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: 'csv',
          label: '示例数据',
          changeProp: 1,
          type: 'csvDownload',
          preFileName: '离散型散点图',
          datas: [
            [18.78,223],[49.26,182],[70.58,545],[75.67,806],[108.88,747],[123.31,464],[173.62,704],[206.54,272],[222.57,16],[278.52,543],[293.35,158],[310.46,38],[18.06,471],[53.06,878],[60.03,988],[86.35,373],[96.01,81],[122.11,482],[139.06,46],[160.23,709],[173.2,559],[192.45,877],[213.918985],[237.83,649],[251.01,701],[294.77,801],[321.42,623],[368.52,779],[35.98,742],[51.11,219],[60.59,660],[93,721],[102.55,983],[114.76,250],[137.57,709],[159.87,29],[175.44,630],[194.76,942],[211.19,514],[235.4,737],[259.57,599]
          ]
        }, {
          name: 'defaultData',
          changeProp: 1,
          type: 'hide'
        }
      ],
      'defaultData':JSON.stringify([
        ["x","y"],[18.78,223],[49.26,182],[70.58,545],[75.67,806],[108.88,747],[123.31,464],[173.62,704],[206.54,272],[222.57,16],[278.52,543],[293.35,158],[310.46,38],[18.06,471],[53.06,878],[60.03,988],[86.35,373],[96.01,81],[122.11,482],[139.06,46],[160.23,709],[173.2,559],[192.45,877],[213.918985],[237.83,649],[251.01,701],[294.77,801],[321.42,623],[368.52,779],[35.98,742],[51.11,219],[60.59,660],[93,721],[102.55,983],[114.76,250],[137.57,709],[159.87,29],[175.44,630],[194.76,942],[211.19,514],[235.4,737],[259.57,599]
      ]).replace(/\"/g, "\\\""),
      'xAxisName': null,
      'yAxisName': null,
      'axisColor': '#333333',
      'axisLineType':'solid',
      'xAxisSplitLine': true,
      'xAxisTick': true,
      'yAxisSplitLine': true,
      'yAxisTick': true,
      'gridPadding': '30,60,16%,60',
      'xLabelRotate': null,
      'xDimession': 0,
      'yDimession': '1',
      'symbol': 'circle',
      'symbolSize': 10,
      'visualPosition': 'center-right',
      'visualDimension': 1,
      'splitNumber': 5,
      'pieces': 'min:800,label:800以上::min:600,max:800::min:400,max:600::min:200,max:400::max:200,label:200以下',
      'categories': null,
      // 'inRangeColor': '#6ea8e5,#ff962e,#ff5c5f,#70cc62,#86d1ca',
      'inRangeColor': '#0084ff, #339cff, #66b5ff, #99ceff, #cce6ff',
      'rangeSymbolSize': '10, 30',
      'colorAlpha': null,
      'colorLightness': null,
      'colorSaturation': null,
      'colorHue': null,
      'outRangeColor': '#ddd',
      'controllerColor': null,
      '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 axisLineType = '{[ axisLineType ]}';
    const xAxisSplitLine = Boolean('{[ xAxisSplitLine ]}');
    const xAxisTick = Boolean('{[ xAxisTick ]}');
    const yAxisSplitLine = Boolean('{[ yAxisSplitLine ]}');
    const yAxisTick = Boolean('{[ yAxisTick ]}');
    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 ]}');
    const splitNumber = Number('{[ splitNumber ]}');
    let pieces = ('{[ pieces ]}').toString();
    let categories = ('{[ categories ]}').toString();
    const inRangeColor = '{[ inRangeColor ]}';
    let rangeSymbolSize = ('{[ rangeSymbolSize ]}').toString();
    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 ]}');
    let 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,
      axisTick: { show: xAxisTick },
      axisLine: {
        lineStyle: {
          type: axisLineType,
          color: axisColor
        }
      },
      axisLabel: {
        color: fontColor,
        rotate: xLabelRotate
      },
      splitLine: {
        show: xAxisSplitLine,
        lineStyle: {
          color: axisColor,
          opacity: 0.4
        }
      }
    };
    const yAxis = {
      type: 'value',
      name: yAxisName,
      axisTick: { show: yAxisTick },
      axisLine: {
        lineStyle: {
          type: axisLineType,
          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 (pieces.indexOf('::') > 0) {
      pieces = pieces.split('::').map(function(item) {
        item = item.trim();
        const piece = {}
        if (item.indexOf(',') > 0) {
          item.split(',').forEach(function(it) {
            it = it.trim();
            if (it.indexOf(':') > 0) {
              const its = it.split(':');
              const key = its[0].trim();
              const value = key == 'label' || key == 'color' ? its[1].trim() : Number(its[1].trim());
              piece[key] = value;
            }
          })
        } else if (item.indexOf(':') > 0) {
          const items = item.split(':');
          const key = items[0].trim();
          const value = key == 'label' || key == 'color' ? items[1].trim() : Number(items[1].trim());
          piece[key] = value;
        }
        return piece;
      })
    } else if (Boolean(pieces)) {
      const piece = {}
      if (pieces.indexOf(',') > 0) {
        pieces.split(',').forEach(function(it) {
          it = it.trim();
          if (it.indexOf(':') > 0) {
            const its = it.split(':');
            const key = its[0].trim();
            const value = key == 'label' || key == 'color' ? its[1].trim() : Number(its[1].trim());
            piece[key] = value;
          }
        })
      } else if (pieces.indexOf(':') > 0) {
        const items = pieces.split(':');
        const key = items[0].trim();
        const value = key == 'label' || key == 'color' ? items[1].trim() : Number(items[1].trim());
        piece[key] = value;
      }
      pieces = [piece]
    } else {
      pieces = null
    }

    if (rangeSymbolSize.indexOf(',') > 0) {
      rangeSymbolSize = rangeSymbolSize.split(',').map(function(num) { return Number(num) });
    } else if (Boolean(rangeSymbolSize)) {
      rangeSymbolSize = Number(rangeSymbolSize)
    } else {
      rangeSymbolSize = null
    }

    if (categories.indexOf(',') > 0) {
      categories = categories.split(',').map(function(item) { return item.trim() })
    } else {
      categories = null
    }

    const visualMap = {
      type: 'piecewise',
      dimension: visualDimension,
      splitNumber: splitNumber,
      pieces: pieces,
      categories: categories,
      inRange: {
        symbol: symbol,
        symbolSize: rangeSymbolSize
      },
      outOfRange: {
        symbol: symbol,
        symbolSize: rangeSymbolSize
      },
      controller: {
        inRange: {},
        outOfRange: {}
      },
      textStyle: {
        color: fontColor
      }
    }
    if (Boolean(inRangeColor)) {
      const _inRangeColor = inRangeColor.indexOf(',') > 0 ? inRangeColor.split(',').map(function(color) { return  color.trim() }) : [inRangeColor];
      visualMap.inRange.color = _inRangeColor;
      visualMap.controller.inRange.color = _inRangeColor;
    }
    if (Boolean(outRangeColor)) {
      visualMap.outOfRange.color = [outRangeColor];
      visualMap.controller.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.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) {
              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:axisLineType change:xAxisTick change:yAxisTick change:xAxisName change:yAxisName change:axisColor change:xAxisSplitLine change:yAxisSplitLine change:gridPadding change:xLabelRotate change:multiSeries change:customDimessions change:xDimession change:yDimession change:symbol change:symbolSize change:visualPosition change:visualDimension change:splitNumber change:pieces change:categories change:inRangeColor change:rangeSymbolSize change:colorAlpha change:colorLightness change:colorSaturation change:colorHue change:outRangeColor change:controllerColor 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)));
  }
}
