<template>
  <div>
    <ElTable
      ref="tableRef"
      style="width: 100%"
      :span-method="spanMethod"
      :data="localData"
      :size="size"
      :width="width"
      :height="height"
      :max-height="maxHeight"
      :fit="fit"
      :stripe="stripe"
      :border="border"
      :row-key="rowKey"
      :show-header="showHeader"
      :show-summary="showSummary"
      :sum-text="sumText"
      :summary-method="summaryMethod"
      :row-class-name="rowClassName"
      :row-style="rowStyle"
      :cell-class-name="cellClassName"
      :cell-style="cellStyle"
      :header-row-class-name="headerRowClassName"
      :header-row-style="headerRowStyle"
      :header-cell-style="headerCellStyle"
      :highlight-current-row="highlightCurrentRow "
      :current-row-key="currentRowKey"
      :empty-text="emptyText"
      :expand-row-keys="expandRowKeys"
      :default-expand-all="defaultExpandAll"
      :default-sort="defaultSort"
      :select-on-indeterminate="selectOnIndeterminate"
      :indent="indent"
      :tree-props="treeProps"
      :lazy="lazy"
      :load="load"
      :class-name="className"
      :style="tableStyle"
      :table-layout="tableLayout"
      :flexible="flexible"
      @sort-change="_column => $emit('sort-change', _column)"
      @cell-click="(row, column, cell, event) => $emit('cell-click', row, column, cell, event)"
      @row-click="handleRowClick"
      @row-dblclick="handleRowDoubleClick"
      @row-contextmenu="handleRowContextmenu"
      @current-change="handleCurrentChange"
      @header-dragend="headerDragend"
      @selection-change="handleSelectionChange"
    >
      <template v-if="showSelection">
        <el-table-column
          type="selection"
          width="55"
          :reserve-selection="reserveSelection"
          :selectable="selectable"
        />
      </template>
      <template v-if="showIndex">
        <el-table-column
          label="序号"
          type="index"
          width="50"
        />
      </template>
      <el-table-column
        v-for="(col, index) in localCols"
        :key="index"
        :reserve-selection="reserveSelection"
        :align="col.align || 'center'"
        :prop="col.prop"
        :label="col.label"
        :width="col.width"
        :min-width="col.minWidth"
        :sortable="col.sortable"
        :show-overflow-tooltip="col.showOverflowTooltip"
        :formatter="col.formatter"
        :fixed="col.fixed"
        :column-key="String(index)"
        :selectable="selectable"
      >
        <template v-if="col.customRender" #default="{ row, column, $index }">
          <slot :name="col.customRender" :row="row" :column="column" :$index="$index" />
        </template>
        <template #header="scope">
          <div class="thead-cell">
            {{ scope.column.label }}
          </div>
        </template>
      </el-table-column>
      <slot name="default" />
    </ElTable>
    <pagination
      v-show="localPagination.total>0"
      :total="localPagination.total"
      :page.sync="localPagination.pageNum"
      :limit.sync="localPagination.pageSize"
      :layout="layout"
      @pagination="$emit('pagination-change')"
    />
  </div>
</template>

