
<template>
  <div class="kb-container">
    <div class="header-section">
      <div class="title-info">
        <h2>知识库管理</h2>
        <p class="subtitle">管理所有知识库和相关内容</p>
      </div>
      <div class="action-buttons">
        <el-select v-model="queryParams.status" placeholder="所有状态" clearable style="width: 120px; margin-right: 12px" @change="handleSearch">
          <el-option label="正常" value="normal" />
          <el-option label="已禁用" value="disabled" />
        </el-select>
        <el-input
          v-model="queryParams.keyword"
          placeholder="搜索知识库名称..."
          style="width: 240px; margin-right: 12px"
          clearable
          @keyup.enter="handleSearch"
          @clear="handleSearch"
        />
        <el-button type="primary" @click="handleSearch">
          <el-icon><Search /></el-icon> 查询
        </el-button>
        <el-button type="primary" @click="handleAdd">
          <el-icon><Plus /></el-icon> 新建知识库
        </el-button>
      </div>
    </div>

    <el-card class="table-card" shadow="never">
      <el-table :data="tableData" v-loading="loading" style="width: 100%" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        
        <el-table-column label="知识库名称" min-width="200">
          <template #default="{ row }">
            <div class="kb-name-cell">
              <el-icon class="kb-icon" :size="24" :style="{ color: getIconColor(row.name) }"><Collection /></el-icon>
              <div class="kb-info">
                <div class="name">{{ row.name }}</div>
                <div class="desc">{{ row.description || '暂无描述' }}</div>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="collection_name" label="知识库表名" min-width="150" />
        
        <el-table-column prop="document_count" label="文档数量" width="100" />

        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)" effect="light" round>{{ getStatusText(row.status) }}</el-tag>
          </template>
        </el-table-column>

        <el-table-column prop="created_by" label="创建人" width="100" />
        
        <el-table-column prop="created_at" label="创建时间" width="160">
            <template #default="{ row }">
                {{ formatTime(row.created_at) }}
            </template>
        </el-table-column>

        <el-table-column prop="updated_by" label="修改人" width="100" />

        <el-table-column prop="updated_at" label="修改时间" width="160">
            <template #default="{ row }">
                {{ formatTime(row.updated_at) }}
            </template>
        </el-table-column>

        <el-table-column label="操作" width="180" fixed="right">
          <template #default="{ row }">
            <el-tooltip content="查看" placement="top">
                <el-button link type="primary" @click="handleView(row)">
                    <el-icon><View /></el-icon>
                </el-button>
            </el-tooltip>
            <el-tooltip content="编辑" placement="top">
                <el-button link type="primary" @click="handleEdit(row)">
                    <el-icon><Edit /></el-icon>
                </el-button>
            </el-tooltip>
            <el-tooltip :content="row.is_synced ? '已同步' : '同步到Milvus'" placement="top">
                <el-button link type="warning" @click="handleSync(row)" :disabled="row.is_synced">
                    <el-icon><Refresh /></el-icon>
                </el-button>
            </el-tooltip>
            <el-tooltip content="删除" placement="top">
                <el-button link type="danger" @click="handleDelete(row)">
                    <el-icon><Delete /></el-icon>
                </el-button>
            </el-tooltip>
            <el-dropdown @command="(cmd) => handleCommand(cmd, row)" trigger="click">
                <el-button link type="info">
                    <el-icon><MoreFilled /></el-icon>
                </el-button>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item command="toggleStatus">
                            {{ row.status === 'disabled' ? '启用' : '禁用' }}
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <div class="pagination-info">
            显示 {{ (pagination.page - 1) * pagination.pageSize + 1 }} 到 
            {{ Math.min(pagination.page * pagination.pageSize, pagination.total) }} 条，
            共 {{ pagination.total }} 条记录
        </div>
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :total="pagination.total"
          :page-sizes="[10, 20, 50, 100]"
          layout="prev, pager, next, sizes"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- Create/Edit Dialog -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'create' ? '新建知识库' : '编辑知识库'"
      width="700px"
      @close="resetForm"
      class="kb-dialog"
    >
      <el-form ref="formRef" :model="formData" :rules="rules" label-width="110px" class="kb-form">
        <div class="form-section">
            <div class="section-title">基本信息</div>
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="知识库名称" prop="name">
                        <el-input v-model="formData.name" placeholder="请输入知识库名称" />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="集合名称" prop="collection_name" v-if="dialogType === 'create'">
                        <el-input v-model="formData.collection_name" placeholder="Milvus集合名(英文)" />
                    </el-form-item>
                    <el-form-item label="集合名称" v-else>
                        <el-input v-model="formData.collection_name" disabled />
                    </el-form-item>
                </el-col>
            </el-row>
            
            <el-form-item label="描述" prop="description">
                <el-input 
                    v-model="formData.description" 
                    type="textarea" 
                    rows="3" 
                    placeholder="请输入关于此知识库的详细描述..." 
                />
            </el-form-item>
            
            <el-row :gutter="20">
                <el-col :span="12" v-if="dialogType === 'create'">
                    <el-form-item label="向量维度" prop="dimension">
                        <el-input-number v-model="formData.dimension" :min="1" :step="1" style="width: 100%" />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="状态" prop="status">
                        <el-radio-group v-model="formData.status">
                            <el-radio-button label="normal">正常</el-radio-button>
                            <el-radio-button label="disabled">禁用</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                </el-col>
            </el-row>
        </div>

        <div class="form-section">
            <div class="section-header">
                <div class="section-title">元数据字段定义</div>
                <div class="section-desc">定义文档的额外属性，用于精确检索过滤</div>
            </div>
            
            <div class="metadata-fields-container">
                <div v-for="(field, index) in formData.metadata_fields" :key="index" class="metadata-field-card">
                    <div class="field-header">
                        <span class="field-index">字段 {{ index + 1 }}</span>
                        <el-button 
                            v-if="formData.metadata_fields.length > 1"
                            type="danger" 
                            link 
                            :icon="Delete"
                            @click="removeMetadataField(index)"
                            size="small"
                        >删除</el-button>
                    </div>
                    <el-row :gutter="15">
                        <el-col :span="6">
                            <el-form-item label-width="0" style="margin-bottom: 12px;">
                                <el-select 
                                    v-model="field.field_zh_name" 
                                    placeholder="中文名称" 
                                    filterable
                                    allow-create
                                    default-first-option
                                    @change="(val) => handleFieldChange(val, index)"
                                >
                                    <el-option 
                                        v-for="opt in availableFields"
                                        :key="opt.value"
                                        :label="opt.label" 
                                        :value="opt.value" 
                                        :disabled="getDisabledOptions(index).includes(opt.value)"
                                    />
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="6">
                            <el-form-item label-width="0" style="margin-bottom: 12px;">
                                <el-input v-model="field.field_en_name" placeholder="英文标识 (如: year)" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="5">
                            <el-form-item label-width="0" style="margin-bottom: 12px;">
                                <el-select v-model="field.field_type" placeholder="类型">
                                    <el-option label="文本" value="text" />
                                    <el-option label="数字" value="num" />
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="7">
                            <el-form-item label-width="0" style="margin-bottom: 12px;">
                                <el-input v-model="field.remark" placeholder="备注说明" />
                            </el-form-item>
                        </el-col>
                    </el-row>
                </div>
                
                <div class="add-field-btn">
                    <el-button type="primary" plain :icon="Plus" @click="addMetadataField" style="width: 100%">添加元数据字段</el-button>
                </div>
            </div>
        </div>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { Search, Plus, Collection, View, Edit, Delete, MoreFilled, Refresh } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { 
    getKnowledgeBases, 
    getKnowledgeBaseMetadata,
    createKnowledgeBase, 
    updateKnowledgeBase, 
    updateKnowledgeBaseStatus, 
    deleteKnowledgeBase,
    syncKnowledgeBase,
    type KnowledgeBase 
} from '@/api/knowledge-base'
import dayjs from 'dayjs'

