<template>
  <div class="app-table" v-loading="loading">
    <div class="app-table__header">
      <div class="block block--left" v-if="$slots.header">
        <slot name="header"></slot>
      </div>
      <div class="block block--right" v-if="showToolbar">
        <slot name="toolbar">
          <el-button-group>
            <el-button icon="Refresh" @click="refresh" />
            <el-button icon="Setting" @click="showTableSetting = true" />
          </el-button-group>
        </slot>
      </div>
    </div>
    <div class="app-table__container">
      <el-table ref="tableRef" height="100%" :header-cell-class-name="selectionType" v-bind="$attrs"
        :highlight-current-row="highlightCurrentRow" scrollbar-always-on @row-click="onRowClick"
        @expand-change="onRowClick" @select="onSelect" border>
        <!-- 展开行 -->
        <el-table-column type="expand" v-if="$slots.expand">
          <template #default="{ row, $index }">
            <slot name="expand" :row="row" :index="$index"></slot>
          </template>
        </el-table-column>
        <!-- 选择列 -->
        <el-table-column type="selection" width="55" align="center" fixed v-if="selectionType" />
        <!-- 序号 -->
        <el-table-column type="index" label="序号" align="center" :width="80" v-if="showIndex" />
        <!-- 数据列 -->
        <template v-for="(item, index) in columns" :key="index">
          <el-table-column :class-name="item.className" :align="item.align ?? 'center'" :min-width="120"
            :width="item.width" :label="item.label" :prop="item.prop" :fixed="item.fixed || false"
            :sortable="item.sortable" show-overflow-tooltip v-if="item.show ?? true">
            <template #default="{ row, $index }">
              <slot :name="item.prop" :row="row" :value="row[item.prop]" :index="$index">
                {{ handleValue(row, item) }}
              </slot>
            </template>
          </el-table-column>
        </template>
      </el-table>
    </div>
    <div class="app-table__footer">
      <slot name="footer"></slot>
    </div>
    <app-table-setting :columns="columns" @update="updateColumn" @closed="showTableSetting = false"
      v-if="showTableSetting" />
  </div>
</template>

<script lang="ts">
import { defineComponent, shallowRef, PropType } from 'vue'
import { handleNoneValue } from '@/filters'
import AppTableSetting from '../table-setting/index.vue'

export default defineComponent({
  inheritAttrs: false,
  components: {
    AppTableSetting
  },
  emits: ['refresh', 'update:columns', 'rowClick', 'select'],
  props: {
    columns: {
      type: Array as PropType<Model.TableColumn[]>,
      default: () => ([])
    },
    // 是否显示头部工具栏
    showToolbar: Boolean,
    loading: Boolean,
    showIndex: Boolean,
    // 是否要高亮当前行
    highlightCurrentRow: {
      type: Boolean,
      default: true
    },
    // 选择列类型
    selectionType: {
      type: String as PropType<'single' | 'multiple'>,
    }
  },
  setup(props, { emit, expose }) {
    const tableRef = shallowRef()
    const tableRadio = shallowRef()
    const showTableSetting = shallowRef(false)
    const refresh = () => emit('refresh')
    const updateColumn = (value: Model.TableColumn[]) => emit('update:columns', value)

    // 当某一行被勾选时触发的事件
    const onSelect = (selection: unknown[], currentRow: unknown) => {
      const el = tableRef.value
      const rows = selection.filter((e) => {
        if (props.selectionType === 'single') {
          if (e === currentRow) {
            el.setCurrentRow(currentRow) // 高亮行
            return true
          } else {
            el.toggleRowSelection(e, false) // 单选取消其他选中的行
            return false
          }
        }
        return true
      })
      emit('select', rows, currentRow)
    }

    // 当某一行被点击时选中该行
    const onRowClick = (row: unknown) => {
      // if (props.selectionType) {
      //   const el = tableRef.value
      //   const selection = el.getSelectionRows()
      //   const selected = selection.find((e: unknown) => e === row)
      //   el.toggleRowSelection(row, selected ? false : true)
      //   onSelect(el.getSelectionRows(), row)
      // }
      emit('rowClick', row)
    }

    const handleValue = (row: { [key: string]: unknown }, column: Model.TableColumn) => {
      const value = row[column.prop]
      if (Number.isFinite(value) && column.decimal) {
        return Number(value).toFixed(column.decimal)
      }
      return handleNoneValue(value)
    }

    // 暴露组件属性
    expose({
      elTable: tableRef
    })

    return {
      tableRef,
      tableRadio,
      showTableSetting,
      onSelect,
      onRowClick,
      handleValue,
      refresh,
      updateColumn,
    }
  },
})
</script>

<style lang="less">
@import './index.less';
</style>