<template>
  <div class="table-container">
    <el-table
      ref="tableRef"
      height="100%"
      style="width: 100%"
      :data="tableData"
      :row-key="rowKey"
      :tree-props="treeProps"
      :border="border"
      :highlight-current-row="highlightCurrentRow"
      v-bind="$attrs"
      @row-click="handleRowClick"
      @row-contextmenu="handleRowContextmenu"
    >
      <!-- 动态表头列 -->
      <template v-for="(column, index) in columns" :key="index">
        <el-table-column
          v-if="column.type === 'index'"
          type="index"
          :label="column.label"
          :width="column.width || 60"
          :align="column.align || 'center'"
        />
        <el-table-column
          v-else-if="!column.slotName"
          :prop="column.prop"
          :label="column.label"
          :width="column.width"
          :align="column.align || 'left'"
          :sortable="column.sortable"
        />

        <!-- 具名插槽列 -->
        <el-table-column
          v-else
          :label="column.label"
          :width="column.width"
          :align="column.align || 'left'"
        >
          <template #default="{ row }">
            <slot :name="column.slotName" :row="row" />
          </template>
        </el-table-column>
      </template>
    </el-table>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import type { TableInstance } from 'element-plus'

// 定义表格列配置接口
interface TableColumn {
  prop?: string
  type?: string
  label: string
  width?: string | number
  align?: 'left' | 'center' | 'right'
  slotName?: string // 具名插槽名称
  sortable?: boolean // 是否可排序
}

// 定义表格组件属性接口
interface Props {
  tableData: any[]
  rowKey?: string
  treeProps?: {
    children: string
  }
  columns?: TableColumn[]
  border?: boolean // 是否显示边框
  highlightCurrentRow?: boolean // 是否高亮当前行
}

const props = withDefaults(defineProps<Props>(), {
  border: true,
  highlightCurrentRow: true,
})

// 定义组件抛出的事件
const emit = defineEmits<{
  (e: 'row-click', row: any): void // 保留原有行点击事件
  (e: 'row-contextmenu', row: any, column: any, event: MouseEvent): void
}>()

const tableRef = ref<TableInstance>()

// 维护当前选中行状态，用于二次点击取消选中
const selectedRow = ref<any>(null)

/**
 * 处理行点击事件（支持二次点击取消选中）
 */
const handleRowClick = (row: any) => {
  // 增加空值保护，避免传递 null 给父组件
  if (!row) return

  // 判断是否是二次点击同一行
  if (selectedRow.value && selectedRow.value === row) {
    // 二次点击：取消选中
    selectedRow.value = null
    tableRef.value?.setCurrentRow() // 不传参即清除选中 [^14^]
  } else {
    // 首次点击或点击不同行：选中该行
    selectedRow.value = row
    tableRef.value?.setCurrentRow(row)
  }

  emit('row-click', selectedRow.value)
}

/**
 * 处理行右键菜单事件
 */
const handleRowContextmenu = (row: any, column: any, event: MouseEvent) => {
  console.log('row', row)
  emit('row-contextmenu', row, column, event)
}

// 监听 tableData 变化，数据更新时取消选中
watch(
  () => props.tableData,
  () => {
    // 数据更新时，清除选中状态
    selectedRow.value = null
    tableRef.value?.setCurrentRow() // 不传参即清除选中 [^14^]
  },
  { deep: true }, // 深度监听，防止数组元素变化未触发
)

// 暴露清除当前选中行的方法
defineExpose({
  clearCurrentRow: () => {
    selectedRow.value = null
    tableRef.value?.setCurrentRow()
  },
})
</script>

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