<template>
  <div class="table-column-control">
    <el-button
      :type="triggerType"
      :icon="Setting"
      :size="triggerSize"
      :circle="triggerCircle"
      :link="triggerLink"
      @click="visible = true"
    >
      <slot name="trigger">
        {{ triggerText || '列设置' }}
      </slot>
    </el-button>
    
    <el-dialog
      v-model="visible"
      title="列显示设置"
      :width="dialogWidth"
      append-to-body
    >
      <div class="column-control-content">
        <div class="column-control-header">
          <div class="header-actions">
            <el-button
              type="primary"
              link             
              @click="handleToggleSelectAll"
            >
              {{ isAllSelected ? '取消全选' : '全选' }}
            </el-button>
          </div>
        </div>
        
        <div class="column-control-body">
          <el-checkbox-group v-model="checkedColumns" @change="handleColumnChange" class="column-checkbox-group">
            <div
              v-for="column in actualColumns"
              :key="column.prop || column.label"
              class="column-item"
            >
              <el-checkbox
                :label="column.prop || column.label"
                :disabled="!!column.fixed || column.alwaysShow"
              >
                {{ column.label }}
              </el-checkbox>
              <el-tag v-if="column.fixed !== undefined" size="small" type="info">
                {{ column.fixed === 'left' ? '固定左侧' : column.fixed === 'right' ? '固定右侧' : '固定' }}
              </el-tag>
            </div>
          </el-checkbox-group>
        </div>
      </div>
      
      <template #footer>
        <div class="column-control-footer">
          <el-button @click="handleReset">重置</el-button>
          <el-button type="primary" @click="handleConfirm">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick, type Ref } from 'vue'
import { Setting } from '@element-plus/icons-vue'
import type { TableInstance } from 'element-plus'
import { useTableColumns, type ColumnConfig } from '/@/composables/useTableColumns'

interface Column {
  prop?: string
  label: string
  fixed?: boolean | 'left' | 'right'
  alwaysShow?: boolean // 始终显示的列，不可隐藏
  [key: string]: any
}

interface Props {
  columns?: Column[] // 手动配置的列（可选，如果提供了 tableRef 则自动提取）
  tableRef?: Ref<TableInstance | undefined> // el-table 的 ref，用于自动提取列配置
  modelValue?: string[] // 当前显示的列
  storageKey?: string // localStorage 存储的 key，用于持久化
  triggerType?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'
  triggerSize?: 'large' | 'default' | 'small'
  triggerCircle?: boolean
  triggerText?: string
  triggerLink?: boolean
  dialogWidth?: string // 对话框宽度
  // 自动提取时的配置选项
  autoExtractOptions?: {
    defaultHidden?: string[]
    alwaysShow?: string[]
    columnMap?: Record<string, Partial<ColumnConfig>>
  }
}

const props = withDefaults(defineProps<Props>(), {
  triggerType: 'default',
  triggerSize: 'default',
  triggerCircle: false,
  triggerText: '',
  triggerLink: false,
  dialogWidth: '600px'
})

const emit = defineEmits<{
  'update:modelValue': [value: string[]]
  'change': [value: string[]]
}>()

const visible = ref(false)
const checkedColumns = ref<string[]>([])

// 如果提供了 tableRef，使用自动提取；否则使用手动配置的 columns
const tableColumnsResult = props.tableRef
  ? useTableColumns(props.tableRef, props.storageKey, props.autoExtractOptions)
  : { 
      columns: computed(() => []), 
      visibleColumns: computed(() => []), 
      updateVisibleColumns: () => {}, 
      refreshColumns: () => {}, 
      isColumnVisible: () => true 
    }

const { 
  columns: autoColumns, 
  visibleColumns: autoVisibleColumns, 
  updateVisibleColumns: updateAutoVisibleColumns, 
  refreshColumns: refreshAutoColumns, 
  isColumnVisible: autoIsColumnVisible 
} = tableColumnsResult

// 实际使用的列配置
const actualColumns = computed(() => {
  const result = props.tableRef && autoColumns.value.length > 0
    ? autoColumns.value
    : props.columns || []
  return result
})

