<template>
  <div class="fx-column">
    <div class="fx-row fx-bet-cen">
      <div class="fx-1">
        <mx-chart ref="bar" :options="chartOptions.bar" :height="'450px'"></mx-chart>
      </div>
      <div v-if="chartOptions.pie" class="fx-row fx-cen-cen" style="width: 450px">
        <mx-chart ref="pie" :options="chartOptions.pie" :height="'450px'"></mx-chart>
      </div>
    </div>
    <template v-if="chartOptions.pies&&chartOptions.pies.length">
      <el-divider></el-divider>
      <div class="fx-row fx-bet-cen pl30">
        <div v-for="(pie,idx) in chartOptions.pies" :key="idx" class="fx-1 fx-row fx-cen-cen">
          <mx-chart ref="pies" :options="pie" :height="'400px'"></mx-chart>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
import MxChart from '@/components/MxChart/index'
import config from '@/common/mx-config'

export default {
  name: 'elective-generation-charts',
  components: { MxChart },
  props: ['chartBinding'],
  computed: {
    chartOptions() {
      const options = this.chartBinding.generation.options
      let data = this.chartBinding.chartData?.accumulates
      let generation = this.chartBinding.chartData?.generation
      let desc = '录取超缺数量'
      if (this.chartBinding.generation.active == options.primary.value) {
        generation = options.primary.value // force override primary chart data
        data = this.chartBinding.generation.summary.find(item => item.generation == generation)?.categories
        desc = '报名超缺数量'
      }
      if (!data?.length) return {}
      const currentOpt = Object.values(options).find(opt => opt.value == generation)

      // xAxis data - round groups
      const roundGroups = this.chartBinding.generation.roundGroups
      const xAxis = roundGroups.map(rg => rg.groupName)

      // yAxis data
      let series = []
      let valueNameGroup = null
      let valueNameGroups = []
      if (generation == options.primary.value) {
        // 初选报名需要单独处理
        const multiplePreference = data.length > 1
        const preferenceSeries = data.map((single, idx) => {
          const prefix = multiplePreference ? `第${idx + 1}志愿/` : ''
          const stackName = 'preference_' + idx
          const singleGroup = { dimension: !multiplePreference ? '报名人数' : `第${idx + 1}志愿`, values: [] }
          const singleSeries = this.barSeriesMissingAndOverFactory(
            roundGroups,
            rg => rg.expectedCount * 1,
            rg => {
              let actualCount = single.find(item => item.category == 'actualCount')?.values
                .find(item => item.groupId == rg.groupId)?.value || 0
              actualCount = actualCount * 1
              singleGroup.values.push({ value: actualCount, name: rg.groupName })
              return actualCount
            },
            stackName,
            [prefix + '报名人数', , prefix + '缺少人数', prefix + '超出人数']
          )
          let unfinishedCount = single.find(item => item.category == 'actualCount')?.values?.first()?.value || 0
          unfinishedCount = unfinishedCount * 1
          singleGroup.values.push({ value: unfinishedCount, name: '未报名' })
          valueNameGroups.push(singleGroup)
          return singleSeries
        })
        series = preferenceSeries.reduce((prev, cur) => prev.concat(cur), [])
        if (valueNameGroups.length > 1) {
          valueNameGroup = valueNameGroups.reduce((prev, cur) => {
            const merge = this.deepClone(cur) // NOTE: DO NOT modify raw item
            merge.dimension = '报名人次'
            merge.values.forEach(val => {
              const match = prev.values.find(i => i.name == val.name)
              val.value = val.value * 1 + (match?.value || 0) * 1
            })
            return merge
          }, { values: [] })
        } else {
          valueNameGroup = valueNameGroups?.first()
          valueNameGroups = []
        }
      } else {
        valueNameGroup = { dimension: '录取人数', values: [] }
        series = this.barSeriesMissingAndOverFactory(
          roundGroups,
          rg => rg.expectedCount * 1,
          rg => {
            const approvedCount = data.find(item => item.category == 'approvedCount')?.values
              .find(item => item.groupId == rg.groupId)?.value || 0
            const forcedCount = data.find(item => item.category == 'forcedCount')?.values
              .find(item => item.groupId == rg.groupId)?.value || 0
            const enrollCount = approvedCount * 1 + forcedCount * 1
            valueNameGroup.values.push({ value: enrollCount, name: rg.groupName })
            return enrollCount
          },
          'Indicator',
          []
        )
        valueNameGroup.values.push({ value: this.chartBinding.generation.status.disenrollCount, name: '未录取' })
      }
      setTimeout(() => {
        this.$refs.bar?.resize()
        this.$refs.pie?.resize()
      }, 200)
      return {
        bar: this.barOptionFactory('组合统计/' + currentOpt.title, desc, xAxis, series),
        pie: valueNameGroup && this.pieOptionFactory('组合统计/' + currentOpt.title, valueNameGroup.dimension, '', valueNameGroup.values),
        pies: valueNameGroups.map(g => this.pieOptionFactory('组合统计/' + currentOpt.title, g.dimension, '', g.values))
      }
    }
  },
  methods: {
    pieOptionFactory(title, subTitle, dimensionName, valueNamePairs) {
      return {
        title: {
          text: title,
          subtext: subTitle,
          left: 'center'
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          orient: 'vertical',
          left: 'left'
        },
        series: [
          {
            name: dimensionName,
            type: 'pie',
            radius: '50%',
            data: valueNamePairs,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      }
    },
    barOptionFactory(title, subTitle, xAxis, series) {
      return {
        title: {
          text: title,
          subtext: subTitle,
          left: 'center'
        },
        xAxis: {
          type: 'category',
          data: xAxis
        },
        yAxis: {
          type: 'value'
        },
        series: series,
        tooltip: {
          trigger: 'item'
        }
      }
    },
    barSeriesMissingAndOverFactory(sourceArr, baseGetter, actualGetter, stackName, lineNames) {
      // 本来是创建3条线：基础线，缺少线，超出线，但图表的提示展示不方便
      // 所以这里创建4条线：期望线，实际线，缺少线，超出线。（期望线，实际线保持相同颜色）
      const series = []
      const commonDefines = {
        type: 'bar',
        stack: stackName,
        emphasis: {
          focus: 'series',
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
      const actualLine = {
        ...commonDefines,
        name: lineNames[0] || '录取人数',
        data: []
      }
      const expectedLine = {
        ...commonDefines,
        name: lineNames[1] || '设置人数',
        data: []
      }
      const missingLine = {
        ...commonDefines,
        name: lineNames[2] || '缺少人数',
        data: []
      }
      const overLine = {
        ...commonDefines,
        name: lineNames[3] || '超出人数',
        data: []
      }
      sourceArr.forEach(item => {
        const settingCount = baseGetter(item)
        const enrollCount = actualGetter(item)
        if (settingCount <= 0 || settingCount == enrollCount) {
          expectedLine.data.push(0)
          actualLine.data.push({ value: enrollCount, itemStyle: { color: config.color.primary_report } })
          missingLine.data.push(0)
          overLine.data.push(0)
        } else {
          const subCount = Math.abs(settingCount - enrollCount)
          const baseCount = Math.min(settingCount, enrollCount)
          if (enrollCount > settingCount) {
            expectedLine.data.push({ value: baseCount, itemStyle: { color: config.color.primary_report } })
            actualLine.data.push(0)
            missingLine.data.push(0)
            overLine.data.push({ value: subCount, itemStyle: { color: config.color.error } })
          } else {
            expectedLine.data.push(0)
            actualLine.data.push({ value: baseCount, itemStyle: { color: config.color.primary_report } })
            missingLine.data.push({ value: subCount, itemStyle: { color: config.color.yellow_report } })
            overLine.data.push(0)
          }
        }
      })
      series.push(actualLine, expectedLine, missingLine, overLine)
      return series
    }
  }
}
</script>

<style scoped>

</style>
