<template>
  <div class="table-container">
    <div class="table-toolbar" v-if="showColumnSetting">
      <!-- 气泡确认框 -->
      <el-popover
        v-model:visible="columnSettingVisible"
        placement="bottom-end"
        :width="320"
        trigger="click"
      >
        <template #reference> 
            <el-button :icon="Setting" circle  /> 
        </template>

        <div class="column-setting-content">
          <!-- 操作栏 -->
          <div class="setting-header">
            <span class="setting-title">列设置</span>
            <el-button type="primary" size="small" text @click="handleReset">
              重置
            </el-button>
          </div>

          <!-- 拖拽列表 -->
          <div class="column-list">
            <draggable
              :list="localColumns"
              item-key="prop"
              handle=".drag-handle"
              :animation="200"
              ghost-class="ghost"
              @end="handleDragEnd"
            >
              <template #item="{ element }">
                <div class="column-item">
                  <el-icon class="drag-handle"><Rank /></el-icon>
                  <el-checkbox
                    v-model="element.visible"
                    :disabled="element.fixed"
                    @change="handleVisibleChange"
                  >
                    {{ element.label }}
                  </el-checkbox>
                </div>
              </template>
            </draggable>
          </div>
        </div>
      </el-popover>
    </div>
    <el-table
      ref="tableRef"
      style="width: 100%; flex: 1"
      :data="enableClientFilter ? filteredTableData : tableData"
      :row-key="rowKey"
      :tree-props="treeProps"
      :border="border"
      :highlight-current-row="highlightCurrentRow"
      v-loading="loading"
      v-bind="$attrs"
      @row-click="handleRowClick"
      @row-contextmenu="handleRowContextmenu"
      @selection-change="handleSelectionChange"
      @current-change="handleCurrentChange"
    >
      <!-- 勾选列/单选列 -->
      <el-table-column v-if="showSelection && !singleSelect" type="selection" width="55" align="center" />
      <el-table-column v-if="showSelection && singleSelect" width="55" align="center" label="">
        <template #default="{ row }">
          <el-radio v-model="selectedRadioRow" :label="getRowKeyValue(row)" @change="handleRadioChange(row)">&nbsp;</el-radio>
        </template>
      </el-table-column>

      <!-- 动态表头列 -->
      <template v-for="(column, index) in finalColumns" :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 && column.prop"
          :prop="column.prop"
          :label="column.label"
          :width="column.width"
          :align="column.align || 'left'"
          :sortable="column.sortable"
          :column-key="column.prop"
        >
          <template #header>
            <div class="table-header-cell">
              <div class="table-header-label">
                <span>{{ column.label }}</span>
                <template v-if="column.filters && column.filters.length > 0">
                  <el-dropdown
                    trigger="click"
                    @command="(command: any) => handleFilterCommand(command, column)"
                  >
                    <span class="filter-trigger">
                      <el-icon :class="{ 'is-active': filterStates[column.prop!]?.length }">
                        <Filter />
                      </el-icon>
                    </span>
                    <template #dropdown>
                      <el-dropdown-menu>
                        <el-dropdown-item
                          v-for="item in column.filters"
                          :key="item.value"
                          :command="item.value"
                          :divided="filterStates[column.prop!]?.includes(item.value)"
                        >
                          {{ item.text }}
                        </el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </template>
              </div>
              <el-input
                v-if="column.filterable"
                v-model="filterStates[column.prop!]"
                size="small"
                :placeholder="column.filterPlaceholder || '筛选'"
                clearable
                @change="handleFilterInput(column)"
                @clear="handleFilterClear(column)"
                class="header-filter-input"
              />
            </div>
          </template>
          <template v-if="column.isNumber" #default="{ row }">
            <span class="cell-content">{{ formatDecimalTruncate(row[column.prop]) }}</span>
            <el-icon v-if="column.copy" class="copy-icon" @click.stop="handleCopy(row[column.prop])"><DocumentCopy /></el-icon>
          </template>
          <template v-else-if="column.options" #default="{ row }">
            <span class="cell-content">{{ getOptionLabel(column.options, row[column.prop]) }}</span>
            <el-icon v-if="column.copy" class="copy-icon" @click.stop="handleCopy(row[column.prop])"><DocumentCopy /></el-icon>
          </template>
          <template v-else #default="{ row }">
            <span class="cell-content">{{ row[column.prop] }}</span>
            <el-icon v-if="column.copy" class="copy-icon" @click.stop="handleCopy(row[column.prop])"><DocumentCopy /></el-icon>
          </template>
        </el-table-column>

        <!-- 具名插槽列 -->
        <el-table-column
          v-else
          :label="column.label"
          :width="column.width"
          :align="column.align || 'left'"
          :fixed="column.fixed"
        >
          <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, computed, onMounted, reactive } from 'vue'