// Query Parameters
const queryParams = reactive({
  page: 1,
  pageSize: 10,
  keyword: '',
  status: ''
})

// Table Data
const loading = ref(false)
const tableData = ref<KnowledgeBase[]>([])
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0
})

// Dialog
const dialogVisible = ref(false)
const dialogType = ref<'create' | 'edit'>('create')
const submitLoading = ref(false)
const formRef = ref<FormInstance>()
const formData = reactive({
  id: '',
  name: '',
  collection_name: '',
  description: '',
  dimension: 768,
  status: 'normal',
  metadata_fields: [{ field_zh_name: '', field_en_name: '', field_type: 'text', remark: '' }]
})

// 可选字段列表
const availableFields = [
    { label: "文件名称", value: "文件名称" },
    { label: "标准编号", value: "标准编号" },
    { label: "发布单位", value: "发布单位" },
    { label: "文件类型", value: "文件类型" },
    { label: "专业领域", value: "专业领域" },
    { label: "时效性", value: "时效性" },
    { label: "文档层级信息", value: "文档层级信息" },
    { label: "文件URL", value: "文件URL" },
    { label: "施工方案类型适配", value: "施工方案类型适配" }
]

// 计算每个字段下拉框的禁用选项
const getDisabledOptions = (currentIndex: number) => {
    // 获取所有已被选中的字段名
    const selectedValues = formData.metadata_fields
        .map((f, idx) => idx !== currentIndex ? f.field_zh_name : null)
        .filter(v => v !== null && v !== '')
    
    return selectedValues
}

