import { mapGetters } from "vuex";
import constants from '@/utils/constants'
import { downLoadBase64, getTreeDataList, random } from "@/utils";
import { getLineDataArr, getTreeNameByIds } from "@/utils/chart";
import html2canvas from 'html2canvas'

export const customPage = {
  computed: {
    form() {
      return this.$store.state.chart.form
    },
    changeNum() {
      return this.$store.state.chart.changeNum
    },
    patentKey() {
      return this.$store.state.chart.patentKey
    },
    treeList() {
      return this.$store.state.chart.treeList
    },
    treeKey() {
      return this.$store.state.chart.treeKey
    },
    selected() {
      return this.$store.state.chart.selected
    },
    selectedLoad() {
      return this.$store.state.chart.selectedLoad
    },
    count() {
      return this.$store.state.chart.count
    },
    matrix() {
      return this.$store.state.chart.matrix
    },
    reloadData() {
      return this.$store.state.chart.reloadData
    }
  },
  watch:{

  },
  methods: {
    getShowLabel(dict, value) {
      const data = dict.find(s => s.value === parseInt(value))
      if (data) {
        return data.label
      }
    },
  }
}

export const chartOption = {
  mixins: [customPage],
  props: {
    width: String,
    height: String
  },
  data() {
    return {}
  },
  methods: {
    async handleScreenshot(id, name) {
      const canvas = await html2canvas(document.getElementById(id))
      const base64 = canvas.toDataURL('image/jpg')
      downLoadBase64(base64, name + '.png')
    },
    getDataLabel() {
      return {
        show: this.form.setting.dataLabel,
        fontSize: this.form.setting.dataSize,
        position: this.form.setting.dataPosition,
        fontFamily: this.form.setting.fontFamily2,
        color: this.form.setting.labelColor,
        formatter: (val) => {
          switch (val.seriesType) {
            case 'sunburst':
              return val.name
            case 'heatmap':
              return val.value[2]
            case 'tree':
              return val.data.name
            case 'scatter':
              return !val.data[2] ? '' : val.data[2]
            case 'treemap':
              return `${val.name} (${val.value})`
            case 'map':
              return val.value ? `${val.name} \n ${val.value}` : ''
            default:
              if (val.value) {
                return val.value
              } else {
                return ''
              }
          }
        }
      }
    },
    getAxisName(dimension) {
      return this.form.setting[dimension]
    },
    getAxisData(dimension) {
      return this.selected[dimension]
    },
    getColor(name) {
      const color = this.form.setting.config.color.find(item => item.name === name);
      return color ? color.color : undefined
    },
    getDataCount(x, y, b = true) {
      if (b) {
        if (this.form.schema.x.type === 6) {
          const xn = getTreeDataList(this.form.source.x, []).find(item => item.name === x)
          if (xn) {
            x = xn.id
          }
        }
        if (this.form.schema.y.type === 6) {
          const yn = getTreeDataList(this.form.source.y, []).find(item => item.name === y)
          if (yn) {
            y = yn.id
          }
        }
      }
      if (x && y) {
        if (this.count[x]) {
          return this.count[x][y] || 0
        } else {
          return 0
        }
      }
      if (x && !y) {
        return this.count[x] || 0
      }
      if (!x && !y) {
        return random(0, 100)
      }
    },
    getSeriesData() {
      let data = [], count = this.count
      let source = this.selected.x
      switch (this.$options.name) {
        case 'CLine':
        case 'CArea':
        case 'CBar':
        case 'CColumn':
          source.map(s => {
            const color = this.form.setting.config.color.find(item => item.name === s);
            data.push({
              value: this.getDataCount(s),
              itemStyle: {
                color: color ? color.color : undefined
              }
            })
          })
          break
        case 'CDoughnut':
        case 'CPie':
          source.map(s => {
            const color = this.form.setting.config.color.find(item => item.name === s);
            data.push({
              value: this.getDataCount(s),
              name: s,
              label: {
                show: this.form.setting.dataLabel,
                fontSize: this.form.setting.dataSize,
                fontFamily: this.form.setting.fontFamily2,
                color: this.form.setting.labelColor,
                position: this.form.setting.dataPosition,
                formatter: ({ value, name, percent }) => {
                  let text = ""
                  if (this.form.setting.dataLabel) {
                    text += name
                  }
                  if (this.form.setting.dataLabel2) {
                    text += `-${value}件`
                  }
                  if (this.form.setting.dataLabel3) {
                    text += `/${percent}%`
                  }
                  return text
                }
              },
              itemStyle: {
                color: color ? color.color : undefined
              }
            })
          })
          break
      }
      return data
    },
    getAxisLabel(type, axis) {
      return  {
        interval: axis === 'x' ? (this.form.setting.interval ? 0 : undefined) : (this.form.setting.interval2 ? 0 : undefined),
        rotate: axis === 'x' ? this.form.setting.rotate : this.form.setting.rotate2,
        color: axis === 'x' ? this.form.setting.fontColor : this.form.setting.fontColor2,
        show: axis === 'x' ? this.form.setting.show : this.form.setting.show2,
        fontSize: axis === 'x' ? this.form.setting.fontSize : this.form.setting.fontSize2,
        fontFamily: axis === 'x' ? this.form.setting.fontFamily : this.form.setting.fontFamily2,
        fontWeight: (axis === 'x' ? this.form.setting.fontWeight : this.form.setting.fontWeight2) ? 'bold' : 'normal'
      }
    },
    getNameTextStyle(axis) {
      return {
        padding: axis === 'x' ? [this.form.setting.paddingTop, this.form.setting.paddingLeft, this.form.setting.paddingBottom, this.form.setting.paddingRight] : [this.form.setting.paddingTop2, this.form.setting.paddingLeft2, this.form.setting.paddingBottom2, this.form.setting.paddingRight2],
        color: axis === 'x' ? this.form.setting.fontColor : this.form.setting.fontColor2,
        fontSize: axis === 'x' ? this.form.setting.fontSize : this.form.setting.fontSize2,
        fontFamily: axis === 'x' ? this.form.setting.fontFamily : this.form.setting.fontFamily2,
        fontWeight: (axis === 'x' ? this.form.setting.fontWeight : this.form.setting.fontWeight2) ? 'bold' : 'normal'
      }
    },
    dateTimeSort() {
      let temp = JSON.parse(JSON.stringify(this.selected.x))
      let data = []
      let t, y, m
     
      temp.map(item => {
        switch (this.form.schema.x.expand) {
          case '月':
          case '年':
            data.push({
              name: item,
              time: new Date(item).getTime()
            })
            break
          case '季':
            t = item.split('-')
            y = t[0]
            m = (parseInt(t[1].replaceAll('Q', '')) - 1) * 3 + 1
            data.push({
              name: item,
              time: new Date(y + '-' + m).getTime()
            })
            break
          case '半年':
            t = item.split('-')
            y = t[0]
            m = parseInt(t[1].replaceAll('H', '')) * 6
            data.push({
              name: item,
              time: new Date(y + '-' + m).getTime()
            })
            break
          case 13:
          case 14:
          case '自定义':
            t = item.split('-')
            y = t[0]
            data.push({
              name: item,
              time: new Date(y + '-01').getTime()
            })
            break
        }
      })
      this.selected.x = data.sort((a, b) => a.time - b.time).map(item => item.name)
    },
    get1AxisOption(type, areaStyle) {
      if (this.form.schema.x.ptype === 2) {
        this.dateTimeSort()
      }
      let xAxis = {
        name: this.getAxisName('title1'),
        nameTextStyle: this.getNameTextStyle('x'),
        type: 'category',
        data: this.getAxisData('x'),
        nameLocation: this.form.setting.nameLocation,
        splitLine: {
          show: this.form.setting.splitLine
        },
        axisLabel: this.getAxisLabel('category', 'x')
      }
      let yAxis = {
        name: this.getAxisName('title2'),
        nameTextStyle: this.getNameTextStyle('y'),
        type: 'value',
        nameLocation: this.form.setting.nameLocation2,
        splitLine: {
          show: this.form.setting.splitLine2
        },
        axisLine:{
          show:this.form.setting.show2
        },
        axisLabel: this.getAxisLabel('value', 'y')
      }
      let series = [{
        data: this.getSeriesData(),
        type: type,
        areaStyle: areaStyle,
        itemStyle: {
          color: this.form.setting.config.color[0].color
        },
        barWidth: this.form.setting.barWidth,
        label: this.getDataLabel()
      }]
      let grid = {
        top: this.form.setting.gridTop + '%',
        left: this.form.setting.gridLeft + '%',
        right: this.form.setting.gridRight + '%',
        bottom: this.form.setting.gridBottom + '%',
        containLabel: true,
      }
      return {
        xAxis,
        yAxis,
        series,
        grid
      }
    },
    get2AxisOption(type, stack) {
      if (this.form.schema.x.ptype === 2) {
        this.dateTimeSort()
      }
      const enable = this.form.setting.config.line.enable
      const operator = this.form.setting.config.line.operator
      let series = this.selected.y.map(y => {
        return {
          name: y,
          type: type,
          stack: stack,
          itemStyle: {
            color: this.getColor(y)
          },
          barWidth: this.form.setting.barWidth,
          data: this.selected.x.map(x => this.getDataCount(x, y)),
          label: this.getDataLabel()
        }
      })
      let xAxis = {
        name: this.form.setting.title1,
        nameTextStyle: this.getNameTextStyle('x'),
        type: 'category',
        nameLocation: this.form.setting.nameLocation,
        data: this.selected.x,
        splitLine: {
          show: this.form.setting.splitLine
        },
        axisLabel: this.getAxisLabel('category', 'x')
      }
      let yAxis = [{
        name: this.form.setting.title2,
        nameTextStyle: this.getNameTextStyle('y'),
        type: 'value',
        nameLocation: this.form.setting.nameLocation2,
        splitLine: {
          show: this.form.setting.splitLine2
        },
        axisLine:{
          show:this.form.setting.show2
        },
        axisLabel: this.getAxisLabel('value', 'y')
      }]
      let legend = [...this.selected.y]
      if (enable && ([5, 6].indexOf(this.form.setting.type) !== -1)) {
        let name = this.form.setting.config.line.name
        series.push({
          name: name,
          type: 'line',
          yAxisIndex: 1,
          data: getLineDataArr(this.form, this.selected, this.count),
          itemStyle: {
            color: this.form.setting.config.line.color
          },
          label: {
            ...this.getDataLabel(),
            formatter({ value }) {
              return operator === 1 ? `${Math.round(parseFloat(value) * 100)} %` : value
            }
          }
        })
        yAxis.push({
          type: 'value',
          name: name,
        })
        legend.push(name)
      }
      let grid = {
        top: this.form.setting.gridTop + '%',
        left: this.form.setting.gridLeft + '%',
        right: this.form.setting.gridRight + '%',
        bottom: this.form.setting.gridBottom + '%',
        containLabel: true
      }
      return {
        legend: {
          show: this.form.setting.legend,
          data: legend,
          textStyle: {
            fontFamily: this.form.setting.fontFamily3,
            color: this.form.setting.legendColor,
            fontSize: this.form.setting.legendFontSize
          },
          ...this.getLegendLocation(),
          type: this.form.setting.type2,
        },
        grid,
        xAxis,
        yAxis,
        series
      }
    },
    getLegendLocation() {
      let x = ''
      let y = ''
      switch (this.form.setting.legendLocation) {
        case 'top':
          x = 'center'
          y = 'top'
          break
        case 'left':
          x = 'left'
          y = 'center'
          break
        case 'bottom':
          x = 'center'
          y = 'bottom'
          break
        case 'right':
          x = 'right'
          y = 'center'
          break
      }
      return {
        x: x,
        y: y,
        orient: ['top', 'bottom'].indexOf(this.form.setting.legendLocation) !== -1 ? 'horizontal' : "vertical",
      }
    },
    initChart(id, chartOption) {
      const chartDom = document.getElementById(id);
      const myChart = this.$echarts.init(chartDom);
      myChart.setOption(chartOption)
      // this.$store.commit('SET_MY_CHART', myChart)
      return myChart
    },
  }
}

export const chartOptionMixins = {
  mixins: [chartOption],
  mounted() {
    this.$nextTick(() => {
      this.initChart(this.id, this.getOption())
    })
  },
}