import { Setting, Rank, Filter, DocumentCopy } from '@element-plus/icons-vue'
import draggable from 'vuedraggable'
import type { TableInstance } from 'element-plus'
import { ElMessage } from 'element-plus'
import { formatDecimalTruncate } from '@/utils/formatDecimal'
import { useRoute } from 'vue-router'
import { useUserStore } from '@/stores/modules/user'

// 筛选状态管理
const filterStates = reactive<Record<string, any>>({})

// 根据选项配置获取标签
const getOptionLabel = (options: { label: string; value: string | number }[], value: any): string => {
  if (value === null || value === undefined) return ''
  const option = options.find((opt) => opt.value === value)
  return option?.label || String(value)
}

// 定义表格列配置接口
interface TableColumn {
  prop?: string
  type?: string
  label: string
  width?: string | number
  align?: 'left' | 'center' | 'right'
  slotName?: string
  sortable?: boolean
  isNumber?: boolean
  options?: { label: string; value: string | number }[]
  visible?: boolean
  fixed?: boolean | 'left' | 'right'
  sortOrder?: number
  // 表头筛选器相关属性
  filters?: { text: string; value: any }[]
  filterMethod?: (value: any, row: any, column: any) => boolean
  filterable?: boolean
  filterPlaceholder?: string
  // 复制功能
  copy?: boolean
}

// 定义表格组件属性接口
interface Props {
  tableData: any[]
  rowKey?: string
  treeProps?: {
    children: string
  }
  columns?: TableColumn[]
  border?: boolean
  highlightCurrentRow?: boolean
  loading?: boolean
  showSelection?: boolean
  singleSelect?: boolean // 单选模式
  showColumnSetting?: boolean
  columnSettingStorageKey?: string
  enableClientFilter?: boolean // 是否启用客户端筛选
}

const props = withDefaults(defineProps<Props>(), {
  border: true,
  highlightCurrentRow: true,
  loading: false,
  showSelection: false,
  singleSelect: false,
  showColumnSetting: true, // 默认开启列设置
  columnSettingStorageKey: '',
  enableClientFilter: true, // 默认开启客户端筛选
})

// 单选模式相关
const selectedRadioRow = ref<any>(null)

// 获取行标识的safe版本
const getRowKeyValue = (row: any) => {
  return props.rowKey ? row[props.rowKey] : row.id
}

const handleRadioChange = (row: any) => {
  selectedRadioRow.value = getRowKeyValue(row)
  emit('selection-change', [row])
}

// 获取过滤后的数据
const filteredTableData = computed(() => {
  if (!props.enableClientFilter || Object.keys(filterStates).length === 0) {
    return props.tableData
  }
  
  return props.tableData.filter((row) => {
    for (const prop in filterStates) {
      const filterValue = filterStates[prop]
      if (Array.isArray(filterValue) && filterValue.length > 0) {
        if (!filterValue.includes(row[prop])) {
          return false
        }
      } else if (filterValue && typeof filterValue === 'string') {
        const cellValue = String(row[prop] || '').toLowerCase()
        if (!cellValue.includes(filterValue.toLowerCase())) {
          return false
        }
      }
    }
    return true
  })
})

// 定义组件抛出的事件
const emit = defineEmits<{
  (e: 'row-click', row: any): void
  (e: 'row-contextmenu', row: any, column: any, event: MouseEvent): void
  (e: 'selection-change', rows: any[]): void
  (e: 'current-change', row: any): void
  (e: 'filter-change', filters: { [key: string]: any }): void
}>()

const route = useRoute()
const userStore = useUserStore()

// 缓存 key 版本号（当列配置结构升级时可手动改这个值，使旧缓存失效）
const CACHE_VERSION = 'v1'

// 生成缓存 key
const getCacheKey = () => {
  const baseKey = props.columnSettingStorageKey
    || String((route.name as string) || route.path || 'default')
  const userId = String((userStore.userInfo as any)?.id || 'guest')
  return `table-column-setting-${CACHE_VERSION}-${baseKey}-${userId}`
}

