<script setup lang="ts" generic="T extends Record<string, any>">
import { ref, computed, watch } from 'vue'
import { ElMessageBox } from 'element-plus'
import type { TableInstance } from 'element-plus'
import { useRouter } from 'vue-router'

/**
 * 通用列表页组件
 * 封装原 renderTablePage 的能力：标题、搜索、创建按钮、多选、批量删除、操作列
 */
const props = withDefaults(
  defineProps<{
    title: string
    data: T[]
    loading?: boolean
    /** 是否显示搜索框 */
    searchable?: boolean
    /** 搜索字段（默认取数据第一列） */
    searchFields?: string[]
    /** 是否支持多选 */
    multiSelect?: boolean
    /** 创建按钮文本，不传则不显示 */
    createText?: string
    /** 创建按钮跳转路径 */
    createTo?: string
    /** 删除函数（用于批量删除），返回 boolean 表示成功 */
    deleteFn?: (row: any) => Promise<any>
    /** 行 key 字段名 */
    rowKey?: string
    /** 空数据提示 */
    emptyText?: string
    /** 默认每页条数 */
    pageSize?: number
    /** 可选每页条数 */
    pageSizes?: number[]
  }>(),
  {
    loading: false,
    searchable: false,
    multiSelect: false,
    rowKey: 'id',
    emptyText: '暂无数据',
    pageSize: 10,
    pageSizes: () => [10, 20, 50, 100],
  },
)

const emit = defineEmits<{
  create: []
  refresh: []
}>()

const router = useRouter()
const tableRef = ref<TableInstance>()
const selectedIds = ref<Set<string | number>>(new Set())
const keyword = ref('')
const currentPage = ref(1)
const currentPageSize = ref(props.pageSize)

/** 行唯一标识取值 */
function rowId(row: T): string | number {
  return row[props.rowKey] ?? row['name'] ?? row['id']
}

/** 过滤后的数据 */
const filteredData = computed(() => {
  if (!keyword.value.trim() || !props.searchFields?.length) return props.data
  const kw = keyword.value.toLowerCase().trim()
  return props.data.filter((row) =>
    props.searchFields!.some((f) => String(row[f] ?? '').toLowerCase().includes(kw)),
  )
})

/** 当前页数据 */
const pagedData = computed(() => {
  const start = (currentPage.value - 1) * currentPageSize.value
  return filteredData.value.slice(start, start + currentPageSize.value)
})

/** 处理多选变化 */
function handleSelectionChange(rows: T[]) {
  selectedIds.value = new Set(rows.map(rowId))
}

/** 单个删除（子组件或操作列调用） */
async function handleDelete(row: any, confirmText = '确定要删除这条记录吗？') {
  if (!props.deleteFn) return
  try {
    await ElMessageBox.confirm(confirmText, '确认删除', {
      type: 'warning',
      confirmButtonText: '确定',
      cancelButtonText: '取消',
    })
    await props.deleteFn(row)
    emit('refresh')
  } catch {
    // 用户取消或删除失败
  }
}

