<template>
  <cacp-dialog
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :resizable="false"
    @closed="onDialogClosed"
  >
    <div class="dynamic-column-dialog">
      <!-- 搜索框 -->
      <div class="column-search" v-if="showSearch">
        <el-input
          v-model="searchText"
          placeholder="搜索列名"
          clearable
          :prefix-icon="Search"
          @keyup.enter="handleSearch"
        />
      </div>

      <!-- 操作按钮 -->
      <div class="column-operations">
        <el-button type="text" @click="selectAll" :disabled="!columns.length">全选</el-button>
        <el-button type="text" @click="clearAll" :disabled="!tempSelectedKeys.length">清空</el-button>
        <el-button type="text" @click="resetToDefault">恢复默认</el-button>
        <el-button type="text" @click="toggleSelectAll" v-if="showToggleAll">
          {{ isAllSelected ? '取消全选' : '全选当前' }}
        </el-button>
      </div>

      <!-- 列选择区域 -->
      <div class="column-select-area">
        <div
            v-for="group in filteredColumnGroups"
            :key="group.key"
            class="column-group"
          >
            <div class="group-header" v-if="group.title && group.columns.length > 0">
              <el-checkbox
                :indeterminate="group.indeterminate"
                :model-value="group.allChecked"
                @change="toggleGroup(group.key, $event)"
              >
                <span class="group-title">{{ group.title }}</span>
<!--                <span class="group-count">({{ group.selectedCount }}/{{ group.columns.length }})</span>-->
              </el-checkbox>
            </div>
            <el-checkbox-group v-model="tempSelectedKeysModel">
              <div class="group-items" v-if="group.columns.length > 0">
                <el-checkbox
                  v-for="column in group.columns"
                  :key="column.key"
                  :label="column.key"
                  :title="column.tooltip || column.label"
                  :disabled="column.disabled"
                >
                  <span class="column-label">{{ column.label }}</span>
  <!--                <span v-if="column.width" class="column-width">({{ column.width }})</span>-->
                  <el-tag v-if="column.defaultVisible" size="small" type="success" class="default-tag">
                    默认
                  </el-tag>
                </el-checkbox>
              </div>
            </el-checkbox-group>
          </div>

        <!-- 无数据提示 -->
        <div v-if="!hasFilteredColumns" class="no-data">
          <el-empty description="未找到匹配的列" :image-size="80" />
        </div>
      </div>

      <!-- 底部统计信息 -->
      <div class="column-statistics">
        已选择 {{ tempSelectedKeys.length }}/{{ columns.length }} 列
      </div>
    </div>

    <!-- 底部按钮 -->
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :disabled="!tempSelectedKeys.length">
          确定
        </el-button>
      </span>
    </template>
  </cacp-dialog>
</template>

<script setup lang="ts">
import { computed, ref, watch, nextTick } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { type CheckboxValueType, ElMessage } from 'element-plus'

export interface ColumnConfig {
  key: string
  label: string
  width?: string | number
  tooltip?: string
  groupKey?: string
  groupTitle?: string
  defaultVisible?: boolean
  property?: string
  sortable?: boolean
  isDict?: boolean
  dictKey?: string
  isDate?: boolean
  formatter?: (value: any) => string
  showOverflowTooltip?: boolean
  disabled?: boolean
}

export interface ColumnGroup {
  key: string
  title?: string
  columns: ColumnConfig[]
  indeterminate: boolean
  allChecked: boolean
  selectedCount: number
}

interface Props {
  modelValue: boolean
  title?: string
  width?: string | number
  columns: ColumnConfig[]
  selectedKeys: string[]
  showSearch?: boolean
  showToggleAll?: boolean
  autoSave?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'update:selectedKeys', keys: string[]): void
  (e: 'confirm', keys: string[]): void
  (e: 'cancel'): void
}

const props = withDefaults(defineProps<Props>(), {
  title: '选择显示的列',
  width: '600px',
  showSearch: true,
  showToggleAll: false,
  autoSave: false
})

const emit = defineEmits<Emits>()

// 搜索文本
const searchText = ref('')

// 临时选中的列键值
const tempSelectedKeys = ref<string[]>([])

// 使用 computed 包装用于 v-model
const tempSelectedKeysModel = computed({
  get: () => tempSelectedKeys.value,
  set: (value: string[]) => {
    tempSelectedKeys.value = value
  }
})

// 对话框显示状态
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 计算是否全选
const isAllSelected = computed(() =>
  tempSelectedKeys.value.length === props.columns.length && props.columns.length > 0
)

// 是否有过滤后的列
const hasFilteredColumns = computed(() => {
  return filteredColumnGroups.value.some(group => group.columns.length > 0)
})

// 分组后的列配置
const columnGroups = computed(() => {
  const groups = new Map<string, ColumnGroup>()

  // 初始化分组
  props.columns.forEach(column => {
    const groupKey = column.groupKey || 'default'
    if (!groups.has(groupKey)) {
      groups.set(groupKey, {
        key: groupKey,
        title: column.groupTitle || '',
        columns: [],
        indeterminate: false,
        allChecked: false,
        selectedCount: 0
      })
    }
    groups.get(groupKey)!.columns.push(column)
  })

  // 计算每个分组的选中状态
  groups.forEach(group => {
    const selectedCount = group.columns.filter(col =>
      tempSelectedKeys.value.includes(col.key)
    ).length

    group.selectedCount = selectedCount
    group.allChecked = selectedCount === group.columns.length
    group.indeterminate = selectedCount > 0 && selectedCount < group.columns.length
  })

  return Array.from(groups.values())
})