// 获取列的唯一标识（用于匹配缓存中的列）
const getColumnKey = (col: TableColumn): string => {
  if (col.prop) return `prop:${col.prop}`
  if (col.slotName) return `slot:${col.slotName}`
  if (col.type) return `type:${col.type}`
  return `label:${col.label}`
}

// 气泡确认框显示状态
const columnSettingVisible = ref(false)

// 本地列配置副本
const localColumns = ref<TableColumn[]>([])

// 计算最终使用的列配置
const finalColumns = computed(() => {
  // 当 showColumnSetting 开启时，始终使用 localColumns
  if (props.showColumnSetting && localColumns.value.length > 0) {
    return localColumns.value.filter((col) => col.visible !== false)
  }
  return props.columns || []
})

// 初始化列配置（从缓存或默认值）
// 逻辑：原始 props.columns 为准，缓存只控制“可见性”和“顺序”。
// - 原始列中与缓存匹配的项 → 应用缓存的 visible / sortOrder
// - 原始列中新增的项 → 追加到末尾，visible 默认 true
// - 缓存中存在但原始列已删除的项 → 丢弃
const initColumns = () => {
  if (!props.columns || props.columns.length === 0) {
    localColumns.value = []
    return
  }

  // 读取缓存（可能为空）
  const cacheKey = getCacheKey()
  let cachedConfig: any[] = []
  const cached = localStorage.getItem(cacheKey)
  if (cached) {
    try {
      const parsed = JSON.parse(cached)
      if (Array.isArray(parsed)) cachedConfig = parsed
    } catch {
      cachedConfig = []
    }
  }

  // 构建缓存映射：key -> { visible, sortOrder }
  const cachedMap = new Map<string, { visible: boolean; sortOrder: number }>()
  cachedConfig.forEach((c, idx) => {
    cachedMap.set(c.key || getColumnKey(c), {
      visible: c.visible !== false,
      sortOrder: typeof c.sortOrder === 'number' ? c.sortOrder : idx,
    })
  })

  // 以原始列为主，命中缓存则用缓存的 visible / sortOrder，否则追加到末尾
  const maxOrder = Math.max(-1, ...Array.from(cachedMap.values()).map((v) => v.sortOrder))
  let nextOrder = maxOrder + 1

  localColumns.value = props.columns.map((col) => {
    const hit = cachedMap.get(getColumnKey(col))
    if (hit) {
      return { ...col, visible: hit.visible, sortOrder: hit.sortOrder }
    }
    return { ...col, visible: col.visible !== false, sortOrder: nextOrder++ }
  })

  // 按 sortOrder 排序
  localColumns.value.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0))
}

// 保存配置到 localStorage（仅缓存 key / visible / sortOrder）
const saveToStorage = () => {
  const config = localColumns.value.map((col, index) => ({
    key: getColumnKey(col),
    visible: col.visible !== false,
    sortOrder: index,
  }))
  localStorage.setItem(getCacheKey(), JSON.stringify(config))
}

// 处理可见性变化
const handleVisibleChange = () => {
  saveToStorage()
}

// 处理拖拽结束
const handleDragEnd = () => {
  saveToStorage()
}

// 重置为默认配置
const handleReset = () => {
  localColumns.value = (props.columns || []).map((col) => ({
    ...col,
    visible: col.visible !== false,
    fixed: col.fixed || false,
  }))
  localStorage.removeItem(getCacheKey())
  columnSettingVisible.value = false
}

// 监听 columns 变化
// 注意：当原始 columns 变化时（如父组件新增/删除了列配置），
// 需要重新合并缓存，否则新字段不会展示。
let lastColumnsKey = ''
watch(
  () => props.columns,
  (newColumns) => {
    if (!newColumns || newColumns.length === 0) return
    // 通过长度+关键字段生成 key，避免不必要的重新初始化
    const newKey = newColumns.map((c) => getColumnKey(c)).join('|')
    if (newKey === lastColumnsKey && localColumns.value.length > 0) return
    lastColumnsKey = newKey
    initColumns()
  },
  { immediate: true, deep: true }
)

// 组件挂载时，如果列还没初始化，再次尝试
onMounted(() => {
  if (props.columns && props.columns.length > 0 && localColumns.value.length === 0) {
    initColumns()
  }
})

const tableRef = ref<TableInstance>()

// 维护当前选中行状态
const selectedRow = ref<any>(null)

