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


  // 组件名称
  name: polarBarChart,

  // 前面板html模板
  viewTemplate() {
    return `
      <div data-gjs-type="${polarBarChart}" class="${polarBarChart}"></div>
    `
  },
  // 前面板html样式
  viewStyle() {
    return `
      <style>
        .${polarBarChart} {
          position: absolute;
          width: 500px;
          height: 300px;
        }
      </style>
    `
  },

  // 编辑器右侧块管理器中显示属性配置
  blockOptions() {
    return {
      category: CATEGORIES.ECHARTS,
      label: `
        <svg class="gjs-block-svg" viewBox="-4 -4 32 32" xmlns="http://www.w3.org/2000/svg">
          <path d="M12,2v1.5c4.7,0,8.5,3.8,8.5,8.5s-3.8,8.5-8.5,8.5S3.5,16.7,3.5,12H2c0,5.5,4.5,10,10,10s10-4.5,10-10S17.5,2,12,2z"/>
          <path d="M12,4.5V6c3.3,0,6,2.7,6,6s-2.7,6-6,6v1.5c4.1,0,7.5-3.4,7.5-7.5S16.1,4.5,12,4.5z"/>
          <path d="M12,8.5c1.9,0,3.5,1.6,3.5,3.5H17c0-2.8-2.2-5-5-5V8.5z"/>
        </svg>
        <div class="gjs-block-label">极坐标<br>柱形图</div>
      `
    };
  },

  // 后面板显示属性配置
  spOptions() {
    return {
      label: '极坐标柱形图',
      icon: 'globe',
      docUrl: 'https://www.yuque.com/docs/share/24f111e1-32a7-45db-9d62-8738948d47c6#',
      author: '秋水',
      email: 'qiushui.smy@xuelangyun.com',
      inPorts: [{
        uuid: 'in1',
        subType: 'json',
        description: {
          zh_CN: '输入1'
        }
      }, {
        uuid: 'in2',
        subType: 'all',
        description: {
          zh_CN: 'loading'
        }
      }]
    }
  },

  // 组件属性
  componentOptions() {
    return {
      name: polarBarChart,
      resizable: true,
      dmode: 'absolute',
      droppable: false,
      traits: [
        {
          name: 'polarCenter',
          label: '极坐标中心',
          changeProp: 1
        }, {
          name: 'polarRadius',
          label: '极坐标半径(%)',
          changeProp: 1
        }, {
          name: 'axisColor',
          label: '坐标轴颜色',
          changeProp: 1,
          type: 'color'
        }, {
          name: 'angleAxisLine',
          label: '角度轴轴线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'angleAxisTickLabel',
          label: '角度轴刻度',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'angleAxisFontFamily',
          label: '角度轴刻度字体',
          changeProp: 1,
          type: 'select',
          options: [
            { id: 'sans-serif', name: '默认' },
            { id: '庞门正道', name: '庞门正道' },
            { id: 'DS-Digital', name: 'DS-Digital' }
          ]
        }, {
          name: 'angleAxisSplitLine',
          label: '角度轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'radiusAxisName',
          label: '半径轴名称',
          changeProp: 1,
        }, {
          name: 'radiusAxisNameFontsize',
          label: '半径轴名称字号',
          changeProp: 1,
          type: 'number',
          min: 9,
          step: 1
        }, {
          name: 'radiusAxisNamePosition',
          label: '半径轴名称位置',
          changeProp: 1,
          type: 'select',
          options: [
            { id: 'end', name: '末尾' },
            { id: 'start', name: '开始' },
          ]
        }, {
          name: 'radiusAxisLine',
          label: '半径轴轴线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'radiusAxisLineWidth',
          label: '半径轴线宽',
          changeProp: 1,
          type: 'number',
          min: 1,
          step: 1
        }, {
          name: 'radiusAxisTickLine',
          label: '半径轴刻度线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'boundaryGap',
          label: '半径轴两边留白',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'radiusAxisTickLabel',
          label: '半径轴刻度',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'radiusLabelMap',
          label: '半径轴刻度值',
          changeProp: 1,
        }, {
          name: 'radiusAxisFontFamily',
          label: '半径轴刻度字体',
          changeProp: 1,
          type: 'select',
          options: [
            { id: 'sans-serif', name: '默认' },
            { id: '庞门正道', name: '庞门正道' },
            { id: 'DS-Digital', name: 'DS-Digital' }
          ]
        }, {
          name: 'radiusAxisSplitLine',
          label: '半径轴分割线',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'spliLineWidth',
          label: '半径轴分割线线宽',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'barWidth',
          label: '柱宽',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'barGap',
          label: '柱间距(%)',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'stack',
          label: '数据堆叠',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'clockwise',
          label: '顺时针',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'startAngle',
          label: '起始刻度角度',
          changeProp: 1,
          type: 'number'
        }, {
          name: 'roundCap',
          label: '柱条端部圆弧效果',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'showBackground',
          label: '显示柱条背景色',
          changeProp: 1,
          type: 'checkbox'
        }, {
          name: 'backgroundColor',
          label: '柱条背景色',
          changeProp: 1,
          type: 'color'
        }, {
          name: 'radiusDimension',
          label: '半径轴数据维度',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1
        }, {
          name: 'angleDimension',
          label: '角度轴数据维度',
          changeProp: 1,
        }, {
          name: 'min',
          label: '最小值',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1
        }, {
          name: 'max',
          label: '最大值',
          changeProp: 1,
          type: 'number',
          min: 0,
          step: 1
        }, {
          name: 'seriesZIndex',
          label: '数据序列z轴值',
          changeProp: 1,
          type: 'number',
          min: 0,
          max: 1
        }, {
          name: 'pointerType',
          label: 'Tooltip指示器类型',
          changeProp: 1,
          type: 'select',
          options: [{ id: 'line', name: '直线' }, { id: 'shadow', name: '阴影' }, { id: 'cross', name: ' 十字准星' }, { id: 'none', name: '无' }]
        }, {
          name: 'pointerColor',
          label: '指示器颜色',
          changeProp: 1,
          type: 'color'
        }, {
          name: 'csv',
          label: '示例数据',
          changeProp: 1,
          type: 'csvDownload',
          preFileName: '极坐标柱形图',
          datas: [["name", "A", "B", "C", "D"], ["percent", 41, 32, 50, 12]]
        }, {
          name: 'defaultData',
          changeProp: 1,
          type: 'hide'
        }
      ],
      defaultData:JSON.stringify([["name", "A", "B", "C", "D"], ["percent", 41, 32, 50, 12]]).replace(/\"/g, "\\\""),
      'legendPosition': 'right: 10%, top: center',
      'legendOrient': 'vertical',
      'polarCenter': '36%,50%',
      'polarRadius': '30, 80',
      'axisColor': '#333333',
      'clockwise': true,
      'angleAxisLine': true,
      'angleAxisTickLabel': true,
      'angleAxisSplitLine': true,
      'angleAxisFontFamily': 'sans-serif',
      'angleDimension': '1,2,3,4',
      'radiusAxisLine': true,
      'radiusAxisLineWidth': 1,
      'radiusAxisTickLabel': true,
      'radiusAxisTickLine': true,
      'radiusAxisSplitLine': true,
      'radiusAxisName': null,
      'radiusAxisNameFontsize': 12,
      'radiusAxisNamePosition': 'end',
      'radiusLabelMap': null,
      'radiusAxisFontFamily': 'sans-serif',
      'radiusDimension': 0,
      'spliLineWidth': 1,
      'barWidth': 12,
      'barGap': 100,
      'stack': false,
      'startAngle': 90,
      'roundCap': false,
      'showBackground': false,
      'boundaryGap': true,
      'backgroundColor': 'rgba(180, 180, 180, 0.2)',
      'seriesZIndex': 0,
      'pointerType': 'line',
      'pointerColor': 'rgba(255,255,255,0.2)',
    }
  },

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

    let polarCenter = ('{[ polarCenter ]}').toString();
    let polarRadius = '{[ polarRadius ]}';
    const axisColor = '{[ axisColor ]}';
    const boundaryGap = Boolean('{[ boundaryGap ]}');
    const min = '{[ min ]}';
    const max = '{[ max ]}';
    const clockwise = Boolean('{[ clockwise ]}');
    const angleAxisLine = Boolean('{[ angleAxisLine ]}');
    const angleAxisTickLabel = Boolean('{[ angleAxisTickLabel ]}');
    const angleAxisSplitLine = Boolean('{[ angleAxisSplitLine ]}');
    const radiusAxisLine = Boolean('{[ radiusAxisLine ]}');
    const radiusAxisTickLabel = Boolean('{[ radiusAxisTickLabel ]}');
    const radiusAxisTickLine = Boolean('{[ radiusAxisTickLine ]}');
    const radiusAxisSplitLine = Boolean('{[ radiusAxisSplitLine ]}');
    const radiusLabelMap = '{[ radiusLabelMap ]}';
    const radiusAxisName = ('{[ radiusAxisName ]}').toString();
    const radiusAxisLineWidth = Number('{[ radiusAxisLineWidth ]}');
    const radiusAxisNameFontsize = Number('{[ radiusAxisNameFontsize ]}');
    const radiusAxisNamePosition = ('{[ radiusAxisNamePosition ]}').toString();
    const angleAxisFontFamily = ('{[ angleAxisFontFamily ]}').toString();
    let angleDimension = ('{[ angleDimension ]}').toString();
    const radiusAxisFontFamily = ('{[ radiusAxisFontFamily ]}').toString();
    const barWidth = '{[ barWidth ]}';
    const barGap = ('{[ barGap ]}').toString() + '%';
    const stack = Boolean('{[ stack ]}');
    const startAngle = Number('{[ startAngle ]}');
    const roundCap = Boolean('{[ roundCap ]}');
    const showBackground = Boolean('{[ showBackground ]}');
    const backgroundColor = '{[ backgroundColor ]}';
    const radiusDimension = Boolean('{[ radiusDimension ]}') ? Number('{[ radiusDimension ]}') : 0;
    const spliLineWidth = Boolean('{[ spliLineWidth ]}') ? Number('{[ spliLineWidth ]}') : 1;
    const seriesZIndex = Boolean('{[ seriesZIndex ]}') ? Number('{[ seriesZIndex ]}') : 0;
    const pointerType = ('{[ pointerType ]}').toString();
    const pointerColor = '{[ pointerColor ]}';
    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]
    } else {
      colors = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
    }

    polarCenter = polarCenter.split(',').map(item => item.trim());

    angleDimension = angleDimension.split(',').map(item => Number(item.trim()));

    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
    }

    if (polarRadius.indexOf(',') > 0) {
      polarRadius = polarRadius.split(',').map(function (item) { return item.trim() + '%' })
    } else if (Boolean(polarRadius)) {
      polarRadius += '%';
    }

    const serieTemp = {
      type: 'bar',
      coordinateSystem: 'polar',
      barWidth: barWidth,
      barGap: barGap,
      zlevel: seriesZIndex
    };
    if (stack) {
      serieTemp.stack = 'stack';
    }
    if (roundCap) {
      serieTemp.roundCap = true;
    }
    if (showBackground) {
      serieTemp.showBackground = showBackground;
      serieTemp.backgroundStyle = {
        color: backgroundColor
      };
    }
    const radiusAxis = {
      type: 'category',
      z: 10,
      boundaryGap: boundaryGap,
      name: radiusAxisName,
      nameLocation: radiusAxisNamePosition,
      axisLine: {
        show: radiusAxisLine,
        lineStyle: {
          width: radiusAxisLineWidth,
          color: axisColor
        }
      },
      axisTick: {
        show: radiusAxisTickLine,
        lineStyle: {
          width: radiusAxisLineWidth,
        }
      },
      axisLabel: {
        show: radiusAxisTickLabel,
        fontSize: fontSize,
        fontFamily: radiusAxisFontFamily,
        color: fontColor,
        interval: 0,
      },
      splitLine: {
        show: radiusAxisSplitLine,
        lineStyle: {
          color: axisColor,
          opacity: 0.4,
          width: spliLineWidth
        }
      }
    };
    if (Boolean(radiusAxisName)) {
      radiusAxis.nameTextStyle = {
        fontSize: radiusAxisNameFontsize
      }
    }
    const angleAxis = {
      type: 'value',
      startAngle: startAngle,
      clockwise: clockwise,
      axisLine: {
        show: angleAxisLine,
        lineStyle: {
          color: axisColor
        }
      },
      axisTick: { show: angleAxisTickLabel },
      axisLabel: {
        show: angleAxisTickLabel,
        fontSize: fontSize,
        fontFamily: angleAxisFontFamily,
        color: fontColor
      },
      splitLine: {
        show: angleAxisSplitLine,
        lineStyle: {
          color: axisColor,
          opacity: 0.4
        }
      }
    };
    if (min) {
      angleAxis.min = Number(min)
    }
    if (max) {
      angleAxis.max = Number(max)
    }

    let _radiusLabelMap;
    if (radiusLabelMap.indexOf(':') > 0) {
      let _radiusLabelArr;
      _radiusLabelMap = {};
      if (radiusLabelMap.indexOf(',') > 0) {
        _radiusLabelArr = radiusLabelMap.split(',');
      } else {
        _radiusLabelArr = [radiusLabelMap]
      }
      _radiusLabelArr.forEach(function (item) {
        if (item.indexOf(':') > 0) {
          const _item = item.trim().split(':').map(v => v.trim());
          _radiusLabelMap[_item[0].toString().toLocaleLowerCase()] = _item[1];
        }
      });
      radiusAxis.axisLabel.formatter = function (name) {
        return _radiusLabelMap[name.toString().toLocaleLowerCase()] || name
      }
    } else {
      radiusAxis.axisLabel.formatter = null
    }

    const tooltip = {
      show: true,
      trigger: 'axis',
      axisPointer: {
        type: pointerType,
        lineStyle: {
          color: pointerColor
        },
        shadowStyle: {
          color: pointerColor
        },
        crossStyle: {
          color: pointerColor
        }
      },
      textStyle: {
        fontSize: fontSize
      }
    };
    if (_radiusLabelMap || _legendMap) {
      tooltip.formatter = function (params) {
        if (params.length) {
          const radiusAxisName = _radiusLabelMap ? _radiusLabelMap[params[0].name.toString().toLocaleLowerCase()] || params[0].name : params[0].name;
          const list = params.map(function (item) {
            const seriesName = _legendMap ? _legendMap[item.seriesName.toString().toLocaleLowerCase()] || item.seriesName : item.seriesName;
            return "<br /><span style='display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:" + item.color + "'></span>" + seriesName + ": " + item.data[1]
          })
          return radiusAxisName + list.join(' ')
        }
      }
    }

    const myChart = window.echarts.init(this);
    const self = this;

    function initChart(source) {
      myChart.clear();
      const series = angleDimension.map(function (angle) {
        return Object.assign({}, serieTemp, {encode: {radius: radiusDimension, angle, seriesName: angle}})
      });
      const option = {
        title: title,
        tooltip: tooltip,
        legend: legend,
        polar: {
          center: polarCenter,
          radius: polarRadius
        },
        radiusAxis: radiusAxis,
        angleAxis: angleAxis,
        dataset: {
          source: source
        },
        series: series
      };
      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) {
      myChart.hideLoading();
      initChart(JSON.parse(ds))
    });
  },

  onViewInit() {
    this.updateScript();
    const evn = echartsBasicListen + `
    change:defaultData
    change:seriesZIndex 
    change:spliLineWidth 
    change:radiusAxisTickLine 
    change:roundCap 
    change:startAngle 
    change:polarCenter 
    change:polarRadius 
    change:axisColor 
    change:angleAxisLine
    change:angleAxisTickLabel 
    change:angleAxisSplitLine 
    change:angleAxisFontFamily
    change:angleDimension 
    change:radiusAxisLine 
    change:radiusAxisTickLabel 
    change:radiusAxisSplitLine 
    change:radiusLabelMap 
    change:radiusAxisFontFamily 
    change:radiusDimension 
    change:barWidth
    change:barGap 
    change:showBackground
    change:backgroundColor
    change:stack
    change:min
    change:max
    change:clockwise
    change:radiusAxisName
    change:radiusAxisNameFontsize
    change:radiusAxisNamePosition
    change:radiusAxisLineWidth
    change:boundaryGap
    change:pointerType
    change:pointerColor
    `;
    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)));
  }
}