// 过滤后的列分组（根据搜索文本）
const filteredColumnGroups = computed(() => {
  if (!searchText.value.trim()) return columnGroups.value

  const searchLower = searchText.value.toLowerCase().trim()

  return columnGroups.value.map(group => ({
    ...group,
    columns: group.columns.filter(column =>
      column.label.toLowerCase().includes(searchLower) ||
      column.key.toLowerCase().includes(searchLower) ||
      (column.tooltip && column.tooltip.toLowerCase().includes(searchLower))
    )
  })).filter(group => group.columns.length > 0)
})

// 初始化临时选中的列
watch(
  () => props.selectedKeys,
  (newVal) => {
    tempSelectedKeys.value = [...newVal]
  },
  { immediate: true }
)

// 监视对话框打开，重置搜索
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal) {
      nextTick(() => {
        searchText.value = ''
      })
    }
  }
)

// 全选
const selectAll = () => {
  tempSelectedKeys.value = props.columns.map(col => col.key)
}

// 清空
const clearAll = () => {
  tempSelectedKeys.value = []
}

// 恢复默认
const resetToDefault = () => {
  const defaultKeys = props.columns
    .filter(col => col.defaultVisible)
    .map(col => col.key)
  tempSelectedKeys.value = defaultKeys
  if (props.autoSave) {
    emit('update:selectedKeys', defaultKeys)
  }
}

// 切换全选/取消全选
const toggleSelectAll = () => {
  if (isAllSelected.value) {
    clearAll()
  } else {
    selectAll()
  }
}

// 切换分组选中状态
const toggleGroup = (groupKey: string, checked: CheckboxValueType) => {
  const group = columnGroups.value.find(g => g.key === groupKey)
  if (!group) return

  const groupColumnKeys = group.columns.map(col => col.key)

  // 将 CheckboxValueType 转换为 boolean
  const isChecked = !!checked

  if (isChecked) {
    // 添加分组中所有列
    const newKeys = [...tempSelectedKeys.value]
    groupColumnKeys.forEach(key => {
      if (!newKeys.includes(key)) {
        newKeys.push(key)
      }
    })
    tempSelectedKeys.value = newKeys
  } else {
    // 移除分组中所有列
    tempSelectedKeys.value = tempSelectedKeys.value.filter(
      key => !groupColumnKeys.includes(key)
    )
  }
}

// 处理搜索
const handleSearch = () => {
  // 搜索逻辑已经在 filteredColumnGroups 中实现
}

// 对话框关闭
const onDialogClosed = () => {
  searchText.value = ''
}

// 取消
const handleCancel = () => {
  // 恢复原始选中状态
  tempSelectedKeys.value = [...props.selectedKeys]
  emit('cancel')
  dialogVisible.value = false
}

// 确认
const handleConfirm = () => {
  if (tempSelectedKeys.value.length === 0) {
    ElMessage.warning('请至少选择一列')
    return
  }

  emit('update:selectedKeys', [...tempSelectedKeys.value])
  emit('confirm', [...tempSelectedKeys.value])
  dialogVisible.value = false
}

// 键盘快捷键
const handleKeydown = (e: KeyboardEvent) => {
  if (e.key === 'Escape') {
    handleCancel()
  } else if (e.key === 'Enter' && e.ctrlKey) {
    handleConfirm()
  }
}

// 添加键盘事件监听
if (typeof window !== 'undefined') {
  window.addEventListener('keydown', handleKeydown)
}
</script>

<style scoped lang="scss">
.dynamic-column-dialog {
  display: flex;
  flex-direction: column;
  //height: 100%;
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 10px;
  .column-search {
    margin-bottom: 16px;

    :deep(.el-input__wrapper) {
      border-radius: 6px;
    }
  }

  .column-operations {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--el-border-color-light);

    .el-button {
      padding: 0;
      height: auto;
      font-size: 14px;

      &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }
    }
  }

  .column-select-area {
    flex: 1;
    overflow-y: auto;
    padding-right: 4px;

    .column-group {
      margin-bottom: 12px;

      &:last-child {
        margin-bottom: 0;
      }

      .group-header {
        margin-bottom: 10px;
        padding: 6px 0;
        background-color: var(--el-fill-color-light);
        border-radius: 6px;

        .el-checkbox {
          width: 100%;
          padding: 0 12px;

          :deep(.el-checkbox__label) {
            display: flex;
            align-items: center;
            justify-content: space-between;
            width: 100%;
          }

          .group-title {
            font-weight: 600;
            color: var(--el-text-color-primary);
          }

          .group-count {
            color: var(--el-text-color-secondary);
            font-size: 12px;
            font-weight: normal;
          }
        }
      }

      .group-items {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        gap: 10px;
        padding: 0 4px;

        .el-checkbox {
          margin: 0;
          padding: 8px 12px;
          border: 1px solid var(--el-border-color-light);
          border-radius: 6px;
          transition: all 0.3s;

          &:hover {
            border-color: var(--el-color-primary);
            background-color: var(--el-color-primary-light-9);
          }

          &:deep(.el-checkbox__label) {
            display: flex;
            align-items: center;
            flex: 1;
            min-width: 0;
          }

          .column-label {
            flex: 1;
            margin-right: 8px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }

          .column-width {
            color: var(--el-text-color-secondary);
            font-size: 12px;
            flex-shrink: 0;
          }

          .default-tag {
            margin-left: 8px;
            flex-shrink: 0;
          }
        }
      }
    }

    .no-data {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 200px;
    }
  }

  .column-statistics {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--el-border-color-light);
    font-size: 14px;
    color: var(--el-text-color-secondary);
    text-align: center;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
