<script setup lang="ts">
import { ref, onMounted, CSSProperties } from 'vue'
import Pagination from './components/Pagination.vue'
import { useTable } from '@/hooks/useTable'
import { ElTable, TableProps } from 'element-plus'
import { ColumnProps } from './interface/index'

interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
  columns: ColumnProps[] // 列配置项
  requestApi: (params: any) => Promise<any> // 请求表格数据的api ==> 必传
  dataCallback?: (data: any) => any // 返回数据的回调函数，可以对数据进行处理 ==> 非必传
  title?: string // 表格标题，目前只在打印的时候用到 ==> 非必传
  pagination?: boolean // 是否需要分页组件 ==> 非必传（默认为true）
  layout?: string
  initParam?: any // 初始化请求参数 ==> 非必传（默认为{}）
  border?: boolean // 是否带有纵向边框 ==> 非必传（默认为true）
  toolButton?: boolean // 是否显示表格功能按钮 ==> 非必传（默认为true）
  selectId?: string // 当表格数据多选时，所指定的 id ==> 非必传（默认为 id）
  displayHeader?: boolean // 是否隐藏头部
  rowClick?: (row: any, column: any, event: any) => void // 点击行
  selectionChange?: (row: any) => void // 选择函数
  selectable?: (row: any) => void // 选择函数
  getRowKey?: ((row: any) => string) | string // 用于优化select勾选框
  tableRowClassName?: (data: any) => CSSProperties
}

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<ProTableProps>(), {
  columns: () => [],
  pagination: true,
  layout: 'total, sizes, prev, pager, next, jumper',
  initParam: {},
  border: false,
  toolButton: true,
  selectId: 'id',
  searchCol: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 })
})

const multipleTableRef = ref()
const clearSelection = () => multipleTableRef.value?.clearSelection()
const toggleRowSelection = () => multipleTableRef.value?.toggleRowSelection()
// 表格操作 Hooks
const { tableData, pageable, loading, getTableList, searchTable, handleSizeChange, handleCurrentChange } = useTable(
  props.requestApi,
  props.initParam,
  props.pagination,
  props.dataCallback
)
// 接收 columns 并设置为响应式
const tableColumns = ref<ColumnProps[]>(props.columns)
onMounted(() => {
  getTableList()
})

defineExpose({
  getTableList,
  searchTable,
  clearSelection,
  toggleRowSelection,
})
</script>

<template>
  <div class="table-header" :style="{ display: displayHeader ? 'none' : '' }">
    <slot name="table-header" :pageable="pageable"></slot>
  </div>

  <div class="card table">
    <el-table ref="multipleTableRef"
      v-loading="loading"
      :data="tableData"
      @row-click="props.rowClick"
      @selection-change="props.selectionChange"
      :border="border"
      :row-key="props.getRowKey"
      :row-style="tableRowClassName"
    >
      <!-- 默认插槽 -->
      <slot></slot>
      <template v-for="item in tableColumns" :key="item">
        <!-- selection || index -->
		  <el-table-column
			  v-bind="item"
			  :align="item.align ?? 'center'"
			  :reserve-selection="item.type == 'selection'"
			  v-if="item.type == 'selection'"
			  :selectable="props.selectable"
			  show-overflow-tooltip
		  ></el-table-column>
		  <el-table-column
			  v-bind="item"
			  :align="item.align ?? 'center'"
			  v-if="item.type == 'index'"
			  show-overflow-tooltip
		  ></el-table-column>
        <!-- expand 支持 tsx 语法 && 作用域插槽 (tsx > slot) -->
        <el-table-column v-bind="item" :align="item.align ?? 'center'" v-if="item.type === 'expand'" v-slot="scope" show-overflow-tooltip>
          <component :is="item.render" :row="scope.row" v-if="item.render"> </component>
          <slot :name="item.type" :row="scope.row" v-else></slot>
        </el-table-column>
        <!-- 普通渲染 -->
        <el-table-column
          v-bind="item"
          :align="item.align ?? 'center'"
          v-if="!item.type && item.prop && item.name !== item.prop"
          v-slot="scope" show-overflow-tooltip
        >
          <div v-if="item.prop=='T_wait_audit'" style="color: red;">
            {{ scope.row[item.prop]==true?'待审核':'' }}
          </div>
          <el-tooltip v-if="item.ellipsis" effect="dark" :content="scope.row[item.prop]" placement="bottom">
            {{ scope.row[item.prop] }}
          </el-tooltip>
          <slot v-if="item.fixed" :name="item.fixed" :row="scope.row"></slot>
        </el-table-column>
        <!-- 自定义slot -->
        <el-table-column
          v-bind="item"
          :align="item.align ?? 'center'"
          v-if="!item.type && item.prop && item.name === item.prop"
          v-slot="scope" show-overflow-tooltip
        >
          <slot :name="item.prop" :row="scope.row"></slot>
        </el-table-column>
      </template>
      <!-- 插入表格最后一行之后的插槽 -->
      <template #append>
        <slot name="append"> </slot>
      </template>
      <!-- 表格无数据情况 -->
      <template #empty>
        <el-empty></el-empty>
      </template>
    </el-table>
    <!-- 分页组件 -->
    <slot name="pagination">
      <Pagination
        v-if="pagination"
        :layout="layout"
        :pageable="pageable"
        :handleSizeChange="handleSizeChange"
        :handleCurrentChange="handleCurrentChange"
      />
    </slot>
  </div>
</template>

<style scoped lang="scss">
@import './index.scss';
:deep(.el-table--enable-row-hover .el-table__body tr) {
  transition: all 0.5s ease-in-out;
}
:deep(.el-table--enable-row-hover .el-table__body tr:hover) {
  box-shadow: 0 0 6px #dfdfdf;
  transform: translateX(-2px);
}
</style>