/** 批量删除 */
async function handleBatchDelete() {
  if (selectedIds.value.size === 0 || !props.deleteFn) return
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedIds.value.size} 条记录吗？`,
      '批量删除',
      { type: 'warning' },
    )
    const rows = props.data.filter((row) => selectedIds.value.has(rowId(row)))
    let ok = 0
    let fail = 0
    for (const row of rows) {
      try {
        await props.deleteFn(row)
        ok++
      } catch {
        fail++
      }
    }
    selectedIds.value.clear()
    emit('refresh')
    if (fail === 0) {
      ElMessageBox.alert(`成功删除 ${ok} 条记录`, '成功', { type: 'success' })
    } else {
      ElMessageBox.alert(`成功 ${ok} 条，失败 ${fail} 条`, '部分失败', { type: 'warning' })
    }
  } catch {
    // 取消
  }
}

function clearSelection() {
  selectedIds.value.clear()
  tableRef.value?.clearSelection()
}

function handleCreate() {
  if (props.createTo) {
    router.push(props.createTo)
  } else {
    emit('create')
  }
}

// 数据变化时清空选中
watch(
  () => props.data,
  () => {
    selectedIds.value.clear()
    currentPage.value = 1
    tableRef.value?.clearSelection()
  },
)

watch(
  () => keyword.value,
  () => {
    currentPage.value = 1
  },
)

defineExpose({ handleDelete, clearSelection })
</script>

<template>
  <div class="data-table-page">
    <el-card shadow="never" class="table-card">
      <!-- 工具栏 -->
      <div class="table-toolbar">
        <slot name="title">
          <h2 class="table-title">{{ title }}</h2>
        </slot>
        <div class="toolbar-actions">
          <el-input
            v-if="searchable"
            v-model="keyword"
            :placeholder="`搜索${title}...`"
            clearable
            class="search-input"
          >
            <template #prefix><i class="fa fa-search" /></template>
          </el-input>
          <el-button v-if="createText" type="primary" @click="handleCreate">
            <i class="fa fa-plus" style="margin-right: 4px" />
            {{ createText }}
          </el-button>
          <slot name="toolbar-extra" />
        </div>
      </div>

      <!-- 批量操作栏 -->
      <transition name="el-zoom-in-top">
        <div v-if="multiSelect && selectedIds.size > 0" class="batch-bar">
          <span class="batch-info">
            已选择 <strong>{{ selectedIds.size }}</strong> 项
            <el-button link type="primary" @click="clearSelection">取消选择</el-button>
          </span>
          <el-button type="danger" size="small" @click="handleBatchDelete">
            <i class="fa fa-trash" style="margin-right: 4px" />
            批量删除 ({{ selectedIds.size }})
          </el-button>
        </div>
      </transition>

      <!-- 表格 -->
      <div class="table-body">
        <el-table
          ref="tableRef"
          :data="pagedData"
          v-loading="loading"
          :row-key="rowKey as any"
          height="100%"
          style="width: 100%"
          :empty-text="emptyText"
          @selection-change="handleSelectionChange"
        >
          <el-table-column
            v-if="multiSelect"
            type="selection"
            width="50"
            align="center"
            reserve-selection
            fixed="left"
          />
          <slot name="columns" />
          <el-table-column
            v-if="$slots.actions"
            label="操作"
            align="center"
            width="220"
            fixed="right"
          >
            <template #default="{ row }">
              <slot name="actions" :row="row" :handleDelete="handleDelete" />
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="table-pagination">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="currentPageSize"
          background
          layout="total, sizes, prev, pager, next, jumper"
          :page-sizes="pageSizes"
          :total="filteredData.length"
        />
      </div>
    </el-card>
  </div>
</template>

<style scoped lang="scss">
.data-table-page {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  min-height: 0;
  
  .table-card {
    margin-bottom: 0;
    width: 100%;
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
  }

  .table-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    padding: 0 12px;
    flex-wrap: wrap;
    gap: 12px;
  }

  .table-title {
    font-size: 18px;
    font-weight: 600;
    color: #1e293b;
    margin: 0;
    letter-spacing: -0.3px;
  }

  .toolbar-actions {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .search-input {
    width: 280px;
    :deep(.el-input__wrapper) {
      border-radius: 8px;
      box-shadow: 0 0 0 1px #e2e8f0 inset;
      transition: all 0.2s;
      
      &.is-focus {
        box-shadow: 0 0 0 1px var(--primary-color) inset;
      }
    }
  }

  .batch-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: rgba(79, 70, 229, 0.05);
    border: 1px solid rgba(79, 70, 229, 0.1);
    border-radius: 8px;
    padding: 10px 16px;
    margin: 0 24px 16px;

    .batch-info {
      font-size: 13px;
      color: var(--primary-color);
      
      strong {
        font-weight: 600;
        margin: 0 4px;
      }
    }
  }

  .table-body {
    flex: 1;
    min-height: 0;
  }

  .table-pagination {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 16px 24px;
    border-top: 1px solid #f1f5f9;

    :deep(.el-pagination) {
      margin-top: 0;
    }
  }

  :deep(.el-card__body) {
    display: flex;
    flex-direction: column;
    padding: 12px 0 0;
    flex: 1;
    min-height: 0;
  }

  :deep(.el-table__inner-wrapper::before) {
    display: none;
  }

  /* 表格单元格统一样式（各列表页共用，与模型调优保持一致） */
  :deep(.el-table td.el-table__cell) {
    padding: 18px 0 !important;
  }

  :deep(.el-table__cell .cell) {
    line-height: 22px;
    white-space: nowrap;
  }

  /* 操作列按钮组统一样式（各列表页共用） */
  :deep(.el-table) .action-buttons {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: 8px;
  }
}
</style>
