<script setup lang="ts">
import type {
  ChunkPreviewItem,
  HitStatItem,
  HitStatsResponse,
  KnowledgeAnnotation,
  KnowledgeBase,
  KnowledgeBaseUpdateInput,
  KnowledgeDocumentListItem,
  KnowledgeRetrievalResult,
  KnowledgeSegment,
  ModelListItem,
  RetrievalLog,
} from '#/api/ai-platform/ai-platform';

import {
  computed,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  watch,
} from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';
import {
  ArrowLeft,
  BarChart2,
  BookMarked,
  CircleHelp,
  Database,
  Edit,
  Eye,
  FileText,
  Layers,
  Minus,
  Plus,
  RefreshCw,
  ScrollText,
  Search,
  Settings,
  Target,
  Trash2,
  TriangleAlert,
} from '@vben/icons';
import { $t } from '@vben/locales';

import {
  ElButton,
  ElCard,
  ElCheckboxButton,
  ElCheckboxGroup,
  ElEmpty,
  ElForm,
  ElFormItem,
  ElImageViewer,
  ElInput,
  ElInputNumber,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElPagination,
  ElScrollbar,
  ElSelect,
  ElSlider,
  ElSwitch,
  ElTag,
  ElTooltip,
} from 'element-plus';

import {
  batchAddKnowledgeDocumentsApi,
  chunkPreviewApi,
  createAnnotationApi,
  deleteAnnotationApi,
  deleteKnowledgeDocumentApi,
  deleteKnowledgeSegmentApi,
  getActiveModelsApi,
  getAnnotationListApi,
  getHitStatsApi,
  getKnowledgeBaseDetailApi,
  getKnowledgeDocumentListApi,
  getKnowledgeSegmentListApi,
  getRetrievalLogsApi,
  reindexAllDocumentsApi,
  reindexAnnotationsApi,
  reindexKnowledgeDocumentApi,
  retrieveKnowledgeApi,
  toggleKnowledgeDocumentApi,
  updateAnnotationApi,
  updateKnowledgeBaseApi,
  updateKnowledgeSegmentApi,
} from '#/api/ai-platform/ai-platform';
import { getFileTypeIcon } from '#/assets/file-icons';
import { ZqDialog } from '#/components/zq-dialog';
import FileSelector from '#/components/zq-form/file-selector/file-selector.vue';
import { ZqTabs } from '#/components/zq-tabs/index';
import { getFileUrl } from '#/composables/useFileUrl';
import { useAppContextStore } from '#/store/app-context';

const route = useRoute();
const router = useRouter();
const appContextStore = useAppContextStore();

const kbId = computed(() => route.params.id as string);
const activeTab = ref('documents');
const loading = ref(false);

const tabItems = computed(() => [
  {
    key: 'documents',
    label: $t('ai-platform.knowledge.document.title'),
    icon: FileText,
  },
  {
    key: 'segments',
    label: $t('ai-platform.knowledge.segment.title'),
    icon: Layers,
  },
  {
    key: 'retrieval',
    label: $t('ai-platform.knowledge.retrieval.title'),
    icon: Target,
  },
  {
    key: 'annotations',
    label: $t('ai-platform.knowledge.annotation.title'),
    icon: BookMarked,
  },
  {
    key: 'hitStats',
    label: $t('ai-platform.knowledge.hitStats.title'),
    icon: BarChart2,
  },
  {
    key: 'retrievalLogs',
    label: $t('ai-platform.knowledge.retrievalLog.title'),
    icon: ScrollText,
  },
  {
    key: 'settings',
    label: $t('ai-platform.knowledge.settings.title'),
    icon: Settings,
  },
]);

// 知识库详情
const kbDetail = ref<KnowledgeBase | null>(null);

async function loadDetail() {
  loading.value = true;
  try {
    kbDetail.value = await getKnowledgeBaseDetailApi(kbId.value);
  } catch {
    ElMessage.error('Failed to load knowledge base');
  } finally {
    loading.value = false;
  }
}

// ==================== 文档列表 ====================
const docLoading = ref(false);
const docList = ref<KnowledgeDocumentListItem[]>([]);
const docSearch = ref('');
const docPagination = reactive({ current: 1, pageSize: 20, total: 0 });

// 文档状态轮询
let pollTimer: null | ReturnType<typeof setTimeout> = null;
const POLL_INTERVAL = 3000;

function hasProcessingDocs() {
  return docList.value.some(
    (d) => d.status === 'pending' || d.status === 'indexing',
  );
}

function startPolling() {
  stopPolling();
  pollTimer = setTimeout(async () => {
    await fetchDocuments(true);
    if (hasProcessingDocs()) {
      startPolling();
    } else {
      loadDetail();
    }
  }, POLL_INTERVAL);
}

function stopPolling() {
  if (pollTimer) {
    clearTimeout(pollTimer);
    pollTimer = null;
  }
}

async function fetchDocuments(silent = false) {
  if (!silent) docLoading.value = true;
  try {
    const res = await getKnowledgeDocumentListApi(kbId.value, {
      page: docPagination.current,
      pageSize: docPagination.pageSize,
      name: docSearch.value || undefined,
    });
    docList.value = res.items;
    docPagination.total = res.total;
    if (hasProcessingDocs()) {
      startPolling();
    }
  } catch {
    // ignore
  } finally {
    if (!silent) docLoading.value = false;
  }
}

function getDocStatusType(status: string) {
  const map: Record<string, string> = {
    completed: 'success',
    indexing: 'warning',
    pending: 'info',
    failed: 'danger',
    disabled: 'info',
  };
  return map[status] || 'info';
}

function getDocStatusText(status: string) {
  const key = `ai-platform.knowledge.document.${status}`;
  return $t(key);
}

function formatFileSize(bytes: number) {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
}

// ==================== 文档缩略图 & 预览 ====================
const IMAGE_EXTS = new Set([
  'bmp',
  'gif',
  'ico',
  'jpeg',
  'jpg',
  'png',
  'svg',
  'tiff',
  'webp',
]);

function isImageFile(doc: KnowledgeDocumentListItem): boolean {
  const ext = doc.name?.split('.').pop()?.toLowerCase() || '';
  return IMAGE_EXTS.has(ext);
}

function getDocFileExt(doc: KnowledgeDocumentListItem): string {
  return doc.name?.split('.').pop()?.toLowerCase() || doc.file_type || '';
}

const docThumbnailCache = ref<Map<string, string>>(new Map());

function getDocThumbnail(doc: KnowledgeDocumentListItem): string | undefined {
  if (!isImageFile(doc) || !doc.file_id) return undefined;
  const cached = docThumbnailCache.value.get(doc.file_id);
  if (cached) return cached;
  // 异步加载并缓存
  getFileUrl(doc.file_id).then((url) => {
    const newCache = new Map(docThumbnailCache.value);
    newCache.set(doc.file_id!, url);
    docThumbnailCache.value = newCache;
  });
  return undefined;
}

const docPreviewVisible = ref(false);
const docPreviewUrlList = ref<string[]>([]);

async function handlePreviewDoc(doc: KnowledgeDocumentListItem) {
  if (!doc.file_id) return;
  if (isImageFile(doc)) {
    let url = docThumbnailCache.value.get(doc.file_id);
    if (!url) {
      try {
        url = await getFileUrl(doc.file_id);
      } catch {
        ElMessage.error($t('ai-platform.knowledge.chunkPreview.error'));
        return;
      }
    }
    docPreviewUrlList.value = [url];
    docPreviewVisible.value = true;
  } else {
    const ext = getDocFileExt(doc);
    const query = new URLSearchParams({ name: doc.name || '', ext });
    window.open(`/file-preview/${doc.file_id}?${query.toString()}`, '_blank');
  }
}

async function handleDeleteDoc(doc: KnowledgeDocumentListItem) {
  try {
    await ElMessageBox.confirm(
      $t('ai-platform.knowledge.document.deleteConfirm'),
      $t('ai-platform.knowledge.document.delete'),
      { type: 'warning' },
    );
    await deleteKnowledgeDocumentApi(kbId.value, doc.id);
    ElMessage.success($t('ai-platform.knowledge.document.deleteSuccess'));
    fetchDocuments();
    loadDetail();
  } catch {
    // cancelled
  }
}

async function handleReindex(doc: KnowledgeDocumentListItem) {
  try {
    await reindexKnowledgeDocumentApi(kbId.value, doc.id);
    ElMessage.success($t('ai-platform.knowledge.document.reindexSuccess'));
    fetchDocuments();
  } catch {
    // ignore
  }
}