const rules: FormRules = {
  name: [{ required: true, message: '请输入知识库名称', trigger: 'blur' }],
  collection_name: [
    { required: true, message: '请输入集合名称', trigger: 'blur' },
    { pattern: /^[a-zA-Z_][a-zA-Z0-9_]*$/, message: '必须以字母或下划线开头，只能包含字母、数字和下划线', trigger: 'blur' }
  ],
  dimension: [{ required: true, message: '请输入维度', trigger: 'blur' }]
}

// Methods
const loadData = async () => {
  loading.value = true
  try {
    const res = await getKnowledgeBases({
        page: pagination.page,
        page_size: pagination.pageSize,
        keyword: queryParams.keyword,
        status: queryParams.status
    })
    tableData.value = res.data
    pagination.total = res.meta?.total || 0
  } catch (error) {
    console.error(error)
  } finally {
    loading.value = false
  }
}

const handleSearch = () => {
  pagination.page = 1
  loadData()
}

const handleSizeChange = (val: number) => {
  pagination.pageSize = val
  loadData()
}

const handleCurrentChange = (val: number) => {
  pagination.page = val
  loadData()
}

const handleSelectionChange = (val: KnowledgeBase[]) => {
  // console.log(val)
}

const handleFieldChange = (val: string, index: number) => {
    // 自动映射中英文名称和类型
    const map: Record<string, any> = {
        '文件名称': { en: 'file_name', type: 'text' },
        '标准编号': { en: 'standard_number', type: 'text' },
        '发布单位': { en: 'issuing_authority', type: 'text' },
        '文件类型': { en: 'document_type', type: 'text' },
        '专业领域': { en: 'professional_field', type: 'text' },
        '时效性': { en: 'validity', type: 'text' },
        '文档层级信息': { en: 'hierarchy', type: 'text' },
        '文件URL': { en: 'file_url', type: 'text' },
        '施工方案类型适配': { en: 'plan_type_list', type: 'text' }
    }
    
    if (map[val]) {
        formData.metadata_fields[index].field_en_name = map[val].en
        formData.metadata_fields[index].field_type = map[val].type
    }
}

const handleAdd = () => {
  dialogType.value = 'create'
  formData.id = ''
  formData.name = ''
  formData.collection_name = ''
  formData.description = ''
 formData.dimension = 768
  formData.status = 'normal'
  formData.metadata_fields = [{ field_zh_name: '', field_en_name: '', field_type: 'text', remark: '' }]
  dialogVisible.value = true
}
const handleEdit = async (row: KnowledgeBase) => {
  dialogType.value = 'edit'
  formData.id = row.id
  formData.name = row.name
  formData.collection_name = row.collection_name
  formData.description = row.description || ''
  formData.status = row.status
  
  // 加载元数据字段，允许编辑
  try {
      const res = await getKnowledgeBaseMetadata(row.id)
      if (res.code === 0 && res.data) {
          // res.data.metadata_fields 是从 t_samp_metadata 获取的
          if (res.data.metadata_fields && res.data.metadata_fields.length > 0) {
              formData.metadata_fields = res.data.metadata_fields
          } else {
              formData.metadata_fields = [{ field_zh_name: '', field_en_name: '', field_type: 'text', remark: '' }]
          }
      }
  } catch (error) {
      console.error("加载元数据失败", error)
      formData.metadata_fields = [{ field_zh_name: '', field_en_name: '', field_type: 'text', remark: '' }]
  }
  
  dialogVisible.value = true
}

