<template>
  <div class="table-view">
    <ElTable
      ref="tableRef"
      :data="paginatedData"
      border
      :stripe="stripe"
      header-align="center"
      height="100%"
      v-bind="attrs"
    >
      <ElTableColumn
        v-if="selectionable"
        type="selection"
        width="50"
        fixed="left"
        header-align="center"
        align="center"
      ></ElTableColumn>
      <ElTableColumn
        v-if="serialNumberable"
        label="序号"
        type="index"
        width="60"
        fixed="left"
        header-align="center"
        align="center"
      ></ElTableColumn>
      <template v-for="column in columns" :key="column.key">
        <ElTableColumn
          v-if="column.type === 'expand'"
          v-bind="column"
          header-align="center"
        >
          <!-- 当type等于expand时， 配置通过h函数渲染、txs语法或者插槽自定义内容 -->
          <template #default="scope">
            <div>
              <component
                :is="column.render"
                v-if="column.render"
                :row="scope.row"
                :index="scope.$index"
              />
              <slot
                v-else-if="column.slot"
                name="expand"
                :row="scope.row"
                :index="scope.$index"
              ></slot>
            </div>
          </template>
        </ElTableColumn>
        <RenderColumn v-else :col="column">
          <template v-for="(_, name) of slots" #[name]="scope">
            <slot :name="name" v-bind="scope" />
          </template>
        </RenderColumn>
      </template>
    </ElTable>
  </div>
</template>
<script setup lang="tsx" generic="T">
import { type Slot, useAttrs, useSlots, type PropType, shallowRef } from 'vue'
import type { CustomColumn } from '@/types/table'
import RenderColumn from './RenderColumn.vue'
import { ElTable } from 'element-plus'
import type { TableInstance } from 'element-plus'

const tableRef = shallowRef<TableInstance>()

// eslint-disable-next-line @typescript-eslint/no-explicit-any
defineProps({
  paginatedData: {
    type: Array,
    required: true,
  },
  columns: {
    type: Array as PropType<CustomColumn<T>>,
    required: true,
  },
  stripe: {
    type: Boolean,
    default: false,
  },
  serialNumberable: {
    type: Boolean,
    default: false,
  },
  selectionable: {
    type: Boolean,
    default: false,
  },
})

const attrs = useAttrs()
const slots = useSlots() as Record<string, Slot>

const setCurrentRow = (row: T) => {
  tableRef.value?.setCurrentRow(row)
}

const toggleRowSelection = (row: T, selected: boolean = true) => {
  tableRef.value?.toggleRowSelection(row, selected)
}

const clearSelection = () => {
  tableRef.value?.clearSelection()
}
const toggleAllSelection = () => {
  tableRef.value?.toggleAllSelection()
}

defineExpose({
  tableRef,
  setCurrentRow,
  toggleRowSelection,
  clearSelection,
  toggleAllSelection,
})
</script>

<style lang="scss" scoped>
.table-view {
  height: 100%;
  overflow: hidden;
  position: relative;
}
</style>
