<template>
  <section class="th-table">
    <!-- 表格 -->
    <el-table
      ref="table"
      v-loading="loading"
      :data="data"
      :tree-props="treeProps"
      v-bind="tableProps"
      @select="handleSelect"
      @selection-change="handleSelectionChange"
      @select-all="handleSelectAll"
      v-on="$listeners"
    >
      <!--选择列-->
      <el-table-column
        v-if="showSelection && selectionIndex === 0"
        type="selection"
        align="center"
        :width="selectionWidth"
        :selectable="row => !row.disabled"
        v-bind="selectionProps"
      />
      <!--序号列-->
      <el-table-column
        v-if="showIndex"
        type="index"
        align="center"
        :label="indexLabel"
        :width="indexWidth"
        :index="indexMethod"
        v-bind="indexProps"
      />
      <!--选择列-->
      <el-table-column
        v-if="showSelection && selectionIndex === 1"
        type="selection"
        align="center"
        :width="selectionWidth"
        :selectable="row => !row.disabled"
        v-bind="selectionProps"
      />
      <!-- 数据列 -->
      <template v-for="column in showColumns">
        <el-table-column
          v-if="column.component === 'children'"
          :key="column.prop"
          v-bind="{ align: 'center', ...column }"
        >
          <template v-for="item in column.children || []">
            <el-table-column
              v-if="item.component === 'children'"
              :key="item.prop"
              v-bind="{ align: 'center', ...item }"
            >
              <template v-for="obj in item.children || []">
                <th-table-column :key="obj.prop" :column="obj">
                  <template :slot="obj.prop" slot-scope="scope">
                    <slot :name="obj.prop" :row="scope.row" :column="obj" />
                  </template>
                </th-table-column>
              </template>
            </el-table-column>
            <th-table-column v-else :key="item.prop" :column="item">
              <template :slot="item.prop" slot-scope="scope">
                <slot :name="item.prop" :row="scope.row" :column="item" />
              </template>
            </th-table-column>
          </template>
        </el-table-column>
        <th-table-column v-else :key="column.prop" :column="column">
          <template :slot="column.prop" slot-scope="scope">
            <slot :name="column.prop" :row="scope.row" :column="column" />
          </template>
        </th-table-column>
      </template>
      <!-- 操作列 -->
      <el-table-column
        v-if="$length(handleColumn)"
        v-bind="{
          align: 'center',
          ...handleColumnProps
        }"
      >
        <!-- 操作列内容 -->
        <template slot-scope="scope">
          <template v-for="(item, index) in handleColumn">
            <el-button
              v-if="!scope.row[`hidden${item.key}`]"
              :key="index"
              type="primary"
              size="mini"
              :disabled="disabledHandle(scope.row, item)"
              v-bind="item.props"
              @click="handleEvent(scope.row, item)"
            >
              {{ item.name }}
            </el-button>
          </template>
        </template>
      </el-table-column>
      <!-- append -->
      <template slot="append">
        <slot name="append" />
      </template>
    </el-table>
    <th-pagination
      v-if="showPagination"
      :page="pageNo"
      :page-size="pageSize"
      :total="totalCount"
      v-bind="pageProps"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    >
      <slot name="pagination" />
    </th-pagination>
  </section>
</template>

<script>
import ThTableColumn from './column'