async function handleToggleDoc(
  doc: KnowledgeDocumentListItem,
  enabled: boolean,
) {
  try {
    await toggleKnowledgeDocumentApi(kbId.value, doc.id, enabled);
    fetchDocuments();
  } catch {
    // ignore
  }
}

// 添加文档弹窗
const addDocFileIds = ref<string[]>([]);
const fileSelectorRef = ref<InstanceType<any> | null>(null);

function handleOpenAddDoc() {
  fileSelectorRef.value?.openModal();
}

async function handleAddDocChange(val: string | string[] | undefined) {
  const ids = Array.isArray(val) ? val : (val ? [val] : []);
  if (ids.length === 0) return;
  try {
    await batchAddKnowledgeDocumentsApi(kbId.value, ids);
    ElMessage.success($t('ai-platform.knowledge.document.addSuccess'));
    addDocFileIds.value = [];
    fetchDocuments();
    loadDetail();
  } catch {
    // ignore
  }
}

// ==================== 分段列表 ====================
const segLoading = ref(false);
const segList = ref<KnowledgeSegment[]>([]);
const segSearch = ref('');
const segEmbeddingFilter = ref<string[]>([]);
const segPagination = reactive({ current: 1, pageSize: 20, total: 0 });
const segMetadataFilterKey = ref('');
const segMetadataFilterValue = ref('');

async function fetchSegments() {
  segLoading.value = true;
  try {
    const res = await getKnowledgeSegmentListApi(kbId.value, {
      page: segPagination.current,
      pageSize: segPagination.pageSize,
      keyword: segSearch.value || undefined,
      embeddingStatus:
        segEmbeddingFilter.value.length === 1
          ? segEmbeddingFilter.value[0]
          : undefined,
      metadataKey: segMetadataFilterKey.value || undefined,
      metadataValue: segMetadataFilterValue.value || undefined,
    });
    segList.value = res.items;
    segPagination.total = res.total;
  } catch {
    // ignore
  } finally {
    segLoading.value = false;
  }
}

// 分段元数据编辑
const metadataEditSegId = ref('');
const metadataEditDialogVisible = ref(false);
const metadataEditPairs = ref<Array<{ key: string; value: string }>>([]);

function handleEditMetadata(seg: KnowledgeSegment) {
  metadataEditSegId.value = seg.id;
  const meta = seg.extra_metadata || {};
  metadataEditPairs.value = Object.entries(meta).map(([key, value]) => ({
    key,
    value: typeof value === 'string' ? value : JSON.stringify(value),
  }));
  if (metadataEditPairs.value.length === 0) {
    metadataEditPairs.value.push({ key: '', value: '' });
  }
  metadataEditDialogVisible.value = true;
}

function addMetadataPair() {
  metadataEditPairs.value.push({ key: '', value: '' });
}

function removeMetadataPair(index: number) {
  metadataEditPairs.value.splice(index, 1);
}

async function handleSaveMetadata() {
  const metadata: Record<string, any> = {};
  for (const pair of metadataEditPairs.value) {
    if (pair.key.trim()) {
      metadata[pair.key.trim()] = pair.value;
    }
  }
  try {
    await updateKnowledgeSegmentApi(kbId.value, metadataEditSegId.value, {
      extra_metadata: metadata,
    });
    ElMessage.success($t('ai-platform.knowledge.saveSuccess'));
    metadataEditDialogVisible.value = false;
    fetchSegments();
  } catch {
    // ignore
  }
}

// 编辑分段弹窗
const editSegDialogVisible = ref(false);
const editSegForm = reactive({ id: '', content: '', enabled: true });

function handleEditSegment(seg: KnowledgeSegment) {
  editSegForm.id = seg.id;
  editSegForm.content = seg.content;
  editSegForm.enabled = seg.enabled;
  editSegDialogVisible.value = true;
}

async function handleSaveSegment() {
  try {
    await updateKnowledgeSegmentApi(kbId.value, editSegForm.id, {
      content: editSegForm.content,
      enabled: editSegForm.enabled,
    });
    ElMessage.success($t('ai-platform.knowledge.saveSuccess'));
    editSegDialogVisible.value = false;
    fetchSegments();
  } catch {
    // ignore
  }
}

async function handleDeleteSegment(seg: KnowledgeSegment) {
  try {
    await ElMessageBox.confirm(
      $t('ai-platform.knowledge.segment.deleteConfirm'),
      $t('ai-platform.knowledge.segment.delete'),
      { type: 'warning' },
    );
    await deleteKnowledgeSegmentApi(kbId.value, seg.id);
    ElMessage.success($t('ai-platform.knowledge.segment.deleteSuccess'));
    fetchSegments();
    loadDetail();
  } catch {
    // cancelled
  }
}

// ==================== 分块预览 ====================
const chunkPreviewDialogVisible = ref(false);
const chunkPreviewLoading = ref(false);
const chunkPreviewDocName = ref('');
const chunkPreviewResults = ref<ChunkPreviewItem[]>([]);
const chunkPreviewTotal = ref(0);

async function handleOpenChunkPreview(doc: KnowledgeDocumentListItem) {
  if (!doc.file_id) {
    ElMessage.warning($t('ai-platform.knowledge.chunkPreview.noFileId'));
    return;
  }
  chunkPreviewDocName.value = doc.name;
  chunkPreviewResults.value = [];
  chunkPreviewTotal.value = 0;
  chunkPreviewDialogVisible.value = true;
  chunkPreviewLoading.value = true;
  try {
    const res = await chunkPreviewApi(kbId.value, {
      file_id: doc.file_id,
      chunk_strategy: kbDetail.value?.chunk_strategy || 'recursive',
      chunk_size: kbDetail.value?.chunk_size || 500,
      chunk_overlap: kbDetail.value?.chunk_overlap || 50,
    });
    chunkPreviewResults.value = res.chunks;
    chunkPreviewTotal.value = res.total;
  } catch {
    ElMessage.error($t('ai-platform.knowledge.chunkPreview.error'));
  } finally {
    chunkPreviewLoading.value = false;
  }
}

// ==================== 召回测试 ====================
const retrievalQuery = ref('');
const retrievalLoading = ref(false);
const retrievalResults = ref<KnowledgeRetrievalResult[]>([]);
const retrievalElapsed = ref(0);
const retrievalMode = ref('');
const rerankApplied = ref(false);
const retrievalMetadataFilters = ref<Array<{ key: string; value: string }>>([]);
const expandedParentIds = ref<Set<string>>(new Set());

function addRetrievalMetadataFilter() {
  retrievalMetadataFilters.value.push({ key: '', value: '' });
}

function removeRetrievalMetadataFilter(index: number) {
  retrievalMetadataFilters.value.splice(index, 1);
}

function toggleParentContent(segmentId: string) {
  if (expandedParentIds.value.has(segmentId)) {
    expandedParentIds.value.delete(segmentId);
  } else {
    expandedParentIds.value.add(segmentId);
  }
}

function getMatchSourceType(source?: string) {
  const map: Record<string, string> = {
    vector: 'primary',
    fulltext: 'success',
    annotation: 'warning',
  };
  return map[source || ''] || 'info';
}

async function handleRetrieve() {
  if (!retrievalQuery.value.trim()) return;
  retrievalLoading.value = true;
  expandedParentIds.value.clear();
  try {
    let metadataFilter: Record<string, any> | undefined;
    const validFilters = retrievalMetadataFilters.value.filter((f) =>
      f.key.trim(),
    );
    if (validFilters.length > 0) {
      metadataFilter = {};
      for (const f of validFilters) {
        metadataFilter[f.key.trim()] = f.value;
      }
    }
    const res = await retrieveKnowledgeApi({
      query: retrievalQuery.value,
      knowledge_base_ids: [kbId.value],
      metadata_filter: metadataFilter,
    });
    retrievalResults.value = res.results;
    retrievalElapsed.value = res.elapsed_time;
    retrievalMode.value = res.retrieval_mode || '';
    rerankApplied.value = res.rerank_applied || false;
  } catch {
    // ignore
  } finally {
    retrievalLoading.value = false;
  }
}

// ==================== 批量重新索引 ====================
async function handleReindexAll() {
  try {
    await ElMessageBox.confirm(
      $t('ai-platform.knowledge.document.reindexAllConfirm'),
      $t('ai-platform.knowledge.document.reindexAll'),
      { type: 'warning' },
    );
    await reindexAllDocumentsApi(kbId.value);
    ElMessage.success($t('ai-platform.knowledge.document.reindexAllSuccess'));
    fetchDocuments();
  } catch {
    // cancelled
  }
}

// ==================== 标注管理 ====================
const annotationLoading = ref(false);
const annotationList = ref<KnowledgeAnnotation[]>([]);
const annotationSearch = ref('');
const annotationPagination = reactive({ current: 1, pageSize: 20, total: 0 });

