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

export default {

  // 组件名称
  name: funnelChart,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${funnelChart}" class="${funnelChart}"></div>
    `
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${funnelChart} {
          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 t="1608617618619" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2551" width="30" height="30"><path d="M512 970.105263l-215.578947-328.757895h425.768421L512 970.105263z m-113.178947-274.863158l113.178947 177.852632 113.178947-177.852632H398.821053zM722.189474 592.842105H301.810526L134.736842 334.147368h754.526316L722.189474 592.842105z m-393.431579-53.894737h361.094737l97.010526-150.905263H231.747368L328.757895 538.947368zM883.873684 280.252632H134.736842L5.389474 75.452632H1024l-140.126316 204.8z m-716.8-53.894737h684.463158L916.210526 129.347368H102.4l64.673684 97.010527z" fill="#1890ff" p-id="2552"></path></svg>
        <div class="gjs-block-label">漏斗图</div>
      `,
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: '漏斗图',
      icon: 'globe',
      inPorts: [{
        uuid: 'in1',
        subType: 'json',
        description: {
          zh_CN: '输入1'
        }
      }],
    }
  },

  // 组件属性
  componentOptions() {
    return {
      name: funnelChart,
      resizable: true,
      dmode: 'absolute',
      droppable: false,
      traits: [
        {
          name: 'width',
          label: '漏斗图宽度',
          changeProp: 1,
        }, {
          name: 'orient',
          label: '漏斗图朝向',
          type: 'select',
          changeProp: 1,
          options: [{ id: 'vertical', name: '垂直' },{ id: 'horizontal', name: '水平' }],
        }, {
          name: 'sort',
          label: '数据排序',
          type: 'select',
          changeProp: 1,
          options: [{ id: 'ascending', name: '正序' },{ id: 'descending', name: '倒序' },{ id: 'none', name: '按数据顺序' }]
        }, {
          name: 'gap',
          label: '数据图形间距',
          type: 'number',
        }, {
          name: 'labelShow',
          label: '显示标签',
          changeProp: 1,
          type: 'checkbox',
        }, {
          name: 'labelPosition',
          label: '标签位置',
          changeProp: 1,
          type: 'select',
          options: [
            { id: 'left', name: '左侧(漏斗图朝向为垂直时有效)' },
            { id: 'right', name: '右侧(漏斗图朝向为垂直时有效)' },
            { id: 'top', name: '上侧(漏斗图朝向为水平时有效)' },
            { id: 'bottom', name: '下侧(漏斗图朝向为水平时有效)' },
            { id: 'inside', name: '内部' },
            { id: 'insideRight', name: '内部右侧' },
            { id: 'insideLeft', name: '内部左侧' },
            { id: 'leftTop', name: '左侧上部' },
            { id: 'leftBottom', name: '左侧下部' },
            { id: 'rightTop', name: '右侧上部' },
            { id: 'rightBottom', name: '右侧下部' },
          ]
        }, {
          name: 'labelFontColor',
          label: '标签字体颜色',
          changeProp: 1,
          type: 'color',
        }, {
          name: 'labelFontSize',
          label: '标签字体大小',
          changeProp: 1,
          type: 'number',
        }, {
          name: 'showLabelLine',
          label: '显示视觉引导线',
          changeProp: 1,
          type: 'checkbox',
        }, {
          name: 'gradient',
          label: '图形渐变',
          changeProp: 1,
          type: 'select',
          options: [{ id: 'none', name: '无' }, { id: 'line::0-0-0-1', name: '↓' }, { id: 'line::0-1-0-0', name: '↑' }, { id: 'line::0-0-1-0', name: '→' }, { id: 'line::1-0-0-0', name: '←' }, { id: 'line::0-0-1-1', name: '↘' }, { id: 'line::1-0-0-1', name: '↙' }, { id: 'line::0-1-1-0', name: '↗' }, { id: 'line::1-1-0-0', name: '↖' }]
        }, {
          name: 'gradientColor',
          label: '渐变颜色',
          changeProp: 1,
        }, {
          name: 'csv',
          label: '示例数据',
          changeProp: 1,
          type: 'csvDownload',
          preFileName: '线形图',
          datas: [["name", "DEMO-1"], ["one", 1], ["two", 2], ["three", 3], ["four", 4], ["five", 5]]
        }, {
          name: 'defaultData',
          changeProp: 1,
          type: 'hide'
        }
      ],
      width: '80%',
      sort: 'descending',
      orient: 'vertical',
      gap: 2,
      labelShow: true,
      labelPosition: 'right',
      labelFontColor: null,
      labelFontSize: 12,
      showLabelLine: false,
      gradient: 'none',
      gradientColor: 'rgba(10,255,179,0.2)|rgba(10,255,179,0.8)::rgba(10,255,179,0.2)|rgba(10,255,179,0.8)::rgba(10,255,179,0.2)|rgba(10,255,179,0.8)::rgba(10,255,179,0.2)|rgba(10,255,179,0.8)::rgba(10,255,179,0.2)|rgba(10,255,179,0.8)',
      defaultData:JSON.stringify([
        ["name", "DEMO-1"], 
        ["one", 60], 
        ["two", 40], 
        ["three", 20], 
        ["four", 80], 
        ["five", 100]
      ]).replace(/\"/g, "\\\""),
    }
  },

  onModelScript() {
    const dataSource = '{[ dataSource ]}';
    const bgColor = '{[ bgColor ]}';
    const borderColor = '{[ borderColor ]}';
    const fontColor = transferColorToRgba('{[ fontColor ]}');
    const fontSize = Number('{[ fontSize ]}');
    const titleText = '{[ titleText ]}';
    const titleColor = transferColorToRgba('{[ titleColor ]}');
    const titlePosition = ('{[ titlePosition ]}').toString();
    let colors = '{[ colors ]}';
    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 legendFontFamily = ('{[ legendFontFamily ]}').toString();
    const legendMap = ('{[ legendMap ]}').toString();

    const width = '{[ width ]}';
    const sort = '{[ sort ]}';
    const gap = Number('{[ gap ]}');
    const orient = '{[ orient ]}';
    const labelShow = Boolean('{[ labelShow ]}');
    const labelPosition = '{[ labelPosition ]}';
    const labelFontColor = transferColorToRgba('{[ labelFontColor ]}');
    const labelFontSize = Number('{[ labelFontSize ]}');
    const showLabelLine = Boolean('{[ showLabelLine ]}');
    const gradient = ('{[ gradient ]}').toString();
    let gradientColor = '{[ gradientColor ]}'; 
    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 (gradientColor.indexOf('::') > -1) {
      gradientColor = gradientColor.split('::').map(item => item.trim());
    } else if (Boolean(gradientColor)) {
      gradientColor = [gradientColor];
    }

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

    const legendShow = legendOrient != 'null';
    const legend = {
      show: legendShow,
      type: 'scroll',
      icon: legendIcon,
      itemGap: legendItemGap,
      itemWidth: legendItemWidth,
      itemHeight: legendItemHeight,
      textStyle: {
        fontFamily: legendFontFamily,
        fontSize: legendFontSize || fontSize,
        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
    }

    let label = {
      show: labelShow,
      position: labelPosition,
      fontSize: labelFontSize || fontSize
    };

    if ( labelFontColor ) {
      Object.assign(label, { color: labelFontColor });
    }

    let serieTemp = {
      type: 'funnel',
      width,
      sort,
      gap,
      orient,
      label,
      labelLine: {
        show: showLabelLine
      }
    };

    const self = this;
    const _id = self.getAttribute('id');
    const eventName = `call-${_id}`;
    const myChart = window.echarts.init(self);

    function transferColorToRgba(color, alpha = 1) {
      if (typeof color !== 'string' && !(color instanceof String)) return;
      color = color.charAt(0) === '#' ? color.substring(1) : color;
      if (color.length !== 6 && color.length !== 3) return ;
      if (color.length === 3) {
        color = color.replace(/(\w)(\w)(\w)/, '$1$1$2$2$3$3')
      }
      var reg = /\w{2}/g;
      var colors = color.match(reg);
      for (var i = 0; i < colors.length; i++) {
        colors[i] = parseInt(colors[i], 16).toString();
      }
      return 'rgba(' + colors.join() + ',' + alpha + ')';
    }
    function initChart(source) {
      myChart.clear();

      if (gradient && gradient !== 'none' && gradientColor) {
        const _gradient = gradient.split('::');
        const _type = _gradient[0];
        const _line = _gradient[1].split('-');
        const _colorStopsLen = gradientColor.length;
        let color = new Array();
        console.log(gradientColor)
        source.map((val, index) => {
          const colorStops = gradientColor[index < _colorStopsLen ? index : index % _colorStopsLen];
          const colorarray= colorStops.split('|');
          color.push({
            type: _type,
            x:_line[0], y:_line[1], x2:_line[2], y2:_line[3],
            colorStops: [
              { offset: 0, color: colorarray[0] },
              { offset: 1, color: colorarray[1] },
            ]
          });
        });
        console.log(color)
        Object.assign(serieTemp, { color });
      }
      const option = {
        title: title,
        legend: legend,
        dataset: { source },
        series: serieTemp
      };
      myChart.setOption(option);
      myChart.resize();

      if (window.prevEventType && window.prevEventType[eventName]) {
        myChart.off(window.prevEventType[eventName]);
      }
    }

    initChart(defaultData);

    window.addEventListener('resize', function () {
      myChart.resize();
    }, false)
    let hasTransfer = false;
    // 有 dashboardHost 说明是运行模式
    if (window.spSocket) {
      window.spSocket.subscribe({
        eventName: eventName,
        callback: function (_data) {
          let _in1Str = _data.data.in1;
          if (_in1Str) {
            const data = JSON.parse(_in1Str);
            initChart(data);
          }
        }
      });
    }

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

  onViewInit() {
    this.updateScript();
    const evn = echartsBasicListen + `
      change:width
      change:sort
      change:gap
      change:orient
      change:labelShow
      change:labelPosition
      change:labelFontColor
      change:labelFontSize
      change:gradientColor
      change:gradient
      change:showLabelLine
    `;
    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)));
  }
}