// 获取所有列（包括固定列和 alwaysShow 列）
const getAllColumns = (): string[] => {
  return actualColumns.value.map(col => col.prop || col.label)
}

// 初始化选中的列
const initCheckedColumns = () => {
  if (props.modelValue && props.modelValue.length > 0) {
    checkedColumns.value = [...props.modelValue]
  } else if (props.tableRef && autoVisibleColumns.value.length > 0) {
    // 使用自动提取的可见列，但需要确保包含所有列（包括固定列）
    // 合并已保存的可见列和固定列/alwaysShow列
    const fixedAndAlwaysShow = actualColumns.value
      .filter(col => col.alwaysShow || !!col.fixed)
      .map(col => col.prop || col.label)
    checkedColumns.value = [...new Set([...autoVisibleColumns.value, ...fixedAndAlwaysShow])]
  } else if (props.storageKey) {
    // 从 localStorage 读取
    const saved = localStorage.getItem(props.storageKey)
    if (saved) {
      try {
        const savedColumns = JSON.parse(saved)
        // 确保固定列和 alwaysShow 列始终在选中列表中
        const fixedAndAlwaysShow = actualColumns.value
          .filter(col => col.alwaysShow || !!col.fixed)
          .map(col => col.prop || col.label)
        checkedColumns.value = [...new Set([...savedColumns, ...fixedAndAlwaysShow])]
      } catch (e) {
        // 如果解析失败，使用默认值（所有列）
        checkedColumns.value = getAllColumns()
      }
    } else {
      checkedColumns.value = getAllColumns()
    }
  } else {
    checkedColumns.value = getAllColumns()
  }
}

// 监听 actualColumns 变化，更新选中状态
watch(actualColumns, (newColumns) => {
  if (newColumns.length > 0 && checkedColumns.value.length === 0) {
    // 如果列数据已加载但选中列表为空，初始化选中所有列
    initCheckedColumns()
  } else if (newColumns.length > 0) {
    // 确保固定列和 alwaysShow 列始终在选中列表中
    const fixedAndAlwaysShow = newColumns
      .filter(col => col.alwaysShow || !!col.fixed)
      .map(col => col.prop || col.label)
    const currentChecked = checkedColumns.value
    const missingFixed = fixedAndAlwaysShow.filter(col => !currentChecked.includes(col))
    if (missingFixed.length > 0) {
      checkedColumns.value = [...currentChecked, ...missingFixed]
    }
  }
}, { deep: true })

