<template>
  <div
    v-loading="loading"
    element-loading-text="拼命加载中"
    element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0.8)"
    class="table-wrapper"
  >
    <el-table
      ref="table"
      v-el-table-infinite-scroll="load"
      :data="dealedTableData"
      :header-cell-class-name="headerCellClass"
      :span-method="tableSpanMethod"
      :tree-props="treeProps"
      :row-key="rowKeyTree"
      :show-summary="showSummary"
      :summary-method="getSummaries"
      height="100%"
      stripe
      fit
      border
    >
      <el-table-column
        v-for="col in filteredTableCols"
        :key="col.columnName"
        :prop="col.columnName"
        :label="col.columnLabel"
        :width="col.width"
        :show-overflow-tooltip="showOverflowTooltip"
      >
        <template #header>
          <el-tooltip
            :content="col.columnDescribe || col.columnLabel"
            placement="top"
          >
            <TableHeaderCell
              :label="col.columnLabel"
              :filter-options="tableDataFilters[col.columnName]"
              :filter-values.sync="filterValues[col.columnName]"
              filter-style="arrow"
              :sortable="!!col.needSort"
              :sort-rule.sync="tableDataSortRules[col.columnName]"
            />
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import TableHeaderCell from '../TableHeaderCell'
import { setTableFilters } from '@/utils/table'
import { Query } from '@/api/dataIntegration'

export default {
  name: 'SimpleTable',
  components: { TableHeaderCell },
  props: {
    queryId: {
      type: [String, Number],
      required: true
    },
    queryString: {
      type: String,
      default: ''
    },
    // 是否显示树形表格
    isTree: {
      type: Boolean,
      default: false
    },
    // 树形props
    treeProps: {
      type: Object,
      default: function () {
        return { children: 'children', hasChildren: 'hasChildren' }
      }
    },
    // 树形标识id
    rowKeyTree: {
      type: String,
      default: 'companyID'
    },
    // 是否显示合计行
    showSummary: {
      type: Boolean,
      default: false
    },
    // 不换行，溢出隐藏
    showOverflowTooltip: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      page: 0,
      noMore: false,
      tableCols: [], // 表头数据
      tableData: [], // 表格数据
      tableDataFilters: {}, // 表头-下拉数据
      filterValues: {}, // 表头-下拉-选中数据
      tableDataSortRules: {}, // 表头-排序
      tableGroups: [], // 表格分组规则
      spanArr: [] // 表格分组数据缓存
    }
  },
  computed: {
    filteredTableCols() {
      return this.tableCols.filter(col => col.needShow)
    },
    dealedTableData() {
      const filtered = this.tableData.filter(item => {
        let flag = true
        Object.entries(this.filterValues).forEach(([key, arr]) => {
          if (arr.length && !arr.includes(item[key])) {
            flag = false
          }
        })
        return flag
      })
      const sortRules = Object.entries(this.tableDataSortRules).reduce(
        (pre, [key, value]) => {
          if (value) {
            pre[0].push(key)
            value = value === 'ascending' ? 'asc' : 'desc'
            pre[1].push(value)
          }
          return pre
        },
        [[], []]
      )
      return this._.orderBy(filtered, sortRules[0], sortRules[1])
    }
  },
  watch: {
    queryString: {
      handler() {
        this.resetTable()
        this.queryTableData()
      },
      immediate: true
    },
    dealedTableData: {
      handler(arr) {
        const spanArr = []
        let pos = 0
        arr.forEach((item, index, arr) => {
          if (index === 0) {
            spanArr.push(1)
          } else {
            if (this.tableGroups.every(prop => arr[index][prop] === arr[index - 1][prop])) {
              spanArr[pos] += 1
              spanArr.push(0)
            } else {
              spanArr.push(1)
              pos = index
            }
          }
        })
        this.spanArr = spanArr
      },
      deep: true
    }
  },
  updated() {
    this.$refs['table']?.doLayout()
  },
  methods: {
    load() {
      if (!this.isTree) {
        if (this.noMore || this.loading) {
          return
        }
        this.queryTableData()
      }
    },
    resetTable() {
      this.page = 0
      this.noMore = false
      this.tableData = []
    },
    initTableData() {
      this.tableDataFilters = {}
      this.filteredTableCols.forEach(col => {
        this.tableDataFilters[col.columnName] = []
        if (col.needGroup) {
          this.tableGroups.push(col.columnName)
        }
      })
      setTableFilters(this.tableData, this.tableDataFilters)
    },
    // 给表头单元格加上 ascending 或 descending 使用 element 自带的排序箭头变色
    headerCellClass({ row, column, rowIndex, columnIndex }) {
      const classes = []
      const rule = this.tableDataSortRules[column.property]
      if (rule) {
        classes.push(rule)
      }
      return classes.join(' ')
    },
    // 分组
    tableSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (this.tableGroups.includes(column.property)) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 合计
    getSummaries(param) {
      const { columns, data } = param
      const sums = []
      columns.forEach((column, index) => {
        this.tableColsCopy.forEach(p => {
          if (column.property === p.columnName && p.needCount) {
            const values = data.map(item => Number(item[column.property]))
            if (!values.every(value => isNaN(value))) {
              sums[index] = values.reduce((prev, curr) => {
                const value = Number(curr)
                if (!isNaN(value)) {
                  return prev + curr
                } else {
                  return prev
                }
              }, 0)
              sums[index] += ''
            }
          }
        })
      })
      return sums
    },
    async queryTableData() {
      this.loading = true
      try {
        const {
          code,
          returnData: { columnSet, listValues }
        } = await Query({
          id: this.queryId,
          needPage: ++this.page,
          dataContent: this.queryString ? { whereString: this.queryString } : []
        })
        if (Number(code) === 0) {
          if (listValues.length === 0) {
            this.page--
            this.noMore = true
          }
          this.tableCols = columnSet
          this.$emit('get-column-set', columnSet)
          this.tableData.push(...listValues)
          this.initTableData()
        } else {
          this.page--
          this.$message.error('获取表格数据失败')
        }
      } catch (error) {
        console.log('出错了', error.message || error)
      }
      this.loading = false
    }
  }
}
</script>

<style lang="scss" scoped>
.table-wrapper {
  width: 100%;
  height: 100%;
  ::v-deep .el-table {
    width: 100%;
    .cell {
      padding: 0;
      text-align: center;
      font-size: 14px;
      font-family: Helvetica, 'Microsoft YaHei';
      letter-spacing: 0;
    }
    .el-table__header-wrapper {
      .cell {
        font-weight: bold;
        color: #101116;
        > .el-checkbox {
          display: none;
        }
      }
    }
  }
}
</style>