export default {
  name: 'ThTable',
  components: {
    ThTableColumn
  },
  props: {
    // 是否加载状态
    loading: {
      type: Boolean,
      default: false
    },
    // 是否允许表头过滤
    showHeaderFilter: {
      type: Boolean,
      default: false
    },
    // 是否显示分页
    showPagination: {
      type: Boolean,
      default: true
    },
    // 是否显示选择框
    showSelection: {
      type: Boolean,
      default: false
    },
    // 选择栏宽度
    selectionWidth: {
      type: String,
      default: '50'
    },
    // 选择栏属性
    selectionProps: {
      type: Object,
      default: () => ({})
    },
    // 是否显示序号列
    showIndex: {
      type: Boolean,
      default: false
    },
    // 序号列宽度
    indexWidth: {
      type: String,
      default: '50'
    },
    // 序号列列名
    indexLabel: {
      type: String,
      default: '序号'
    },
    // 序号列属性
    indexProps: {
      type: Object,
      default: () => ({})
    },
    // 选择列序号
    selectionIndex: {
      type: Number,
      default: 1
    },
    // 数据
    data: {
      type: Array,
      default: () => []
    },
    // 选择项
    selectedKeys: {
      type: Array,
      default: () => []
    },
    // 表头
    columns: {
      type: Array,
      default: () => []
    },
    // 操作列选项
    handleColumnProps: {
      type: Object,
      default: () => ({
        // fixed: 'right',
        // label: '操作',
        // width: '112',
        // icon: 'shezhi',
        // labelClassName: '',
        // className: ''
      })
    },
    // 操作列内容
    handleColumn: {
      type: Array,
      default: () => [
        // {
        //   key: 'Delete',
        //   name: '删除',
        //   icon: 'delete',
        //   disabled: !this._checkPermission('/admin/area', 'DELETE'),
        //   isDisabled (row, item) { return false }
        // }
      ]
    },
    // 当前页
    pageNo: {
      type: Number,
      default: 1
    },
    // 每页数
    pageSize: {
      type: Number,
      default: 20
    },
    // 总页数
    totalCount: {
      type: Number,
      default: 0
    },
    // 分页属性
    pageProps: {
      type: Object,
      default: () => ({})
    },
    // 表格属性
    props: {
      type: Object,
      default: () => ({})
    },
    // 表格树属性
    treeProps: {
      type: Object,
      default: () => ({
        children: 'children',
        hasChildren: 'hasChildren'
      })
    }
  },
  data() {
    return {
      showColumnsKeys: this.columns.filter(d => !d.isHidden).map(d => d.prop),
      showColumns: this.columns.filter(d => !d.isHidden)
    }
  },
  computed: {
    tableProps() {
      return {
        rowKey: 'id',
        defaultExpandAll: true,
        rowClassName: 'th-table-row',
        cellClassName: 'th-table-cell',
        headerRowClassName: 'th-table-row__header',
        headerCellClassName: 'th-table-cell__header',
        tooltipEffect: 'light',
        height: this.showPagination ? 'calc(100% - 34px)' : '100%',
        ...this.props
      }
    }
  },
  watch: {
    columns: {
      handler(newVal) {
        if (Array.isArray(newVal)) {
          this.showColumnsKeys = newVal.filter(d => !d.isHidden).map(d => d.prop)
          this.showColumns = newVal.filter(d => !d.isHidden)
        }
      },
      immediate: true
    }
  },
  methods: {
    // 勾选表格事件
    handleSelectionChange(val) {
      this.$emit('handleSelectionChange', val)
    },
    // 勾选父节点，联动子节点
    handleSelect(selection, row) {
      const that = this
      const rowKey = this.tableProps.rowKey || 'id'
      const children = this.treeProps.children || 'children'
      const selected = selection.map(d => d[rowKey]).includes(row[rowKey])
      const loop = function(data) {
        if (data instanceof Array && data.length) {
          data.forEach(r => {
            that.$refs.table.toggleRowSelection(r, selected)
            if (r[children]) loop(r[children])
          })
        }
      }
      if (row[children]) {
        loop(row[children])
      }
      this.$emit('handleSelect', selected, row)
    },
    // 全选
    handleSelectAll(val) {
      const selected = this.$length(val) > 0
      const that = this
      const children = this.treeProps.children || 'children'
      const loop = function(data) {
        if (that.$length(data)) {
          data.forEach(r => {
            if (r.disabled) {
              that.$refs.table.toggleRowSelection(r, false)
            } else {
              that.$refs.table.toggleRowSelection(r, selected)
            }
            if (r[children]) loop(r[children])
          })
        }
      }
      loop(val)
      this.$emit('handleSelectAll', selected)
    },
    // 切换页数
    handleSizeChange(val) {
      this.$emit('handleSizeChange', val)
    },
    // 切换当前页
    handleCurrentChange(val) {
      this.$emit('handleCurrentChange', val)
    },
    // 操作按钮点击事件
    handleEvent(row, item) {
      this.$emit(`handle${item.key}`, row, item)
    },
    // 操作按钮禁用事件
    disabledHandle(row, item) {
      return item.disabled || (item.isDisabled instanceof Function ? item.isDisabled(row, item) : false)
    },
    // 输入框事件
    inputEvent(evt, index, prop) {
      this.$emit('inputEvent', evt, index, prop)
    },
    // 排序方法
    indexMethod(index) {
      return this.pageSize * (this.pageNo - 1) + index + 1
    }
  }
}
</script>
