<template>
  <mx-table ref="table" :prop-defines="resolvedTable.columns" :rows="resolvedTable.rows" border>
    <template #elective-cell="{value, label, prop}">
      <el-popover trigger="hover" :disabled="(value&&value.disabled)||!!!prop.queryCode"
                  popper-class="zero-padding-popover">
        <div class="fx-column">
          <el-button plain type="text" @click="goDetails(value, label)">查看名单</el-button>
        </div>
        <div slot="reference" v-if="value" :style="getCellStyles(value)">
          <span v-if="value.star">*</span>
          <span>{{ value && value.value }}</span>
        </div>
      </el-popover>
    </template>
  </mx-table>
</template>

<script>
import config from '@/common/mx-config'
import MxTransferMixin from '@/components/mx-transfer-mixin'

export default {
  mixins: [MxTransferMixin],
  name: 'elective-generation-table',
  props: ['chartBinding'],
  computed: {
    resolvedTable() {
      // setting data
      const columns = { groupName: { label: '组合', fixed: true }, expectedCount: { label: '设置人数', fixed: true } }
      const rows = this.deepClone(this.chartBinding.generation.roundGroups) // TODO: need clone?
      // generation data
      const mergedColumns = []
      this.chartBinding.tableData.forEach(item => {
        if (this.chartBinding.generation.hiddenGenerations.includes(item.generation)) return
        const isPreference = item.categories.every(item => Array.isArray(item))
        const generationQueryableCategories = []
        const generationQueryableIgnoreGroupCategories = []
        const ext = {
          roundId: item.roundId,
          generation: item.generation,
          queryableCategories: generationQueryableCategories, // 本代支持查询的列
          ignoreGroupCategories: generationQueryableIgnoreGroupCategories // 本代支持查询，且与组合无关的列
        }

        const subColumns = {}
        const mergedHeaderKey = 'generation_' + item.generation
        const options = Object.values(this.chartBinding.generation.options)
        const mergedHeaderOpt = options.find(opt => opt.value == item.generation)
        const mergedHeaderDefine = { label: mergedHeaderOpt.title, children: subColumns }
        if (isPreference) {
          const cnIndexer = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
          item.categories.forEach((subItem, idx) => {
            const cnIndex = idx < cnIndexer.length ? cnIndexer[idx] : (idx + 1)
            const innerHeaderKey = mergedHeaderKey + '_' + idx
            const innerHeaderDefine = item.categories.length > 1
              ? { label: `${cnIndex}志愿`, children: {} }
              : mergedHeaderDefine
            const overrideQueryName = item.categories.length > 1 ? innerHeaderDefine.label : ''
            subItem.forEach(data => this.resolveTableGeneration(ext, data, innerHeaderDefine.children, rows, mergedColumns, innerHeaderKey, false, overrideQueryName))
            columns[innerHeaderKey] = innerHeaderDefine
          })
        } else {
          item.categories.forEach(data => this.resolveTableGeneration(ext, data, subColumns, rows, mergedColumns))
          columns[mergedHeaderKey] = mergedHeaderDefine
        }
      })
      // accumulate data
      if (this.chartBinding.generation.active > this.chartBinding.generation.options.primaryDM.value
        && this.chartBinding.chartData?.accumulates?.length) {
        const prefix = 'accumulate_'
        const ext = {
          roundId: this.chartBinding.generation.status.roundId,
          generation: -1, // for detail page special display,
          queryableCategories: [], // 本代支持查询的列
          ignoreGroupCategories: [] // 本代支持查询，且与组合无关的列
        }
        this.chartBinding.chartData.accumulates.forEach(acc => this.resolveTableGeneration(ext, acc, columns, rows, mergedColumns, prefix, true))
      }
      // completed
      this.$refs.table?.scrollToRight()
      return {
        mergedColumns,
        columns,
        rows
      }
    }
  },
  mounted() {
    window.tableVue = this
  },
  provide() {
    return {
      mergeTable: this.mergeTable
    }
  },
  methods: {
    resolveTableGeneration(ext, data, columnsRef, rowsRef, mergedColumnsRef, prefix = '', fixed = false, overrideQueryName = '') {
      // resolve core
      const prop = prefix + ext.generation + '_' + data.category
      const name = data.displayName
      const shouldMerge = data.values.length != rowsRef.length || data.values.some(v => v.groupId == 0)
      if (data.queryCode) {
        let nextName = data.displayName
        if (overrideQueryName) nextName = overrideQueryName + '/' + nextName
        ext.queryableCategories.push({ id: data.queryCode, name: nextName, detailName: data.detailName })
        if (shouldMerge) ext.ignoreGroupCategories.push(data.queryCode)
      }

      columnsRef[prop] = { label: name, slot: 'elective-cell', fixed: fixed, queryCode: data.queryCode }
      if (!shouldMerge) {
        data.values.forEach(val => {
          const row = rowsRef.find(row => row.groupId == val.groupId)
          if (row) {
            row[prop] = { ...ext, ...val, queryCode: data.queryCode }
          }
        })
      } else {
        // mark for table rows merge
        mergedColumnsRef.push(prop)

        // keep value in display row
        const val = data.values.first()
        const row = rowsRef.first()
        row[prop] = { ...ext, ...val, queryCode: data.queryCode }
      }
    },
    mergeTable({ row, column, rowIndex }) {
      if (this.resolvedTable.mergedColumns.includes(column.property)) {
        return rowIndex === 0 ? [this.resolvedTable.rows.length, 1] : [0, 0]
      }
    },
    getCellStyles(option) {
      const styles = {}
      if (option.color) {
        const map = {
          R: config.color.error,
          r: config.color.error,
          G: config.color.yellow_up,
          g: config.color.yellow_up,
          B: config.color.blue_up,
          b: config.color.blue_up
        }
        styles.color = map[option.color] || option.color
      }
      return styles
    },
    goDetails(option) {
      const path = '/elective/generation/detail'
      const nextData = {
        year: this.chartBinding.generation.status.year,
        roundId: this.chartBinding.generation.status.roundId,
        roundName: this.chartBinding.generation.status.roundName,
        queryGeneration: option.generation,
        queryGroupId: option.groupId,
        queryCode: option.queryCode,
        queryableCategories: option.queryableCategories,
        ignoreGroupCategories: option.ignoreGroupCategories,
        groups: this.chartBinding.generation.roundGroups.map(rg => ({ groupId: rg.groupId, groupName: rg.groupName }))
      }
      this.transferTo(path, nextData)
    },
    simulateGoDetails() {
      if (this.resolvedTable.rows.length == 0) {
        this.msgInfo('没有数据')
        return
      }
      const current = this.chartBinding.generation.current
      for (const column of Object.values(this.resolvedTable.columns)) {
        if (column.children) {
          for (const subColProp of Object.keys(column.children)) {
            for (const row of this.resolvedTable.rows) {
              const val = row[subColProp]
              if (val?.generation == current) {
                this.goDetails(val)
                return
              }
            }
          }
        }
      }
    }
  }
}
</script>

<style scoped>

</style>