<script>
export default {
  name: 'JTable',
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    data: {
      type: Array,
      default: () => []
    },
    size: {
      type: String,
      default: 'medium'
    },
    width: [String, Number],
    height: [String, Number],
    maxHeight: [String, Number],
    fit: {
      type: Boolean,
      default: true // 默认自动撑开
    },
    stripe: {
      type: Boolean,
      default: false
    },
    border: {
      type: Boolean,
      default: false
    },
    rowKey: [String, Function],
    selectable: [Function],
    reserveSelection: {
      type: Boolean,
      default: () => false // 默认刷新数据后不保留 type=selection的数据
    },
    showHeader: {
      type: Boolean,
      default: true
    },
    showSummary: Boolean,
    showSelection: {
      type: Boolean,
      default: () => true
    },
    showIndex: {
      type: Boolean,
      default: () => true
    },
    sumText: String,
    summaryMethod: Function,
    highlightCurrentRow: {
      type: Boolean,
      default: true
    },
    currentRowKey: [String, Number],
    emptyText: String,
    rowClassName: { type: [String, Object] },
    rowStyle: { type: [String, Object] },
    cellClassName: { type: [String, Object, Function] },
    cellStyle: { type: [String, Object, Function] },
    headerRowClassName: { type: [String, Object] },
    headerRowStyle: {
      type: [String, Object],
      default: () => ({
        backgroundColor: '#f5f7fa'
      })
    },
    // headerCellClassName: { type: [String, Object] },
    headerCellStyle: {
      type: [String, Object],
      default: () => ({
        backgroundColor: '#f5f7fa'
      })
    },
    expandRowKeys: Array,
    defaultExpandAll: Boolean,
    defaultSort: { type: Object },
    selectOnIndeterminate: Boolean,
    indent: Number,
    treeProps: Object,
    lazy: Boolean,
    load: Function,
    className: { type: String, default: 'full-width' },
    tableStyle: { type: Object },
    tableLayout: String,
    flexible: Boolean,
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },
    pagination: {
      type: Object,
      default: () => {
        return {
          total: 0,
          pageNum: 0,
          pageSize: 10
        }
      }
    },
    spanMethod: [Function]
  },
  data() {
    return {
      currentRow: null,
      localCols: this.renderCol()
    }
  },
  computed: {
    localData() {
      return this.data
    },
    localPagination: {
      get() {
        return this.pagination
      },
      set(val) {
        this.$emit('update:pagination', val)
      }
    }
  },
  methods: {
    renderCol() {
      return this.columns && this.columns.length > 0
        ? (this.columns.map((d, index) => {
          const col = d
          col.index = col.index || index
          col.showOverflowTooltip = col.showOverflowTooltip !== false
          return col
        }).sort((a, b) => a.index - b.index))
        : []
    },
    resetCol() {
      this.localCols = this.renderCol()
      this.$refs.tableRef.doLayout()
      this.$forceUpdate()
    },
    onScrollLeft() {
      this.$refs.tableRef.bodyWrapper.scrollLeft = 0
    },
    handleRowClick(row, column, e) {
      if (this.selectable && typeof this.selectable === 'function') {
        if (this.selectable()) this.$refs.tableRef.toggleRowSelection(row)
      } else {
        this.$refs.tableRef.toggleRowSelection(row)
      }
      if (this.rowKey && this.treeProps && JSON.stringify(this.treeProps) !== '{}') this.$refs.tableRef.toggleRowExpansion(row)
      this.$emit('row-click', row, column, e)
    },
    handleRowDoubleClick(row, column, e) {
      this.currentRow = row
      this.$emit('row-dblclick', row, column, e)
    },
    handleRowContextmenu(row, column, e) {
      this.$emit('row-contextmenu', row, column, e)
    },
    handleCurrentChange(row, oldRow) {
      this.$emit('current-change', row, oldRow)
    },
    handleSelectionChange(selection) {
      if (selection && selection.length > 0) {
        this.$refs.tableRef.setCurrentRow(selection[selection.length - 1])
      } else {
        this.$refs.tableRef.setCurrentRow()
      }
      this.$emit('selection-change', selection)
    },
    headerDragend(newWidth, oldWidth, column) {
      this.localCols.forEach((it) => {
        if (it.prop === column.property && newWidth !== oldWidth) {
          it.width = newWidth
        }
      })
    },
    onToggleRowExpansion(list, expand) {
      list.forEach(item => {
        this.$refs.tableRef.toggleRowExpansion(item, expand)
        const children = item[this.treeProps.children]
        if (children && children.length > 0) this.onToggleRowExpansion(children, expand)
      })
    }
  }
}
</script>

<style scoped lang="scss">

</style>