// 监听弹窗打开，触发列配置重新提取
watch(visible, (newVal) => {
  console.log('[TableColumnControl] 弹窗状态变化:', newVal)
  if (newVal) {
    // 弹窗打开时，确保选中状态正确初始化
    if (actualColumns.value.length > 0) {
      initCheckedColumns()
    }
  }
  if (newVal && props.tableRef) {
    console.log('[TableColumnControl] 弹窗打开，tableRef 存在:', props.tableRef)
    console.log('[TableColumnControl] tableRef.value:', props.tableRef.value)
    console.log('[TableColumnControl] tableRef.value 类型:', typeof props.tableRef.value)
    
    // 尝试多种方式获取表格实例
    const getTableInstance = (): TableInstance | null => {
      // 方法1: 直接从 props.tableRef.value 获取
      if (props.tableRef?.value) {
        console.log('[TableColumnControl] 从 props.tableRef.value 获取表格实例')
        return props.tableRef.value
      }
      
      // 方法2: 尝试从 props.tableRef 本身获取（可能是直接的 ref 对象）
      if ((props.tableRef as any).value) {
        console.log('[TableColumnControl] 从 props.tableRef 的 value 属性获取表格实例')
        return (props.tableRef as any).value
      }
      
      // 方法3: 如果 props.tableRef 本身就是表格实例（不应该发生，但作为备用）
      if ((props.tableRef as any).$el) {
        console.log('[TableColumnControl] props.tableRef 本身就是表格实例')
        return props.tableRef as any
      }
      
      return null
    }
    
    // 如果 tableRef.value 已经有值，直接提取
    const tableInstance = getTableInstance()
    if (tableInstance) {
      const tableEl = (tableInstance as any).$el
      if (tableEl) {
        console.log('[TableColumnControl] 表格实例已就绪，立即提取列配置')
        nextTick(() => {
          refreshAutoColumns()
          console.log('[TableColumnControl] 刷新后列数:', actualColumns.value.length)
        })
        return
      }
    }
    
    // 等待 tableRef.value 有值后再提取
    let waitCount = 0
    const maxWaitCount = 50 // 最多等待 5 秒（50 * 100ms）
    let waitTimer: ReturnType<typeof setTimeout> | null = null
    
    const waitForTableRef = () => {
      // 尝试获取表格实例
      const tableInstance = getTableInstance()
      if (tableInstance) {
        const tableEl = (tableInstance as any).$el
        if (tableEl) {
          console.log('[TableColumnControl] 表格实例已就绪，开始提取列配置')
          nextTick(() => {
            refreshAutoColumns()
            console.log('[TableColumnControl] 刷新后列数:', actualColumns.value.length)
            
            // 如果还是没有数据，多次重试
            let retryCount = 0
            const maxRetries = 10
            const retryInterval = setInterval(() => {
              retryCount++
              console.log(`[TableColumnControl] 第 ${retryCount} 次重试刷新列配置`)
              refreshAutoColumns()
              console.log(`[TableColumnControl] 重试后列数:`, actualColumns.value.length)
              if (actualColumns.value.length > 0 || retryCount >= maxRetries) {
                console.log('[TableColumnControl] 停止重试，最终列数:', actualColumns.value.length)
                clearInterval(retryInterval)
              }
            }, 200)
          })
          return // 成功获取，退出
        }
      }
      
      // 继续等待
      waitCount++
      if (waitCount < maxWaitCount) {
        console.log(`[TableColumnControl] tableRef.value 还未就绪，等待中... (${waitCount}/${maxWaitCount})`)
        waitTimer = setTimeout(waitForTableRef, 100)
      } else {
        console.warn('[TableColumnControl] 等待超时，tableRef.value 仍未就绪')
        console.warn('[TableColumnControl] props.tableRef:', props.tableRef)
        console.warn('[TableColumnControl] props.tableRef?.value:', props.tableRef?.value)
        // 即使超时，也尝试提取一次（可能表格已经渲染了，只是 ref 没有正确绑定）
        console.log('[TableColumnControl] 尝试强制提取列配置')
        refreshAutoColumns()
        console.log('[TableColumnControl] 强制提取后列数:', actualColumns.value.length)
      }
    }
    
    // 延迟一下，确保表格已渲染
    setTimeout(() => {
      waitForTableRef()
    }, 300)
    
    // 清理函数：弹窗关闭时清除等待定时器
    return () => {
      if (waitTimer) {
        clearTimeout(waitTimer)
        waitTimer = null
      }
    }
  } else {
    console.warn('[TableColumnControl] 弹窗打开但 tableRef 不存在或为空')
  }
})

// 监听 tableRef.value 的变化，当它被赋值时触发列配置提取
if (props.tableRef) {
  // 尝试多种方式监听 tableRef.value 的变化
  watch(() => {
    // 尝试多种方式获取 tableRef.value
    if (props.tableRef?.value) {
      return props.tableRef.value
    }
    if ((props.tableRef as any).value) {
      return (props.tableRef as any).value
    }
    return null
  }, (newVal, oldVal) => {
    if (newVal && newVal !== oldVal) {
      console.log('[TableColumnControl] tableRef.value 已赋值，触发列配置提取')
      // 延迟一下，确保表格完全渲染
      setTimeout(() => {
        nextTick(() => {
          refreshAutoColumns()
          console.log('[TableColumnControl] 列配置提取完成，列数:', actualColumns.value.length)
        })
      }, 200)
    }
  }, { immediate: true }) // 立即检查一次，如果 tableRef.value 已经有值，立即触发
}