const handleSync = async (row: KnowledgeBase) => {
    try {
        await syncKnowledgeBase(row.id)
        ElMessage.success('同步成功，Milvus集合已创建')
        loadData()
    } catch (error) {
        // error handled by request interceptor
    }
}

const handleView = async (row: KnowledgeBase) => {
    // 复用编辑时的逻辑加载元数据，但不打开编辑弹窗
    try {
        const res = await getKnowledgeBaseMetadata(row.id)
        let metadataInfo = ''
        let schemaInfo = ''
        
        if (res.code === 0 && res.data) {
            if (res.data.metadata_fields && res.data.metadata_fields.length > 0) {
                metadataInfo = res.data.metadata_fields.map((f: any) => 
                    `<li>${f.field_zh_name} (${f.field_en_name}): ${f.field_type === 'text' ? '文本' : '数字'} - ${f.remark || '无备注'}</li>`
                ).join('')
            }
            
            if (res.data.custom_schemas && res.data.custom_schemas.length > 0) {
                schemaInfo = res.data.custom_schemas.map((s: any) => 
                    `<li>${s.field_name}: ${s.field_type} ${s.max_length ? `(Max: ${s.max_length})` : ''} - ${s.description || '无描述'}</li>`
                ).join('')
            }
        }
        
        const content = `
            <div style="text-align: left;">
                <p><strong>名称:</strong> ${row.name}</p>
                <p><strong>集合:</strong> ${row.collection_name}</p>
                <p><strong>描述:</strong> ${row.description || '暂无'}</p>
                <p><strong>状态:</strong> ${getStatusText(row.status)}</p>
                <p><strong>文档数:</strong> ${row.document_count}</p>
                <p><strong>创建时间:</strong> ${formatTime(row.created_at)}</p>
                <br>
                <p><strong>自定义 Schema (Milvus):</strong></p>
                <ul>
                    <li>pk: INT64 (主键)</li>
                    <li>text: VARCHAR (65535) - 内容</li>
                    <li>vector: FLOAT_VECTOR (768) - 向量列</li>
                    <li>sparse: BM25 - 关键字检索</li>
                    <li>document_id: VARCHAR (128) - 文档ID</li>
                    <li>parent_id: VARCHAR (128) - 父段ID</li>
                    <li>index: INT64 - 索引序号</li>
                    <li>tag_list: VARCHAR (2048) - 标签</li>
                    <li>permission: JSON - 权限</li>
                    <li>metadata: JSON - 元数据</li>
                    <li>is_deleted: BOOL - 删除标志</li>
                    <li>created_by: VARCHAR (128) - 创建人</li>
                    <li>created_time: INT64 - 创建时间</li>
                    <li>updated_by: VARCHAR (128) - 修改人</li>
                    <li>updated_time: INT64 - 修改时间</li>
                </ul>
                <br>
                <p><strong>元数据字段 (Metadata):</strong></p>
                <ul>${metadataInfo || '<li>无元数据字段</li>'}</ul>
            </div>
        `
        
        ElMessageBox.alert(content, '知识库详情', {
            dangerouslyUseHTMLString: true,
            confirmButtonText: '关闭',
            customStyle: { maxWidth: '600px' }
        })
    } catch (error) {
        console.error("加载详情失败", error)
        ElMessage.error("获取详情失败")
    }
}