// 处理勾选变化
const handleSelectionChange = (rows: any[]) => {
  emit('selection-change', rows)
}

// 处理当前行变化
const handleCurrentChange = (row: any) => {
  if (row === null || row === undefined) return
  emit('current-change', row)
}

// 处理行点击事件
const handleRowClick = (row: any) => {
  if (!row) return
  if (selectedRow.value && selectedRow.value === row) {
    selectedRow.value = null
    tableRef.value?.setCurrentRow(null)
  } else {
    selectedRow.value = row
    tableRef.value?.setCurrentRow(row)
  }
  emit('row-click', selectedRow.value)
}

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

// 监听 tableData 变化（清除单选/行选中状态）
watch(
  () => props.tableData,
  () => {
    if (props.singleSelect) {
      selectedRadioRow.value = null
    }
    selectedRow.value = null
    tableRef.value?.setCurrentRow(null)
  },
  { deep: true }
)

// 处理下拉筛选命令
const handleFilterCommand = (command: any, column: TableColumn) => {
  const prop = column.prop!
  if (!filterStates[prop]) {
    filterStates[prop] = []
  }
  
  const index = filterStates[prop].indexOf(command)
  if (index > -1) {
    filterStates[prop].splice(index, 1)
  } else {
    filterStates[prop].push(command)
  }
  
  emit('filter-change', { ...filterStates })
}

// 处理输入筛选
const handleFilterInput = (column: TableColumn) => {
  emit('filter-change', { ...filterStates })
}

// 处理清除筛选
const handleFilterClear = (column: TableColumn) => {
  filterStates[column.prop!] = ''
  emit('filter-change', { ...filterStates })
}

// 复制文本
const handleCopy = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text)
    ElMessage.success('复制成功')
  } catch (error) {
    console.error('复制失败', error)
  }
}

// 暴露方法
defineExpose({
  clearCurrentRow: () => {
    selectedRow.value = null
    tableRef.value?.setCurrentRow(null)
  },
  setCurrentRow: (row: any) => {
    tableRef.value?.setCurrentRow(row)
  },
})
</script>

<style scoped lang="scss">
.table-container {
  width: 100%;
  height: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .table-toolbar {
    display: flex;
    justify-content: flex-end;
    padding: 8px 0;

    :deep(.el-button) {
      font-size: 18px;
    }
  }

  :deep(.el-table) {
    flex: 1;
    overflow: auto;
  }
}

::v-deep(.cell) {
  display: flex;
  justify-content: center;
  align-items: center;
}
.column-setting-content {
  .setting-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid #ebeef5;

    .setting-title {
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }
  }

  .column-list {
    max-height: 360px;
    overflow-y: auto;

    .column-item {
      display: flex;
      align-items: center;
      padding: 8px;
      margin-bottom: 4px;
      background: #f5f7fa;
      border-radius: 4px;
      transition: background-color 0.2s;

      &:hover {
        background: #ebeef5;
      }

      .drag-handle {
        margin-right: 10px;
        cursor: move;
        color: #909399;
        font-size: 14px;

        &:hover {
          color: #409eff;
        }
      }

      :deep(.el-checkbox) {
        flex: 1;
        font-size: 13px;
      }
    }

    .ghost {
      opacity: 0.5;
      background: #c6e2ff;
    }
  }
}

// 表头单元格样式
.table-header-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  
  .table-header-label {
    display: flex;
    align-items: center;
    gap: 4px;
  }
  
  .filter-trigger {
    display: flex;
    align-items: center;
    cursor: pointer;
    padding: 2px;
    border-radius: 4px;
    transition: all 0.2s;
    
    &:hover {
      background: #f5f7fa;
    }
    
    .el-icon {
      font-size: 14px;
      color: #909399;
      
      &.is-active {
        color: #409eff;
      }
    }
  }
  
  .header-filter-input {
    width: 100%;
    // max-width: 140px;

    :deep(.el-input__wrapper) {
      padding: 0 8px;
      font-size: 12px;
      height: 26px;
    }

    :deep(.el-input__inner) {
      height: 24px;
      line-height: 24px;
    }
  }
}

// 复制图标样式
.copy-icon {
  margin-left: 4px;
  cursor: pointer;
  color: #909399;
  font-size: 14px;

  &:hover {
    color: #409eff;
  }
}

.cell-content {
  // 可选：让文字和图标在同一行
}
</style>