// 暴露给父组件使用
defineExpose({
  isColumnVisible: autoIsColumnVisible,
  visibleColumns: autoVisibleColumns,
  refreshColumns: refreshAutoColumns
})

// 获取默认显示的列（所有可隐藏的列）- 用于重置功能
const getDefaultColumns = (): string[] => {
  return actualColumns.value
    .filter(col => !col.alwaysShow && !col.fixed)
    .map(col => col.prop || col.label)
}

// 获取所有可选择的列
const selectableColumns = computed(() => {
  return actualColumns.value
    .filter(col => !col.alwaysShow && !col.fixed)
    .map(col => col.prop || col.label)
})

// 判断是否全选
const isAllSelected = computed(() => {
  const selectable = selectableColumns.value
  if (selectable.length === 0) return false
  return selectable.every(col => checkedColumns.value.includes(col))
})

// 切换全选/全不选
const handleToggleSelectAll = () => {
  if (isAllSelected.value) {
    // 当前全选，执行全不选（但保留固定列和 alwaysShow 列）
    const fixedAndAlwaysShow = actualColumns.value
      .filter(col => col.alwaysShow || !!col.fixed)
      .map(col => col.prop || col.label)
    checkedColumns.value = [...fixedAndAlwaysShow]
  } else {
    // 当前未全选，执行全选（所有列）
    checkedColumns.value = getAllColumns()
  }
}

// 重置为默认值
const handleReset = () => {
  checkedColumns.value = getDefaultColumns()
  handleColumnChange(checkedColumns.value)
}

// 确认
const handleConfirm = () => {
  handleColumnChange(checkedColumns.value)
  visible.value = false
}

// 列变化处理
const handleColumnChange = (value: string[]) => {
  // 确保固定列和 alwaysShow 列始终在选中列表中
  const fixedAndAlwaysShow = actualColumns.value
    .filter(col => col.alwaysShow || !!col.fixed)
    .map(col => col.prop || col.label)
  const finalValue = [...new Set([...value, ...fixedAndAlwaysShow])]
  
  emit('update:modelValue', finalValue)
  emit('change', finalValue)
  
  // 如果使用自动提取，同步更新（只更新可选择的列）
  if (props.tableRef) {
    const selectableValue = finalValue.filter(col => {
      const column = actualColumns.value.find(c => (c.prop || c.label) === col)
      return column && !column.alwaysShow && !column.fixed
    })
    updateAutoVisibleColumns(selectableValue)
  } else {
    // 保存到 localStorage（只保存可选择的列）
    if (props.storageKey) {
      const selectableValue = finalValue.filter(col => {
        const column = actualColumns.value.find(c => (c.prop || c.label) === col)
        return column && !column.alwaysShow && !column.fixed
      })
      localStorage.setItem(props.storageKey, JSON.stringify(selectableValue))
    }
  }
}

// 监听外部 modelValue 变化
watch(() => props.modelValue, (newVal) => {
  if (newVal && newVal.length > 0) {
    checkedColumns.value = [...newVal]
  }
}, { immediate: true })

// 初始化
onMounted(() => {
  initCheckedColumns()
})
</script>

<style lang="scss" scoped>
.table-column-control {
  display: inline-block;
}

.column-control-content {
  .column-control-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid #ebeef5;
    
    .header-title {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
    }
    
    .header-actions {
      display: flex;
      gap: 8px;
    }
  }
  
  .column-control-body {
    max-height: 400px;
    overflow-y: auto;
    margin-bottom: 12px;
    
    .column-checkbox-group {
      display: flex;
      flex-wrap: wrap;
      gap: 12px 16px;
    }
    
    .column-item {
      display: flex;
      align-items: center;
      gap: 6px;
      min-width: 120px;
      
      :deep(.el-checkbox) {
        margin-right: 0;
        
        .el-checkbox__label {
          font-size: 14px;
          color: #606266;
          padding-left: 8px;
        }
      }
    }
  }
  
  .column-control-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding-top: 12px;
    border-top: 1px solid #ebeef5;
  }
}
</style>