async function fetchAnnotations() {
  annotationLoading.value = true;
  try {
    const res = await getAnnotationListApi(kbId.value, {
      page: annotationPagination.current,
      pageSize: annotationPagination.pageSize,
      keyword: annotationSearch.value || undefined,
    });
    annotationList.value = res.items;
    annotationPagination.total = res.total;
  } catch {
    // ignore
  } finally {
    annotationLoading.value = false;
  }
}

const addAnnotationDialogVisible = ref(false);
const editAnnotationDialogVisible = ref(false);
const annotationForm = reactive({
  id: '',
  question: '',
  answer: '',
  enabled: true,
});

function handleAddAnnotation() {
  annotationForm.id = '';
  annotationForm.question = '';
  annotationForm.answer = '';
  annotationForm.enabled = true;
  addAnnotationDialogVisible.value = true;
}

function handleEditAnnotation(item: KnowledgeAnnotation) {
  annotationForm.id = item.id;
  annotationForm.question = item.question;
  annotationForm.answer = item.answer;
  annotationForm.enabled = item.enabled;
  editAnnotationDialogVisible.value = true;
}

async function handleSaveAnnotation() {
  if (!annotationForm.question.trim() || !annotationForm.answer.trim()) {
    ElMessage.warning(
      $t('ai-platform.knowledge.annotation.questionPlaceholder'),
    );
    return;
  }
  try {
    if (annotationForm.id) {
      await updateAnnotationApi(kbId.value, annotationForm.id, {
        question: annotationForm.question,
        answer: annotationForm.answer,
        enabled: annotationForm.enabled,
      });
      ElMessage.success($t('ai-platform.knowledge.annotation.saveSuccess'));
      editAnnotationDialogVisible.value = false;
    } else {
      await createAnnotationApi(kbId.value, {
        question: annotationForm.question,
        answer: annotationForm.answer,
      });
      ElMessage.success($t('ai-platform.knowledge.annotation.createSuccess'));
      addAnnotationDialogVisible.value = false;
    }
    fetchAnnotations();
  } catch {
    // ignore
  }
}

async function handleDeleteAnnotation(item: KnowledgeAnnotation) {
  try {
    await ElMessageBox.confirm(
      $t('ai-platform.knowledge.annotation.deleteConfirm'),
      $t('ai-platform.knowledge.annotation.delete'),
      { type: 'warning' },
    );
    await deleteAnnotationApi(kbId.value, item.id);
    ElMessage.success($t('ai-platform.knowledge.annotation.deleteSuccess'));
    fetchAnnotations();
  } catch {
    // cancelled
  }
}

async function handleReindexAnnotations() {
  try {
    await reindexAnnotationsApi(kbId.value);
    ElMessage.success($t('ai-platform.knowledge.annotation.reindexSuccess'));
    fetchAnnotations();
    startAnnotationPolling();
  } catch {
    // ignore
  }
}

let annotationPollingTimer: null | ReturnType<typeof setInterval> = null;

function startAnnotationPolling() {
  stopAnnotationPolling();
  annotationPollingTimer = setInterval(async () => {
    await fetchAnnotations();
    const hasPending = annotationList.value.some(
      (a) => a.embedding_status === 'pending',
    );
    if (!hasPending) {
      stopAnnotationPolling();
    }
  }, 3000);
}

function stopAnnotationPolling() {
  if (annotationPollingTimer) {
    clearInterval(annotationPollingTimer);
    annotationPollingTimer = null;
  }
}

// ==================== 命中统计 ====================
const hitStatsLoading = ref(false);
const hitStatsData = ref<HitStatsResponse | null>(null);
const hitStatsIncludeZero = ref(false);

async function fetchHitStats() {
  hitStatsLoading.value = true;
  try {
    hitStatsData.value = await getHitStatsApi(kbId.value, {
      topN: 50,
      includeZero: hitStatsIncludeZero.value,
    });
  } catch {
    // ignore
  } finally {
    hitStatsLoading.value = false;
  }
}

function getHitBarWidth(item: HitStatItem) {
  if (!hitStatsData.value || hitStatsData.value.total_hits === 0) return '0%';
  return `${Math.max(item.hit_percentage, 2)}%`;
}

// ==================== 检索日志 ====================
const logLoading = ref(false);
const logList = ref<RetrievalLog[]>([]);
const logSearch = ref('');
const logPagination = reactive({ current: 1, pageSize: 20, total: 0 });

async function fetchRetrievalLogs() {
  logLoading.value = true;
  try {
    const res = await getRetrievalLogsApi({
      knowledgeBaseId: kbId.value,
      keyword: logSearch.value || undefined,
      page: logPagination.current,
      pageSize: logPagination.pageSize,
    });
    logList.value = res.items;
    logPagination.total = res.total;
  } catch {
    // ignore
  } finally {
    logLoading.value = false;
  }
}

// ==================== 设置 ====================
const settingsForm = reactive<KnowledgeBaseUpdateInput>({
  process_rules: { remove_extra_spaces: false, remove_urls_emails: false },
});
const allModels = ref<ModelListItem[]>([]);
const embeddingModels = computed(() =>
  allModels.value.filter((m) => m.model_type === 'embedding'),
);
const rerankModels = computed(() =>
  allModels.value.filter((m) => m.model_type === 'rerank'),
);
const settingsLoading = ref(false);

async function loadEmbeddingModels() {
  try {
    const res = await getActiveModelsApi();
    allModels.value = res;
  } catch {
    // ignore
  }
}

function initSettingsForm() {
  if (!kbDetail.value) return;
  const kb = kbDetail.value;
  settingsForm.name = kb.name;
  settingsForm.description = kb.description;
  settingsForm.icon = kb.icon;
  settingsForm.embedding_model_id = kb.embedding_model_id;
  settingsForm.embedding_dimensions = kb.embedding_dimensions;
  settingsForm.chunk_strategy = kb.chunk_strategy;
  settingsForm.chunk_size = kb.chunk_size;
  settingsForm.chunk_overlap = kb.chunk_overlap;
  settingsForm.retrieval_mode = kb.retrieval_mode;
  settingsForm.top_k = kb.top_k;
  settingsForm.score_threshold = kb.score_threshold;
  settingsForm.rerank_enabled = kb.rerank_enabled;
  settingsForm.rerank_model_id = kb.rerank_model_id;
  settingsForm.retrieval_weight = kb.retrieval_weight;
  settingsForm.indexing_technique = kb.indexing_technique;
  settingsForm.process_rules = kb.process_rules || {};
}

// Embedding模型切换引导
const originalEmbeddingModelId = ref('');

function initSettingsOriginalModel() {
  if (kbDetail.value) {
    originalEmbeddingModelId.value = kbDetail.value.embedding_model_id || '';
  }
}

async function handleSaveSettings() {
  const embeddingModelChanged =
    settingsForm.embedding_model_id !== originalEmbeddingModelId.value;

  if (
    embeddingModelChanged &&
    kbDetail.value &&
    (kbDetail.value.segment_count || 0) > 0
  ) {
    try {
      await ElMessageBox.confirm(
        $t('ai-platform.knowledge.settings.embeddingModelChangeWarning'),
        $t('ai-platform.knowledge.settings.embeddingModelChangeTitle'),
        {
          type: 'warning',
          confirmButtonText: $t(
            'ai-platform.knowledge.settings.saveAndReindex',
          ),
          cancelButtonText: $t('common.cancel'),
        },
      );
    } catch {
      return;
    }
  }

  settingsLoading.value = true;
  try {
    await updateKnowledgeBaseApi(kbId.value, settingsForm);
    ElMessage.success($t('ai-platform.knowledge.saveSuccess'));

    if (
      embeddingModelChanged &&
      kbDetail.value &&
      (kbDetail.value.segment_count || 0) > 0
    ) {
      await reindexAllDocumentsApi(kbId.value);
      ElMessage.success($t('ai-platform.knowledge.document.reindexAllSuccess'));
      fetchDocuments();
    }

    originalEmbeddingModelId.value = settingsForm.embedding_model_id || '';
    loadDetail();
  } catch {
    // ignore
  } finally {
    settingsLoading.value = false;
  }
}

function handleBack() {
  router.push(appContextStore.getContextPath('/ai-platform/knowledge-base'));
}

