<template>
  <div :id="id">
    <el-table :data="tableData" :span-method="objectSpanMethod" :cell-style="cellStyle" border header-row-class-name="custom-table-header" style="margin-bottom: 40px;">
      <el-table-column v-if="showIndex" type="index" label="序号" align="center"></el-table-column>
      <el-table-column v-for="col in tableCol" :prop="col.prop" :label="col.label" align="center" show-overflow-tooltip></el-table-column>
      <table-column v-if="treeType !== 0" v-for="col in source" :column="col" />
    </el-table>
  </div>
</template>

<script>
import { chartOption, customPage } from "@/views/analyse/custom/mixins";
import { mapGetters } from "vuex";
import { findChildren, getTreeDataList, getTreeLastChildren } from "@/utils";
import TableColumn from "./Column";
import { getXAxisName } from "@/utils/chart";

export default {
  name: "CTable",
  components: { TableColumn },
  mixins: [chartOption],
  data() {
    return {
      id: 'cTable',
      tableData: [],
      tableCol: [],
      showIndex: false,
      isLevel: 0,
      maxLevel: 0,
      treeType: 0,
      rowspan: {},
      source: [],
      number: ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'],
      tableConfig: []
    }
  },
  computed: {
    ...mapGetters(['patentField'])
  },
  mounted() {
    if (this.form.schema.x.type === 6 || this.form.schema.y.type === 6) {
      this.showIndex = false
      this.initTree(this.form.schema.x.type === 6, this.form.schema.y.type === 6)
    } else {
      this.showIndex = true
      this.initData()
    }
    this.tableConfig = JSON.parse(JSON.stringify(this.form.setting.config.table))
  },
  methods: {
    cellStyle({ row, column, rowIndex, columnIndex }) {
      const { property, label, type } = column
      let color = ''
      let level = ['level-1', 'level-2', 'level-3', 'level-4', 'level-5', 'level-6', 'level-7', 'level-8', 'level-9', 'level-10']
      if (['name', 'index', ...level].indexOf(property) === -1 && type === 'default') {
        const data = row[property]
        this.tableConfig.map(item => {
          if (data >= item.min && data <= item.max) {
            color = item.color
          }
        })
      }
      return {
        background: color,
        color: '#000'
      }
    },
    getTreeLastChildren(dimension) {
      const tree = getTreeDataList(this.form.source[dimension], [])
      const data = tree.filter(item => this.treeKey[dimension].indexOf(item.id) !== -1)
      let arr = data.filter(item =>  !item.children || !item.children.length)
      data.map(item => arr.push(...getTreeLastChildren(item.children || [], [])))
      return arr.map(item => item.id)
    },
    getTreeColumnSource() {
      const tree = getTreeDataList(this.form.source.y, [])
      return tree.filter(item => this.treeKey.y.indexOf(item.id) !== -1)
    },
    getTreeSource(tree1, tree2) {
      let x, y, source
      if (tree1 && !tree2) {
        this.treeType = 0
        x = this.treeKey.x
        y = this.selected.y
        source = JSON.parse(JSON.stringify(this.form.source.x))
      }
      if (!tree1 && tree2) {
        this.treeType = 1
        x = this.selected.x
        y = this.getTreeLastChildren('y')
        source = []
        this.source = this.getTreeColumnSource()
      }
      if (tree1 && tree2) {
        this.treeType = 2
        x = this.treeKey.x
        y = this.getTreeLastChildren('y')
        source = JSON.parse(JSON.stringify(this.form.source.x))
        this.source = this.getTreeColumnSource()
      }
      return { x, y, source }
    },
    initTree(tree1, tree2) {
      const matrix = this.form.schema.y.field
      const { x, y, source } = this.getTreeSource(tree1, tree2)
      if (!x.length) {
        return false
      }
      if (this.treeType === 0 || this.treeType === 2) {
        let column = []
        let tree = getTreeDataList(source, [])
        tree.map(item => item.path = item.path.split('/').map(p => parseInt(p, 0)))
        this.isLevel = tree.find(item => item.id === x[0]).level || 0
        const isTree = tree.filter(item => x.indexOf(item.id) !== -1)
        const maxLevel = Math.max(...getTreeDataList(isTree, []).map(item => item.level))
        const lastChildren = this.findLastChildren(isTree, [])
        let index = 1
        for (let i = this.isLevel; i <= maxLevel; i++) {
          this.tableCol.push({
            prop: `level-${i}`,
            label: `${this.number[index++]}级`
          })
        }
        this.tableCol.map(col => {
          const level = parseInt(col.prop.replaceAll('level-', ''))
          const data = getTreeDataList(isTree, [])
          this.$set(this.rowspan, col.prop, this.getRowspan(data, level, lastChildren))
        })
        if (matrix) {
          if (this.treeType === 2) {

          } else {
            y.map(item => {
              this.tableCol.push({
                prop: item,
                label: item
              })
            })
          }
          column = [...y]
        } else {
          this.tableCol.push({
            prop: 'count',
            label: '数量'
          })
          column = ['count']
        }
        this.treeRecFun(isTree, {}, column)
      } else {
        this.tableCol.push({
          prop: 'name',
          label: getXAxisName(this.patentField, this.form.schema.x.field, this.form.schema.x.expand)
        })
        x.map(x => {
          let data = {
            name: x
          }
          y.map(y => {
            data[y] = this.getDataCount(x, y, false)
          })
          this.tableData.push(data)
        })
      }
      this.initTreeData()
    },
    initTreeData() {

    },
    getRowspan(tree, level, lastChildren) {
      let arr = []
      let index = 0
      const data = tree.filter(item => item.level === level)
      arr = lastChildren.map(item => { return 1 })
      for (let i = 0; i < data.length; i++) {
        const children = this.findLastChildren(data[i].children || [], [])
        arr[index] = children.length
        if (arr[index]) {
          for (let j = index + 1; j < (arr[index] + index); j++) {
            arr[j] = 0
          }
          index += children.length
        } else {
          arr[index++] = 1
        }
      }
      return arr
    },
    findLastChildren(treeList, arr) {
      for (let i = 0; i < treeList.length; i++) {
        if (treeList[i].children && treeList[i].children.length) {
          this.findLastChildren(treeList[i].children, arr)
        } else {
          arr.push(treeList[i])
        }
      }
      return arr
    },
    treeRecFun(treeData, data, column) {
      treeData.forEach(tree => {
        let key = `level-${tree.level}`
        data[key] = tree.name
        if (tree.children && tree.children.length) {
          this.treeRecFun(tree.children, data, column)
        } else {
          let c = {}
          column.map(item => {
            c[item] = this.getDataCount(tree.id, item === 'count' ? undefined : item, false)
          })
          this.tableData.push({ ...data, ...c })
          data[key] = null
        }
      })
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (!this.showIndex) {
        const key = `level-${columnIndex + this.isLevel}`
        const rowspan = this.rowspan[key]
        if (rowspan !== undefined) {
          return { rowspan: rowspan[rowIndex], colspan: rowspan[rowIndex] ? 1 : 0 }
        } else {
          return { rowspan: 1, colspan: 1 }
        }
      }
    },
    initData() {
      const matrix = this.form.schema.y.field
      if (matrix) {
        this.tableCol.push({
          prop: 'name',
          label: getXAxisName(this.patentField, this.form.schema.x.field, this.form.schema.x.expand)
        })
        this.selected.y.map(y => {
          this.tableCol.push({
            prop: y,
            label: y
          })
        })
        this.selected.x.map(x => {
          let data = {
            name: x
          }
          this.selected.y.map(y => {
            data[y] = this.getDataCount(x, y)
          })
          this.tableData.push(data)
        })
      } else {
        this.tableCol.push({
          prop: 'name',
          label: getXAxisName(this.patentField, this.form.schema.x.field, this.form.schema.x.expand)
        }, {
          prop: 'count',
          label: '数量'
        })
        for (let x of this.selected.x) {
          this.tableData.push({
            name: x,
            count: this.getDataCount(x)
          })
        }
      }
    },
  }
}
</script>