const handleDelete = (row: KnowledgeBase) => {
  // 预先检查，提升用户体验
  if (row.document_count > 0) {
      ElMessage.warning(`知识库 "${row.name}" 中仍有 ${row.document_count} 条文档，请先清空文档后再删除`)
      return
  }

  ElMessageBox.confirm(
    `确定要删除知识库 "${row.name}" 吗？此操作不可恢复，且会删除对应的Milvus集合。`,
    '警告',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(async () => {
      try {
        await deleteKnowledgeBase(row.id)
        ElMessage.success('删除成功')
        loadData()
      } catch (error) {
        // error handled by request interceptor
      }
    })
    .catch(() => {})
}

const handleCommand = async (command: string, row: KnowledgeBase) => {
    if (command === 'toggleStatus') {
        const newStatus = row.status === 'disabled' ? 'normal' : 'disabled'
        try {
            await updateKnowledgeBaseStatus(row.id, newStatus)
            ElMessage.success('状态更新成功')
            loadData()
        } catch (error) {
            console.error(error)
        }
    }
}

const addMetadataField = () => {
    formData.metadata_fields.push({ field_zh_name: '', field_en_name: '', field_type: 'text', remark: '' })
}

const removeMetadataField = (index: number) => {
    formData.metadata_fields.splice(index, 1)
}

const handleSubmit = async () => {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (valid) {
      submitLoading.value = true
      try {
        if (dialogType.value === 'create') {
          await createKnowledgeBase({
            name: formData.name,
            collection_name: formData.collection_name,
            description: formData.description,
            dimension: formData.dimension,
            metadata_fields: formData.metadata_fields.filter(f => f.field_zh_name && f.field_en_name)
          })
          ElMessage.success('创建成功')
        } else {
          await updateKnowledgeBase(formData.id, {
            name: formData.name,
            description: formData.description,
            status: formData.status,
            metadata_fields: formData.metadata_fields.filter(f => f.field_zh_name && f.field_en_name)
          })
          ElMessage.success('更新成功')
        }
        dialogVisible.value = false
        loadData()
      } catch (error) {
        console.error(error)
      } finally {
        submitLoading.value = false
      }
    }
  })
}

const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

// Helpers
const getStatusType = (status: string) => {
  const map: Record<string, string> = {
    normal: 'success',
    test: 'info',
    disabled: 'danger'
  }
  return map[status] || 'info'
}

const getStatusText = (status: string) => {
  const map: Record<string, string> = {
    normal: '正常',
    test: '测试',
    disabled: '已禁用'
  }
  return map[status] || status
}

const formatTime = (time: string) => {
    if (!time) return '-'
    return dayjs(time).format('YYYY-MM-DD HH:mm')
}

// 为图标生成随机颜色或基于名称的固定颜色
const getIconColor = (name: string) => {
    const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']
    let hash = 0
    for (let i = 0; i < name.length; i++) {
        hash = name.charCodeAt(i) + ((hash << 5) - hash)
    }
    const index = Math.abs(hash) % colors.length
    return colors[index]
}

onMounted(() => {
  loadData()
})
</script>

<style scoped>
.kb-container {
  padding: 20px;
}

.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.title-info h2 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: #303133;
}

.subtitle {
  margin: 8px 0 0;
  color: #909399;
  font-size: 14px;
}

.table-card {
  border-radius: 8px;
}

.kb-name-cell {
  display: flex;
  align-items: flex-start;
  padding: 8px 0;
}

.kb-icon {
  margin-right: 12px;
  margin-top: 4px;
}

.kb-info {
  flex: 1;
}

.kb-info .name {
  font-weight: 600;
  font-size: 14px;
  color: #303133;
  margin-bottom: 4px;
}

.kb-info .desc {
  font-size: 12px;
  color: #909399;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.pagination-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
}

.pagination-info {
    color: #909399;
    font-size: 13px;
}

.kb-dialog :deep(.el-dialog__body) {
    padding: 20px 30px;
}

.kb-form {
    padding-right: 10px;
}

.form-section {
    margin-bottom: 24px;
}

.section-title {
    font-size: 15px;
    font-weight: 600;
    color: #303133;
    margin-bottom: 16px;
    padding-left: 10px;
    border-left: 3px solid #409eff;
}

.section-header {
    display: flex;
    align-items: baseline;
    margin-bottom: 16px;
}

.section-desc {
    font-size: 12px;
    color: #909399;
    margin-left: 10px;
}

.metadata-field-card {
    background-color: #f8f9fa;
    border-radius: 4px;
    border: 1px solid #e4e7ed;
    padding: 12px 16px;
    margin-bottom: 12px;
}

.field-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.field-index {
    font-size: 12px;
    font-weight: 600;
    color: #606266;
    background-color: #e6e8eb;
    padding: 2px 6px;
    border-radius: 2px;
}

.add-field-btn {
    margin-top: 10px;
}

.metadata-fields-container {
    padding: 0 5px;
}

.delete-btn {
    margin-left: 10px;
}
</style>