// Tab 切换时加载数据
watch(activeTab, (tab) => {
  switch (tab) {
    case 'annotations': {
      fetchAnnotations().then(() => {
        const hasPending = annotationList.value.some(
          (a) => a.embedding_status === 'pending',
        );
        if (hasPending) startAnnotationPolling();
        else stopAnnotationPolling();
      });

      break;
    }
    case 'documents': {
      fetchDocuments();
      break;
    }
    case 'hitStats': {
      fetchHitStats();
      break;
    }
    case 'retrievalLogs': {
      fetchRetrievalLogs();
      break;
    }
    case 'segments': {
      fetchSegments();
      break;
    }
    case 'settings': {
      initSettingsForm();
      initSettingsOriginalModel();

      break;
    }
    // No default
  }
});

onMounted(async () => {
  await loadDetail();
  loadEmbeddingModels();
  fetchDocuments();
});

onBeforeUnmount(() => {
  stopPolling();
  stopAnnotationPolling();
});
</script>

<template>
  <div class="ai-knowledge-detail-page">
    <Page auto-content-height v-loading="loading">
      <template #title>
        <div class="flex items-center gap-3">
          <ElButton text @click="handleBack">
            <ArrowLeft class="h-4 w-4" />
          </ElButton>
          <Database class="text-primary h-5 w-5" />
          <span class="text-lg font-medium">
            {{ kbDetail?.name || '' }}
          </span>
          <ElTag
            v-if="kbDetail"
            size="small"
            :type="getDocStatusType(kbDetail.status) as any"
          >
            {{ getDocStatusText(kbDetail.status) }}
          </ElTag>
          <span v-if="kbDetail" class="text-muted-foreground ml-2 text-sm">
            {{ $t('ai-platform.knowledge.documents') }}:
            {{ kbDetail.document_count }}
            &nbsp;|&nbsp;
            {{ $t('ai-platform.knowledge.segments') }}:
            {{ kbDetail.segment_count }}
          </span>
        </div>
      </template>

      <div class="bg-background flex h-full flex-col p-4">
        <ZqTabs
          v-model="activeTab"
          :items="tabItems"
          class="mb-4 flex-shrink-0"
        />

        <ElScrollbar class="flex-1">
          <!-- 文档 Tab -->
          <div v-if="activeTab === 'documents'">
            <div class="mb-4 flex items-center justify-between">
              <div class="flex items-center gap-2">
                <ElInput
                  v-model="docSearch"
                  :placeholder="
                    $t('ai-platform.knowledge.document.searchPlaceholder')
                  "
                  clearable
                  class="w-64"
                  @keyup.enter="fetchDocuments"
                >
                  <template #prefix>
                    <Search class="h-4 w-4" />
                  </template>
                </ElInput>
              </div>
              <div class="flex items-center gap-2">
                <ElButton size="small" @click="handleReindexAll">
                  <RefreshCw class="mr-1 h-3.5 w-3.5" />
                  {{ $t('ai-platform.knowledge.document.reindexAll') }}
                </ElButton>
                <ElButton type="primary" size="small" @click="handleOpenAddDoc">
                  <Plus class="mr-1 h-3.5 w-3.5" />
                  {{ $t('ai-platform.knowledge.document.add') }}
                </ElButton>
              </div>
            </div>

            <div v-loading="docLoading">
              <div v-if="docList.length > 0" class="flex flex-col gap-2">
                <ElCard
                  v-for="doc in docList"
                  :key="doc.id"
                  shadow="never"
                  :body-style="{ padding: '12px 16px' }"
                >
                  <div class="flex items-center justify-between">
                    <div
                      class="flex min-w-0 flex-1 cursor-pointer items-center gap-3"
                      @click="handlePreviewDoc(doc)"
                    >
                      <img
                        v-if="isImageFile(doc) && getDocThumbnail(doc)"
                        :src="getDocThumbnail(doc)"
                        class="h-9 w-9 flex-shrink-0 rounded object-cover"
                      />
                      <img
                        v-else
                        :src="getFileTypeIcon(getDocFileExt(doc))"
                        class="h-9 w-9 flex-shrink-0"
                      />
                      <div class="min-w-0 flex-1">
                        <div
                          class="hover:text-primary truncate text-sm font-medium transition-colors"
                        >
                          {{ doc.name }}
                        </div>
                        <div
                          class="text-muted-foreground mt-0.5 flex gap-3 text-xs"
                        >
                          <span>{{ doc.file_type }}</span>
                          <span>{{ formatFileSize(doc.file_size) }}</span>
                          <span>
                            {{ $t('ai-platform.knowledge.segments') }}:
                            {{ doc.segment_count }}
                          </span>
                        </div>
                      </div>
                    </div>
                    <div class="flex items-center gap-2">
                      <ElTooltip
                        v-if="doc.duplicate_warning"
                        :content="doc.duplicate_warning"
                        placement="top"
                      >
                        <TriangleAlert
                          class="text-warning h-4 w-4 flex-shrink-0"
                        />
                      </ElTooltip>
                      <ElTag
                        size="small"
                        :type="getDocStatusType(doc.status) as any"
                      >
                        {{ getDocStatusText(doc.status) }}
                      </ElTag>
                      <ElSwitch
                        :model-value="doc.enabled"
                        size="small"
                        @change="
                          (val: any) => handleToggleDoc(doc, val as boolean)
                        "
                      />
                      <ElTooltip
                        :content="
                          $t('ai-platform.knowledge.chunkPreview.title')
                        "
                      >
                        <ElButton
                          text
                          size="small"
                          @click="handleOpenChunkPreview(doc)"
                        >
                          <Eye class="h-3.5 w-3.5" />
                        </ElButton>
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('ai-platform.knowledge.document.reindex')"
                      >
                        <ElButton text size="small" @click="handleReindex(doc)">
                          <RefreshCw class="h-3.5 w-3.5" />
                        </ElButton>
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('ai-platform.knowledge.document.delete')"
                      >
                        <ElButton
                          text
                          size="small"
                          @click="handleDeleteDoc(doc)"
                        >
                          <Trash2 class="h-3.5 w-3.5" />
                        </ElButton>
                      </ElTooltip>
                    </div>
                  </div>
                </ElCard>
              </div>
              <ElEmpty v-else :description="$t('common.noData')" />
            </div>

            <div
              v-if="docPagination.total > docPagination.pageSize"
              class="mt-4 flex justify-end"
            >
              <ElPagination
                v-model:current-page="docPagination.current"
                v-model:page-size="docPagination.pageSize"
                :total="docPagination.total"
                layout="total, prev, pager, next"
                background
                size="small"
                @current-change="() => fetchDocuments()"
              />
            </div>
          </div>

          <!-- 分段 Tab -->
          <div v-if="activeTab === 'segments'">
            <div class="mb-4 flex flex-col gap-2">
              <div class="flex items-center gap-2">
                <ElInput
                  v-model="segSearch"
                  :placeholder="
                    $t('ai-platform.knowledge.segment.searchPlaceholder')
                  "
                  clearable
                  class="w-64"
                  @keyup.enter="fetchSegments"
                >
                  <template #prefix>
                    <Search class="h-4 w-4" />
                  </template>
                </ElInput>
                <ElInput
                  v-model="segMetadataFilterKey"
                  :placeholder="
                    $t('ai-platform.knowledge.metadata.filterKeyPlaceholder')
                  "
                  clearable
                  class="w-40"
                  @keyup.enter="fetchSegments"
                />
                <ElInput
                  v-model="segMetadataFilterValue"
                  :placeholder="
                    $t('ai-platform.knowledge.metadata.filterValuePlaceholder')
                  "
                  clearable
                  class="w-40"
                  @keyup.enter="fetchSegments"
                />
                <ElButton @click="fetchSegments">
                  <Search class="mr-1 h-3 w-3" />
                  {{ $t('ai-platform.knowledge.metadata.filter') }}
                </ElButton>
                <ElCheckboxGroup
                  v-model="segEmbeddingFilter"
                  class="flex"
                  @change="fetchSegments"
                >
                  <ElCheckboxButton value="completed">
                    {{ $t('ai-platform.knowledge.segment.embeddingCompleted') }}
                  </ElCheckboxButton>
                  <ElCheckboxButton value="failed">
                    {{ $t('ai-platform.knowledge.segment.embeddingFailed') }}
                  </ElCheckboxButton>
                </ElCheckboxGroup>
              </div>
              <div class="flex items-center gap-2"></div>
            </div>

            <div v-loading="segLoading">
              <div
                v-if="segList.length > 0"
                class="grid grid-cols-1 gap-2 lg:grid-cols-2"
              >
                <ElCard
                  v-for="seg in segList"
                  :key="seg.id"
                  shadow="never"
                  :body-style="{ padding: '12px 16px' }"
                >
                  <div class="mb-2 flex items-center justify-between">
                    <div class="flex items-center gap-2">
                      <ElTag size="small" type="info">
                        #{{ seg.position }}
                      </ElTag>
                      <span
                        v-if="seg.document_name"
                        class="text-muted-foreground text-xs"
                      >
                        {{ seg.document_name }}
                      </span>
                    </div>
                    <div class="flex items-center gap-1">
                      <ElTag
                        size="small"
                        :type="
                          seg.embedding_status === 'completed'
                            ? 'success'
                            : seg.embedding_status === 'failed'
                              ? 'danger'
                              : ('info' as any)
                        "
                      >
                        {{ seg.embedding_status }}
                      </ElTag>
                      <ElButton
                        text
                        size="small"
                        @click="handleEditSegment(seg)"
                      >
                        <Edit class="h-3.5 w-3.5" />
                      </ElButton>
                      <ElButton
                        text
                        size="small"
                        @click="handleDeleteSegment(seg)"
                      >
                        <Trash2 class="h-3.5 w-3.5" />
                      </ElButton>
                    </div>
                  </div>
                  <div
                    class="text-foreground line-clamp-4 text-sm leading-relaxed"
                  >
                    {{ seg.content }}
                  </div>
                  <div
                    v-if="seg.answer"
                    class="bg-muted mt-2 rounded p-2 text-xs"
                  >
                    <span class="text-muted-foreground font-medium">A: </span>
                    <span class="line-clamp-2">{{ seg.answer }}</span>
                  </div>
                  <div
                    class="text-muted-foreground mt-2 flex flex-wrap gap-3 text-xs"
                  >
                    <span>{{ seg.char_count }} chars</span>
                    <span>{{ seg.token_count }} tokens</span>
                    <span v-if="seg.word_count"
                      >{{ seg.word_count }} words</span
                    >
                    <span v-if="seg.page_number">P{{ seg.page_number }}</span>
                    <span>
                      {{ $t('ai-platform.knowledge.retrieval.score') }}:
                      {{ seg.hit_count }}
                    </span>
                  </div>
                  <div
                    v-if="seg.keywords && seg.keywords.length > 0"
                    class="mt-1 flex flex-wrap gap-1"
                  >
                    <ElTag
                      v-for="kw in seg.keywords.slice(0, 5)"
                      :key="kw"
                      size="small"
                      type="info"
                    >
                      {{ kw }}
                    </ElTag>
                  </div>
                  <div
                    v-if="
                      seg.extra_metadata &&
                      Object.keys(seg.extra_metadata).length > 0
                    "
                    class="mt-1 flex flex-wrap items-center gap-1"
                  >
                    <ElTag
                      v-for="(val, key) in seg.extra_metadata"
                      :key="String(key)"
                      size="small"
                      type="warning"
                      class="cursor-pointer"
                      @click="handleEditMetadata(seg)"
                    >
                      {{ key }}: {{ val }}
                    </ElTag>
                  </div>
                  <div v-else class="mt-1">
                    <ElButton
                      text
                      size="small"
                      type="primary"
                      @click="handleEditMetadata(seg)"
                    >
                      <Plus class="mr-1 h-3 w-3" />
                      {{ $t('ai-platform.knowledge.metadata.add') }}
                    </ElButton>
                  </div>
                </ElCard>
              </div>
              <ElEmpty v-else :description="$t('common.noData')" />
            </div>

            <div
              v-if="segPagination.total > segPagination.pageSize"
              class="mt-4 flex justify-end"
            >
              <ElPagination
                v-model:current-page="segPagination.current"
                v-model:page-size="segPagination.pageSize"
                :total="segPagination.total"
                layout="total, prev, pager, next"
                background
                size="small"
                @current-change="fetchSegments"
              />
            </div>
          </div>

          <!-- 召回测试 Tab -->
          <div v-if="activeTab === 'retrieval'">
            <div class="mb-4 flex flex-col gap-2">
              <div class="flex items-center gap-2">
                <ElInput
                  v-model="retrievalQuery"
                  :placeholder="
                    $t('ai-platform.knowledge.retrieval.queryPlaceholder')
                  "
                  clearable
                  class="flex-1"
                  @keyup.enter="handleRetrieve"
                />
                <ElButton
                  type="primary"
                  :loading="retrievalLoading"
                  @click="handleRetrieve"
                >
                  {{ $t('ai-platform.knowledge.retrieval.test') }}
                </ElButton>
              </div>
              <div
                v-if="retrievalMetadataFilters.length > 0"
                class="flex flex-col gap-1"
              >
                <div
                  v-for="(filter, idx) in retrievalMetadataFilters"
                  :key="idx"
                  class="flex items-center gap-2"
                >
                  <ElInput
                    v-model="filter.key"
                    :placeholder="$t('ai-platform.knowledge.metadata.key')"
                    size="small"
                    class="w-40"
                  />
                  <ElInput
                    v-model="filter.value"
                    :placeholder="$t('ai-platform.knowledge.metadata.value')"
                    size="small"
                    class="w-40"
                  />
                  <ElButton
                    text
                    size="small"
                    type="danger"
                    @click="removeRetrievalMetadataFilter(idx)"
                  >
                    <Minus class="h-3.5 w-3.5" />
                  </ElButton>
                </div>
              </div>
              <div>
                <ElButton
                  text
                  size="small"
                  type="primary"
                  @click="addRetrievalMetadataFilter"
                >
                  <Plus class="mr-1 h-3 w-3" />
                  {{ $t('ai-platform.knowledge.metadata.addFilter') }}
                </ElButton>
              </div>
            </div>

            <div v-if="retrievalResults.length > 0">
              <div class="mb-3 flex items-center gap-2 text-sm">
                <span class="text-muted-foreground">
                  {{ $t('ai-platform.knowledge.retrieval.results') }}:
                  {{ retrievalResults.length }}
                  &nbsp;|&nbsp;
                  {{ $t('ai-platform.knowledge.retrieval.elapsed') }}:
                  {{ retrievalElapsed }}ms
                </span>
                <ElTag v-if="retrievalMode" size="small" type="info">
                  {{ retrievalMode }}
                </ElTag>
                <ElTag v-if="rerankApplied" size="small" type="warning">
                  Rerank
                </ElTag>
              </div>
              <div class="flex flex-col gap-2">
                <ElCard
                  v-for="(result, idx) in retrievalResults"
                  :key="result.segment_id"
                  shadow="never"
                  :body-style="{ padding: '12px 16px' }"
                >
                  <div class="mb-2 flex items-center justify-between">
                    <div class="flex items-center gap-2">
                      <ElTag size="small" type="primary">
                        #{{ idx + 1 }}
                      </ElTag>
                      <span class="text-sm font-medium">
                        {{ result.document_name }}
                      </span>
                    </div>
                    <div class="flex items-center gap-2">
                      <ElTag
                        v-if="result.match_source"
                        size="small"
                        :type="getMatchSourceType(result.match_source) as any"
                      >
                        {{
                          $t(
                            `ai-platform.knowledge.retrieval.matchSource.${result.match_source}`,
                          )
                        }}
                      </ElTag>
                      <ElTag size="small" type="success">
                        {{ $t('ai-platform.knowledge.retrieval.score') }}:
                        {{ (result.score * 100).toFixed(1) }}%
                      </ElTag>
                    </div>
                  </div>
                  <div class="text-foreground text-sm leading-relaxed">
                    {{ result.content }}
                  </div>
                  <div v-if="result.parent_content" class="mt-2">
                    <ElButton
                      text
                      size="small"
                      type="primary"
                      @click="toggleParentContent(result.segment_id)"
                    >
                      {{
                        expandedParentIds.has(result.segment_id)
                          ? $t('ai-platform.knowledge.retrieval.hideParent')
                          : $t('ai-platform.knowledge.retrieval.showParent')
                      }}
                    </ElButton>
                    <div
                      v-if="expandedParentIds.has(result.segment_id)"
                      class="bg-muted mt-2 rounded p-3 text-sm leading-relaxed"
                    >
                      {{ result.parent_content }}
                    </div>
                  </div>
                </ElCard>
              </div>
            </div>
            <ElEmpty
              v-else-if="!retrievalLoading"
              :description="$t('ai-platform.knowledge.retrieval.noResults')"
            />
          </div>

          <!-- 标注管理 Tab -->
          <div v-if="activeTab === 'annotations'">
            <div class="mb-4 flex items-center justify-between">
              <div class="flex items-center gap-2">
                <ElInput
                  v-model="annotationSearch"
                  :placeholder="
                    $t('ai-platform.knowledge.annotation.searchPlaceholder')
                  "
                  clearable
                  class="w-64"
                  @keyup.enter="fetchAnnotations"
                >
                  <template #prefix>
                    <Search class="h-4 w-4" />
                  </template>
                </ElInput>
              </div>
              <div class="flex items-center gap-2">
                <ElButton size="small" @click="handleReindexAnnotations">
                  <RefreshCw class="mr-1 h-3.5 w-3.5" />
                  {{ $t('ai-platform.knowledge.annotation.reindex') }}
                </ElButton>
                <ElButton
                  type="primary"
                  size="small"
                  @click="handleAddAnnotation"
                >
                  <Plus class="mr-1 h-3.5 w-3.5" />
                  {{ $t('ai-platform.knowledge.annotation.add') }}
                </ElButton>
              </div>
            </div>

            <div v-loading="annotationLoading">
              <div v-if="annotationList.length > 0" class="flex flex-col gap-2">
                <ElCard
                  v-for="ann in annotationList"
                  :key="ann.id"
                  shadow="never"
                  :body-style="{ padding: '12px 16px' }"
                >
                  <div class="mb-2 flex items-center justify-between">
                    <div class="flex items-center gap-2">
                      <ElTag size="small" type="primary">Q</ElTag>
                      <span class="text-sm font-medium">{{
                        ann.question
                      }}</span>
                    </div>
                    <div class="flex items-center gap-1">
                      <ElTag
                        size="small"
                        :type="
                          ann.embedding_status === 'completed'
                            ? 'success'
                            : ann.embedding_status === 'failed'
                              ? 'danger'
                              : 'warning'
                        "
                      >
                        {{
                          ann.embedding_status === 'completed'
                            ? $t(
                                'ai-platform.knowledge.segment.embeddingCompleted',
                              )
                            : ann.embedding_status === 'failed'
                              ? $t(
                                  'ai-platform.knowledge.segment.embeddingFailed',
                                )
                              : $t(
                                  'ai-platform.knowledge.annotation.vectorizing',
                                )
                        }}
                      </ElTag>
                      <ElTag size="small" type="info">
                        {{ $t('ai-platform.knowledge.annotation.hitCount') }}:
                        {{ ann.hit_count }}
                      </ElTag>
                      <ElButton
                        text
                        size="small"
                        @click="handleEditAnnotation(ann)"
                      >
                        <Edit class="h-3.5 w-3.5" />
                      </ElButton>
                      <ElButton
                        text
                        size="small"
                        @click="handleDeleteAnnotation(ann)"
                      >
                        <Trash2 class="h-3.5 w-3.5" />
                      </ElButton>
                    </div>
                  </div>
                  <div class="bg-muted rounded p-2 text-sm">
                    <span class="text-muted-foreground font-medium">A: </span>
                    {{ ann.answer }}
                  </div>
                </ElCard>
              </div>
              <ElEmpty v-else :description="$t('common.noData')" />
            </div>

            <div
              v-if="annotationPagination.total > annotationPagination.pageSize"
              class="mt-4 flex justify-end"
            >
              <ElPagination
                v-model:current-page="annotationPagination.current"
                v-model:page-size="annotationPagination.pageSize"
                :total="annotationPagination.total"
                layout="total, prev, pager, next"
                background
                size="small"
                @current-change="fetchAnnotations"
              />
            </div>
          </div>

          <!-- 命中统计 Tab -->
          <div v-if="activeTab === 'hitStats'">
            <div class="mb-4 flex items-center gap-4">
              <ElSwitch v-model="hitStatsIncludeZero" @change="fetchHitStats" />
              <span class="text-sm">{{
                $t('ai-platform.knowledge.hitStats.includeZero')
              }}</span>
            </div>

            <div v-loading="hitStatsLoading">
              <div v-if="hitStatsData" class="mb-6 grid grid-cols-3 gap-4">
                <ElCard shadow="never" :body-style="{ padding: '16px' }">
                  <div class="text-muted-foreground text-xs">
                    {{ $t('ai-platform.knowledge.hitStats.totalHits') }}
                  </div>
                  <div class="mt-1 text-2xl font-bold">
                    {{ hitStatsData.total_hits }}
                  </div>
                </ElCard>
                <ElCard shadow="never" :body-style="{ padding: '16px' }">
                  <div class="text-muted-foreground text-xs">
                    {{ $t('ai-platform.knowledge.hitStats.totalSegments') }}
                  </div>
                  <div class="mt-1 text-2xl font-bold">
                    {{ hitStatsData.total_segments }}
                  </div>
                </ElCard>
                <ElCard shadow="never" :body-style="{ padding: '16px' }">
                  <div class="text-muted-foreground text-xs">
                    {{ $t('ai-platform.knowledge.hitStats.zeroHitCount') }}
                  </div>
                  <div class="mt-1 text-2xl font-bold">
                    {{ hitStatsData.zero_hit_count }}
                  </div>
                </ElCard>
              </div>

              <div
                v-if="hitStatsData && hitStatsData.items.length > 0"
                class="flex flex-col gap-2"
              >
                <div
                  v-for="item in hitStatsData.items"
                  :key="item.segment_id"
                  class="flex items-center gap-3 rounded-lg border p-3"
                >
                  <div class="min-w-0 flex-1">
                    <div class="flex items-center gap-2">
                      <ElTag size="small" type="info">
                        #{{ item.position }}
                      </ElTag>
                      <span class="text-muted-foreground text-xs">{{
                        item.document_name
                      }}</span>
                    </div>
                    <div class="mt-1 line-clamp-1 text-sm">
                      {{ item.content_preview }}
                    </div>
                  </div>
                  <div class="flex flex-shrink-0 items-center gap-3">
                    <div class="w-32">
                      <div class="bg-muted h-2 overflow-hidden rounded-full">
                        <div
                          class="bg-primary h-full rounded-full transition-all"
                          :style="{ width: getHitBarWidth(item) }"
                        ></div>
                      </div>
                    </div>
                    <div class="w-16 text-right text-sm font-medium">
                      {{ item.hit_count }}
                    </div>
                    <div class="text-muted-foreground w-16 text-right text-xs">
                      {{ item.hit_percentage.toFixed(1) }}%
                    </div>
                  </div>
                </div>
              </div>
              <ElEmpty
                v-else-if="!hitStatsLoading"
                :description="$t('ai-platform.knowledge.hitStats.noData')"
              />
            </div>
          </div>

          <!-- 检索日志 Tab -->
          <div v-if="activeTab === 'retrievalLogs'">
            <div class="mb-4 flex items-center gap-2">
              <ElInput
                v-model="logSearch"
                :placeholder="
                  $t('ai-platform.knowledge.retrievalLog.searchPlaceholder')
                "
                clearable
                class="w-64"
                @keyup.enter="fetchRetrievalLogs"
              >
                <template #prefix>
                  <Search class="h-4 w-4" />
                </template>
              </ElInput>
            </div>

            <div v-loading="logLoading">
              <div v-if="logList.length > 0" class="flex flex-col gap-2">
                <ElCard
                  v-for="log in logList"
                  :key="log.id"
                  shadow="never"
                  :body-style="{ padding: '12px 16px' }"
                >
                  <div class="flex items-center justify-between">
                    <div class="min-w-0 flex-1">
                      <div class="truncate text-sm font-medium">
                        {{ log.query }}
                      </div>
                      <div
                        class="text-muted-foreground mt-1 flex gap-3 text-xs"
                      >
                        <span>
                          {{
                            $t(
                              'ai-platform.knowledge.retrievalLog.resultCount',
                            )
                          }}: {{ log.result_count }}
                        </span>
                        <span>
                          {{
                            $t('ai-platform.knowledge.retrievalLog.elapsed')
                          }}: {{ log.elapsed_time }}ms
                        </span>
                        <span>{{ log.retrieval_mode }}</span>
                        <span v-if="log.rerank_applied === 'true'">
                          <ElTag size="small" type="warning">Rerank</ElTag>
                        </span>
                        <span>
                          <ElTag
                            size="small"
                            :type="
                              log.source === 'agent' ||
                              log.source === 'agent_annotation'
                                ? 'primary'
                                : 'info'
                            "
                          >
                            {{
                              log.source === 'agent'
                                ? $t(
                                    'ai-platform.knowledge.retrievalLog.sourceAgent',
                                  )
                                : log.source === 'agent_annotation'
                                  ? $t(
                                      'ai-platform.knowledge.retrievalLog.sourceAnnotation',
                                    )
                                  : $t(
                                      'ai-platform.knowledge.retrievalLog.sourceApi',
                                    )
                            }}
                          </ElTag>
                        </span>
                      </div>
                    </div>
                    <span
                      class="text-muted-foreground ml-4 flex-shrink-0 text-xs"
                    >
                      {{ log.sys_create_datetime }}
                    </span>
                  </div>
                </ElCard>
              </div>
              <ElEmpty
                v-else
                :description="$t('ai-platform.knowledge.retrievalLog.noData')"
              />
            </div>

            <div
              v-if="logPagination.total > logPagination.pageSize"
              class="mt-4 flex justify-end"
            >
              <ElPagination
                v-model:current-page="logPagination.current"
                v-model:page-size="logPagination.pageSize"
                :total="logPagination.total"
                layout="total, prev, pager, next"
                background
                size="small"
                @current-change="fetchRetrievalLogs"
              />
            </div>
          </div>

          <!-- 设置 Tab -->
          <div v-if="activeTab === 'settings'">
            <div class="mx-auto max-w-2xl">
              <ElForm label-position="top">
                <h3 class="mb-4 text-base font-medium">
                  {{ $t('ai-platform.knowledge.settings.basic') }}
                </h3>
                <ElFormItem :label="$t('ai-platform.knowledge.name')">
                  <ElInput v-model="settingsForm.name" />
                </ElFormItem>
                <ElFormItem :label="$t('ai-platform.knowledge.description')">
                  <ElInput
                    v-model="settingsForm.description"
                    type="textarea"
                    :rows="3"
                  />
                </ElFormItem>

                <h3 class="mb-4 mt-6 text-base font-medium">
                  {{ $t('ai-platform.knowledge.settings.indexing') }}
                </h3>
                <ElFormItem>
                  <template #label>
                    <div class="flex items-center gap-1">
                      <span>{{
                        $t('ai-platform.knowledge.embeddingModel')
                      }}</span>
                      <ElTooltip
                        placement="top"
                        :content="
                          $t(
                            'ai-platform.knowledge.embeddingModelSettingsTooltip',
                          )
                        "
                      >
                        <CircleHelp
                          class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                        />
                      </ElTooltip>
                    </div>
                  </template>
                  <ElSelect
                    v-model="settingsForm.embedding_model_id"
                    style="width: 100%"
                    clearable
                  >
                    <ElOption
                      v-for="model in embeddingModels"
                      :key="model.id"
                      :label="model.display_name"
                      :value="model.id"
                    />
                  </ElSelect>
                </ElFormItem>
                <div class="grid grid-cols-2 gap-4">
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{
                          $t('ai-platform.knowledge.indexingTechnique')
                        }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t('ai-platform.knowledge.indexingTechniqueTooltip')
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElSelect
                      v-model="settingsForm.indexing_technique"
                      style="width: 100%"
                    >
                      <ElOption
                        :label="
                          $t(
                            'ai-platform.knowledge.indexingTechniques.high_quality',
                          )
                        "
                        value="high_quality"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.indexingTechniques.economy')
                        "
                        value="economy"
                      />
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{
                          $t('ai-platform.knowledge.dimensions')
                        }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t('ai-platform.knowledge.dimensionsTooltip')
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElInputNumber
                      v-model="settingsForm.embedding_dimensions"
                      :min="128"
                      :max="4096"
                      style="width: 100%"
                    />
                  </ElFormItem>
                </div>
                <div class="grid grid-cols-2 gap-4">
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{
                          $t('ai-platform.knowledge.chunkStrategy')
                        }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t(
                              'ai-platform.knowledge.chunkStrategySettingsTooltip',
                            )
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElSelect
                      v-model="settingsForm.chunk_strategy"
                      style="width: 100%"
                    >
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.chunkStrategies.auto')
                        "
                        value="auto"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.chunkStrategies.recursive')
                        "
                        value="recursive"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.chunkStrategies.markdown')
                        "
                        value="markdown"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.chunkStrategies.fixed')
                        "
                        value="fixed"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.chunkStrategies.sentence')
                        "
                        value="sentence"
                      />
                      <ElOption
                        :label="$t('ai-platform.knowledge.chunkStrategies.qa')"
                        value="qa"
                      />
                    </ElSelect>
                  </ElFormItem>
                </div>
                <div class="grid grid-cols-2 gap-4">
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{ $t('ai-platform.knowledge.chunkSize') }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t('ai-platform.knowledge.chunkSizeSettingsTooltip')
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElInputNumber
                      v-model="settingsForm.chunk_size"
                      :min="100"
                      :max="4000"
                      :step="100"
                      style="width: 100%"
                    />
                  </ElFormItem>
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{
                          $t('ai-platform.knowledge.chunkOverlap')
                        }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t(
                              'ai-platform.knowledge.chunkOverlapSettingsTooltip',
                            )
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElInputNumber
                      v-model="settingsForm.chunk_overlap"
                      :min="0"
                      :max="500"
                      :step="10"
                      style="width: 100%"
                    />
                  </ElFormItem>
                </div>

                <h3 class="mb-4 mt-6 text-base font-medium">
                  {{ $t('ai-platform.knowledge.settings.retrieval') }}
                </h3>
                <div class="grid grid-cols-2 gap-4">
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{
                          $t('ai-platform.knowledge.retrievalMode')
                        }}</span>
                        <ElTooltip
                          placement="top"
                          :content="
                            $t('ai-platform.knowledge.retrievalModeTooltip')
                          "
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElSelect
                      v-model="settingsForm.retrieval_mode"
                      style="width: 100%"
                    >
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.retrievalModes.hybrid')
                        "
                        value="hybrid"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.retrievalModes.vector')
                        "
                        value="vector"
                      />
                      <ElOption
                        :label="
                          $t('ai-platform.knowledge.retrievalModes.fulltext')
                        "
                        value="fulltext"
                      />
                    </ElSelect>
                  </ElFormItem>
                  <ElFormItem>
                    <template #label>
                      <div class="flex items-center gap-1">
                        <span>{{ $t('ai-platform.knowledge.topK') }}</span>
                        <ElTooltip
                          placement="top"
                          :content="$t('ai-platform.knowledge.topKTooltip')"
                        >
                          <CircleHelp
                            class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                          />
                        </ElTooltip>
                      </div>
                    </template>
                    <ElInputNumber
                      v-model="settingsForm.top_k"
                      :min="1"
                      :max="20"
                      style="width: 100%"
                    />
                  </ElFormItem>
                </div>
                <ElFormItem>
                  <template #label>
                    <div class="flex items-center gap-1">
                      <span>{{
                        $t('ai-platform.knowledge.scoreThreshold')
                      }}</span>
                      <ElTooltip
                        placement="top"
                        :content="
                          $t('ai-platform.knowledge.scoreThresholdTooltip')
                        "
                      >
                        <CircleHelp
                          class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                        />
                      </ElTooltip>
                    </div>
                  </template>
                  <ElSlider
                    v-model="settingsForm.score_threshold"
                    :min="0"
                    :max="1"
                    :step="0.05"
                    show-input
                  />
                </ElFormItem>
                <ElFormItem>
                  <template #label>
                    <div class="flex items-center gap-1">
                      <span>{{ $t('ai-platform.knowledge.rerank') }}</span>
                      <ElTooltip
                        placement="top"
                        :content="$t('ai-platform.knowledge.rerankTooltip')"
                      >
                        <CircleHelp
                          class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                        />
                      </ElTooltip>
                    </div>
                  </template>
                  <ElSwitch v-model="settingsForm.rerank_enabled" />
                </ElFormItem>
                <ElFormItem
                  v-if="settingsForm.rerank_enabled"
                  :label="$t('ai-platform.knowledgeNode.rerankModel')"
                >
                  <ElSelect
                    v-model="settingsForm.rerank_model_id"
                    style="width: 100%"
                    clearable
                    :placeholder="$t('ai-platform.knowledgeNode.rerankModel')"
                  >
                    <ElOption
                      v-for="model in rerankModels"
                      :key="model.id"
                      :label="model.display_name"
                      :value="model.id"
                    />
                  </ElSelect>
                  <div
                    v-if="rerankModels.length === 0"
                    class="text-warning mt-1 text-xs"
                  >
                    {{ $t('ai-platform.knowledgeNode.noRerankModel') }}
                  </div>
                </ElFormItem>

                <h3 class="mb-4 mt-6 text-base font-medium">
                  {{ $t('ai-platform.knowledge.settings.advanced') }}
                </h3>
                <ElFormItem>
                  <template #label>
                    <div class="flex items-center gap-1">
                      <span>{{
                        $t('ai-platform.knowledge.retrievalWeight')
                      }}</span>
                      <ElTooltip
                        placement="top"
                        :content="
                          $t('ai-platform.knowledge.retrievalWeightTooltip')
                        "
                      >
                        <CircleHelp
                          class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                        />
                      </ElTooltip>
                    </div>
                  </template>
                  <ElInputNumber
                    v-model="settingsForm.retrieval_weight"
                    :min="0.1"
                    :max="10"
                    :step="0.1"
                    :precision="1"
                    style="width: 100%"
                  />
                </ElFormItem>
                <ElFormItem>
                  <template #label>
                    <div class="flex items-center gap-1">
                      <span>{{
                        $t('ai-platform.knowledge.processRules')
                      }}</span>
                      <ElTooltip
                        placement="top"
                        :content="
                          $t('ai-platform.knowledge.processRulesTooltip')
                        "
                      >
                        <CircleHelp
                          class="text-muted-foreground h-3.5 w-3.5 cursor-help"
                        />
                      </ElTooltip>
                    </div>
                  </template>
                  <div class="flex flex-col gap-2">
                    <div class="flex items-center gap-2">
                      <ElSwitch
                        v-model="
                          settingsForm.process_rules!.remove_extra_spaces
                        "
                      />
                      <span class="text-sm">{{
                        $t('ai-platform.knowledge.removeExtraSpaces')
                      }}</span>
                    </div>
                    <div class="flex items-center gap-2">
                      <ElSwitch
                        v-model="settingsForm.process_rules!.remove_urls_emails"
                      />
                      <span class="text-sm">{{
                        $t('ai-platform.knowledge.removeUrlsEmails')
                      }}</span>
                    </div>
                  </div>
                </ElFormItem>

                <div class="mt-6 flex justify-end">
                  <ElButton
                    type="primary"
                    :loading="settingsLoading"
                    @click="handleSaveSettings"
                  >
                    {{ $t('common.save') }}
                  </ElButton>
                </div>
              </ElForm>
            </div>
          </div>
        </ElScrollbar>
      </div>
    </Page>

    <!-- 添加文档（隐藏的 FileSelector） -->
    <FileSelector
      ref="fileSelectorRef"
      v-model="addDocFileIds"
      trigger="button"
      multiple
      :accept="[
        '.pdf',
        '.docx',
        '.doc',
        '.txt',
        '.md',
        '.xlsx',
        '.csv',
        '.html',
        '.pptx',
      ]"
      @change="handleAddDocChange"
    />

    <!-- 分块预览弹窗 -->
    <ZqDialog
      v-model="chunkPreviewDialogVisible"
      :title="`${$t('ai-platform.knowledge.chunkPreview.title')} - ${chunkPreviewDocName}`"
      width="800px"
      :show-footer="false"
    >
      <div v-loading="chunkPreviewLoading" class="min-h-[560px]">
        <div v-if="chunkPreviewTotal > 0" class="mb-3 text-sm">
          <span class="text-muted-foreground">
            {{ $t('ai-platform.knowledge.chunkPreview.totalChunks') }}:
            {{ chunkPreviewTotal }}
          </span>
        </div>
        <ElScrollbar max-height="500px">
          <div
            v-if="chunkPreviewResults.length > 0"
            class="flex flex-col gap-2"
          >
            <ElCard
              v-for="chunk in chunkPreviewResults"
              :key="chunk.position"
              shadow="never"
              :body-style="{ padding: '12px 16px' }"
            >
              <div class="mb-2 flex items-center justify-between">
                <ElTag size="small" type="info">
                  #{{ chunk.position + 1 }}
                </ElTag>
                <div class="text-muted-foreground flex gap-3 text-xs">
                  <span>{{ chunk.char_count }} chars</span>
                  <span>{{ chunk.token_count }} tokens</span>
                  <span>{{ chunk.word_count }} words</span>
                </div>
              </div>
              <div
                class="text-foreground whitespace-pre-wrap text-sm leading-relaxed"
              >
                {{ chunk.content }}
              </div>
              <div
                v-if="chunk.answer"
                class="bg-muted mt-2 rounded p-2 text-xs"
              >
                <span class="text-muted-foreground font-medium">A: </span>
                <span>{{ chunk.answer }}</span>
              </div>
            </ElCard>
          </div>
          <ElEmpty
            v-else-if="!chunkPreviewLoading"
            :description="$t('ai-platform.knowledge.chunkPreview.loading')"
          />
        </ElScrollbar>
      </div>
    </ZqDialog>

    <!-- 编辑分段弹窗 -->
    <ZqDialog
      v-model="editSegDialogVisible"
      :title="$t('ai-platform.knowledge.segment.edit')"
      width="600px"
      @confirm="handleSaveSegment"
    >
      <ElForm label-position="top">
        <ElFormItem :label="$t('ai-platform.knowledge.segment.content')">
          <ElInput
            v-model="editSegForm.content"
            type="textarea"
            :rows="8"
            :placeholder="
              $t('ai-platform.knowledge.segment.contentPlaceholder')
            "
          />
        </ElFormItem>
        <ElFormItem label="">
          <ElSwitch v-model="editSegForm.enabled" />
          <span class="ml-2 text-sm">
            {{
              editSegForm.enabled
                ? $t('ai-platform.knowledge.segment.enabled')
                : $t('ai-platform.knowledge.segment.disabled')
            }}
          </span>
        </ElFormItem>
      </ElForm>
    </ZqDialog>

    <!-- 编辑元数据弹窗 -->
    <ZqDialog
      v-model="metadataEditDialogVisible"
      :title="$t('ai-platform.knowledge.metadata.editTitle')"
      width="560px"
      @confirm="handleSaveMetadata"
    >
      <div class="flex flex-col gap-2">
        <div
          v-for="(pair, idx) in metadataEditPairs"
          :key="idx"
          class="flex items-center gap-2"
        >
          <ElInput
            v-model="pair.key"
            :placeholder="$t('ai-platform.knowledge.metadata.key')"
            size="small"
            class="flex-1"
          />
          <ElInput
            v-model="pair.value"
            :placeholder="$t('ai-platform.knowledge.metadata.value')"
            size="small"
            class="flex-1"
          />
          <ElButton
            text
            size="small"
            type="danger"
            @click="removeMetadataPair(idx)"
          >
            <Minus class="h-3.5 w-3.5" />
          </ElButton>
        </div>
        <div>
          <ElButton text size="small" type="primary" @click="addMetadataPair">
            <Plus class="mr-1 h-3 w-3" />
            {{ $t('ai-platform.knowledge.metadata.addPair') }}
          </ElButton>
        </div>
      </div>
    </ZqDialog>

    <!-- 添加标注弹窗 -->
    <ZqDialog
      v-model="addAnnotationDialogVisible"
      :title="$t('ai-platform.knowledge.annotation.add')"
      width="560px"
      @confirm="handleSaveAnnotation"
    >
      <ElForm label-position="top">
        <ElFormItem :label="$t('ai-platform.knowledge.annotation.question')">
          <ElInput
            v-model="annotationForm.question"
            type="textarea"
            :rows="3"
            :placeholder="
              $t('ai-platform.knowledge.annotation.questionPlaceholder')
            "
          />
        </ElFormItem>
        <ElFormItem :label="$t('ai-platform.knowledge.annotation.answer')">
          <ElInput
            v-model="annotationForm.answer"
            type="textarea"
            :rows="5"
            :placeholder="
              $t('ai-platform.knowledge.annotation.answerPlaceholder')
            "
          />
        </ElFormItem>
      </ElForm>
    </ZqDialog>

    <!-- 编辑标注弹窗 -->
    <ZqDialog
      v-model="editAnnotationDialogVisible"
      :title="$t('ai-platform.knowledge.annotation.edit')"
      width="560px"
      @confirm="handleSaveAnnotation"
    >
      <ElForm label-position="top">
        <ElFormItem :label="$t('ai-platform.knowledge.annotation.question')">
          <ElInput
            v-model="annotationForm.question"
            type="textarea"
            :rows="3"
            :placeholder="
              $t('ai-platform.knowledge.annotation.questionPlaceholder')
            "
          />
        </ElFormItem>
        <ElFormItem :label="$t('ai-platform.knowledge.annotation.answer')">
          <ElInput
            v-model="annotationForm.answer"
            type="textarea"
            :rows="5"
            :placeholder="
              $t('ai-platform.knowledge.annotation.answerPlaceholder')
            "
          />
        </ElFormItem>
        <ElFormItem label="">
          <ElSwitch v-model="annotationForm.enabled" />
          <span class="ml-2 text-sm">
            {{
              annotationForm.enabled
                ? $t('ai-platform.knowledge.annotation.enabled')
                : $t('ai-platform.knowledge.annotation.disabled')
            }}
          </span>
        </ElFormItem>
      </ElForm>
    </ZqDialog>

    <!-- 文档图片预览 -->
    <ElImageViewer
      v-if="docPreviewVisible"
      :url-list="docPreviewUrlList"
      :initial-index="0"
      @close="docPreviewVisible = false"
    />
  </div>
</template>
