<template>
  <div class="database-info-container extension-detail-page">
    <FileDetailModal />

    <FileUploadModal
      v-model:visible="addFilesModalVisible"
      :folder-tree="folderTree"
      :current-folder-id="currentFolderId"
      :is-folder-mode="isFolderUploadMode"
      :mode="addFilesMode"
      @success="onFileUploadSuccess"
    />

    <div class="detail-top-bar">
      <button class="detail-back-btn" type="button" @click="backToDatabase">
        <ArrowLeft :size="16" />
        <span>返回</span>
      </button>
      <div class="detail-title-area">
        <div class="detail-icon">
          <component :is="kbTypeIcon" :size="18" />
        </div>
        <div class="detail-title-text">
          <h2>{{ database.name || '知识库加载中' }}</h2>
          <span class="detail-subtitle">{{ databaseSubtitle }}</span>
        </div>
      </div>
      <div class="detail-actions">
        <a-space :size="8">
          <button
            type="button"
            class="lucide-icon-btn extension-panel-action extension-panel-action-secondary"
            @click="copyDatabaseId"
          >
            <Copy :size="14" />
            <span>复制 ID</span>
          </button>
          <button
            type="button"
            class="lucide-icon-btn extension-panel-action extension-panel-action-primary"
            @click="showEditModal"
          >
            <Pencil :size="14" />
            <span>编辑</span>
          </button>
        </a-space>
      </div>
    </div>

    <div class="database-detail-body">
      <div class="database-tab-bar" aria-label="知识库功能导航">
        <nav class="database-tab-list" aria-label="知识库功能标签" role="tablist">
          <button
            v-for="tab in visibleTabs"
            :key="tab.key"
            type="button"
            class="database-tab-item"
            :class="{ active: activeTab === tab.key }"
            role="tab"
            :aria-selected="activeTab === tab.key"
            @click="activeTab = tab.key"
          >
            <component :is="tab.icon" :size="17" />
            <span>{{ tab.label }}</span>
          </button>
        </nav>
      </div>

      <main class="database-tab-content">
        <div v-if="isMilvus" v-show="activeTab === 'filetable'" class="tab-panel file-panel">
          <div class="file-management-info">
            <div class="file-info-title">
              <div class="file-info-title-row">
                <button
                  type="button"
                  class="lucide-icon-btn extension-panel-action extension-panel-action-primary"
                  @click="showAddFilesModal()"
                >
                  <FileUp :size="14" />
                  <span>上传</span>
                </button>
                <button
                  type="button"
                  class="lucide-icon-btn extension-panel-action extension-panel-action-secondary"
                  @click="showCreateFolderModal"
                >
                  <FolderPlus :size="14" />
                  <span>新建文件夹</span>
                </button>
              </div>
            </div>
            <div class="file-panel-status">
              <div
                v-if="pendingParseCount > 0"
                class="file-stat-card file-stat-action"
                @click="confirmBatchParse"
              >
                <FileText :size="20" />
                <div>
                  <strong>{{ pendingParseCount }}</strong>
                  <span>待解析</span>
                </div>
              </div>
              <div
                v-if="pendingIndexCount > 0"
                class="file-stat-card file-stat-action"
                @click="confirmBatchIndex"
              >
                <DatabaseIcon :size="20" />
                <div>
                  <strong>{{ pendingIndexCount }}</strong>
                  <span>待入库</span>
                </div>
              </div>
              <div class="file-stat-card">
                <FileText :size="20" />
                <div>
                  <strong>{{ fileStats.count }}</strong>
                  <span>文件总数</span>
                </div>
              </div>
              <div v-if="fileStats.sizeText" class="file-stat-card">
                <DatabaseIcon :size="20" />
                <div>
                  <strong>{{ fileStats.sizeText }}</strong>
                  <span>总大小</span>
                </div>
              </div>
              <div class="file-stat-card">
                <CheckCircle2 :size="20" />
                <div>
                  <strong>{{ fileStats.processedCount }}</strong>
                  <span>已处理</span>
                </div>
              </div>
              <div class="file-stat-card">
                <Activity :size="20" />
                <div>
                  <strong>{{ fileStats.completionRate }}%</strong>
                  <span>完成进度</span>
                </div>
              </div>
            </div>
          </div>
          <FileTable ref="fileTableRef" />
        </div>

        <div v-show="activeTab === 'query'" class="tab-panel query-config-panel">
          <div class="query-config-layout">
            <div class="query-test-pane">
              <QuerySection ref="querySectionRef" :visible="true" @toggle-visible="() => {}" />
            </div>
            <aside class="query-config-pane" aria-label="检索配置">
              <div class="search-config-wrapper">
                <div class="search-config-header">
                  <div>
                    <h3>检索配置</h3>
                    <p>调整当前知识库的检索参数。</p>
                  </div>
                  <button
                    type="button"
                    class="lucide-icon-btn extension-panel-action extension-panel-action-primary"
                    :disabled="searchConfigSaving"
                    @click="handleInlineSearchConfigSave"
                  >
                    <Save :size="14" />
                    <span>保存</span>
                  </button>
                </div>
                <div class="search-config-body">
                  <SearchConfigPanel
                    ref="searchConfigPanelRef"
                    :kb-id="kbId"
                    @save="handleSearchConfigSave"
                  />
                </div>
              </div>
            </aside>
          </div>
        </div>

        <div v-if="isMilvus && activeTab === 'graph'" class="tab-panel">
          <KnowledgeGraphSection
            :visible="true"
            :active="activeTab === 'graph'"
            @toggle-visible="() => {}"
          />
        </div>

        <div v-if="isMilvus && activeTab === 'mindmap'" class="tab-panel">
          <MindMapSection v-if="kbId" :kb-id="kbId" ref="mindmapSectionRef" />
        </div>

        <div v-if="isMilvus && activeTab === 'evaluation'" class="tab-panel">
          <RAGEvaluationTab
            v-if="kbId"
            :kb-id="kbId"
            @switch-to-benchmarks="activeTab = 'benchmarks'"
          />
        </div>

        <div v-if="isMilvus && activeTab === 'benchmarks'" class="tab-panel">
          <div class="benchmark-management-container">
            <div class="benchmark-content">
              <EvaluationBenchmarks
                v-if="kbId && isEvaluationSupported"
                :kb-id="kbId"
                @benchmark-selected="activeTab = 'evaluation'"
              />
            </div>
          </div>
        </div>
      </main>
    </div>

    <a-modal v-model:open="editModalVisible" title="编辑知识库信息" width="700px">
      <template #footer>
        <a-button danger @click="deleteDatabase" style="margin-right: auto; margin-left: 0">
          <template #icon>
            <Trash2 :size="16" style="vertical-align: -3px; margin-right: 4px" />
          </template>
          删除数据库
        </a-button>
        <a-button key="back" @click="editModalVisible = false">取消</a-button>
        <a-button key="submit" type="primary" @click="handleEditSubmit">确定</a-button>
      </template>
      <a-form :model="editForm" :rules="rules" ref="editFormRef" layout="vertical">
        <a-form-item label="知识库名称" name="name" required>
          <a-input v-model:value="editForm.name" placeholder="请输入知识库名称" />
        </a-form-item>
        <a-form-item label="知识库描述" name="description">
          <AiTextarea
            v-model="editForm.description"
            :name="editForm.name"
            :files="fileList"
            placeholder="请输入知识库描述"
            :rows="4"
          />
        </a-form-item>

        <a-form-item v-if="!isConnector" label="自动生成问题" name="auto_generate_questions">
          <a-switch
            v-model:checked="editForm.auto_generate_questions"
            checked-children="开启"
            un-checked-children="关闭"
          />
          <span style="margin-left: 8px; font-size: 12px; color: var(--gray-500)">
            上传文件后自动生成测试问题
          </span>
        </a-form-item>

        <a-form-item v-if="!isConnector" name="chunk_preset_id">
          <template #label>
            <span class="chunk-preset-label">
              分块策略
              <a-tooltip :title="editPresetDescription">
                <QuestionCircleOutlined class="chunk-preset-help-icon" />
              </a-tooltip>
            </span>
          </template>
          <a-select v-model:value="editForm.chunk_preset_id" :options="chunkPresetOptions" />
        </a-form-item>

        <template v-if="isDifyKb">
          <a-form-item label="Dify API URL" name="dify_api_url">
            <a-input
              v-model:value="editForm.dify_api_url"
              placeholder="例如: https://api.dify.ai/v1"
            />
          </a-form-item>
          <a-form-item label="Dify Token" name="dify_token">
            <a-input-password
              v-model:value="editForm.dify_token"
              placeholder="请输入 Dify API Token"
            />
          </a-form-item>
          <a-form-item label="Dataset ID" name="dify_dataset_id">
            <a-input
              v-model:value="editForm.dify_dataset_id"
              placeholder="请输入 Dify dataset_id"
            />
          </a-form-item>
        </template>

        <template v-if="isNotionKb">
          <a-form-item label="Notion Token" name="notion_token">
            <a-input-password
              v-model:value="editForm.notion_token"
              placeholder="留空则保持现有 Token 或使用环境变量"
            />
          </a-form-item>
          <a-form-item label="Data Source ID" name="notion_data_source_id">
            <a-input
              v-model:value="editForm.notion_data_source_id"
              placeholder="请输入 Notion data_source_id"
            />
          </a-form-item>
          <a-form-item label="Notion API Version" name="notion_version">
            <a-input v-model:value="editForm.notion_version" placeholder="2026-03-11" />
          </a-form-item>
        </template>

        <a-form-item v-if="canEditShareConfig" label="共享设置" name="share_config">
          <a-form-item-rest>
            <ShareConfigForm
              ref="shareConfigFormRef"
              :model-value="database.share_config"
              :auto-select-user-dept="true"
            />
          </a-form-item-rest>
        </a-form-item>
        <a-form-item
          v-else-if="database.share_config"
          label="共享设置"
          name="share_config_readonly"
        >
          <div class="share-config-readonly">
            <a-tag :color="shareConfigDisplay.color">
              {{ shareConfigDisplay.label }}
            </a-tag>
            <span class="access-names">{{ shareConfigDisplay.detail }}</span>
          </div>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useDatabaseStore } from '@/stores/database'
import { useTaskerStore } from '@/stores/tasker'
import { useUserStore } from '@/stores/user'
import {
  Activity,
  ArrowLeft,
  BarChart3,
  CheckCircle2,
  ClipboardList,
  Copy,
  Database as DatabaseIcon,
  FileUp,
  FileText,
  FolderPlus,
  Map as MapIcon,
  Network,
  Pencil,
  Save,
  Search,
  Trash2
} from 'lucide-vue-next'
import { QuestionCircleOutlined } from '@ant-design/icons-vue'
import { message, Modal } from 'ant-design-vue'
import FileTable from '@/components/FileTable.vue'
import FileDetailModal from '@/components/FileDetailModal.vue'
import FileUploadModal from '@/components/FileUploadModal.vue'
import KnowledgeGraphSection from '@/components/KnowledgeGraphSection.vue'
import QuerySection from '@/components/QuerySection.vue'
import MindMapSection from '@/components/MindMapSection.vue'
import RAGEvaluationTab from '@/components/RAGEvaluationTab.vue'
import EvaluationBenchmarks from '@/components/EvaluationBenchmarks.vue'
import SearchConfigPanel from '@/components/SearchConfigPanel.vue'
import AiTextarea from '@/components/AiTextarea.vue'
import ShareConfigForm from '@/components/ShareConfigForm.vue'
import { departmentApi } from '@/apis/department_api'
import { authApi } from '@/apis/auth_api'
import { CHUNK_PRESET_OPTIONS, getChunkPresetDescription } from '@/utils/chunk_presets'
import { formatFileSize } from '@/utils/file_utils'
import { getKbTypeIcon, getKbTypeLabel, kbUtils } from '@/utils/kb_utils'

const route = useRoute()
const router = useRouter()
const store = useDatabaseStore()
const taskerStore = useTaskerStore()
const userStore = useUserStore()

const kbId = computed(() => store.kbId)
const database = computed(() => store.database)
const isCurrentDatabaseLoaded = computed(() => database.value?.kb_id === kbId.value)
const kbType = computed(() =>
  isCurrentDatabaseLoaded.value ? database.value.kb_type?.toLowerCase() || 'milvus' : ''
)
const isMilvus = computed(() => kbType.value === 'milvus')
const isDifyKb = computed(() => kbType.value === 'dify')
const isNotionKb = computed(() => kbType.value === 'notion')
const isConnector = computed(
  () => isCurrentDatabaseLoaded.value && kbUtils.isReadOnlyDatabase(database.value)
)
const isEvaluationSupported = computed(() => isMilvus.value)
const kbTypeIcon = computed(() => getKbTypeIcon(kbType.value || 'milvus'))

const databaseSubtitle = computed(() => {
  const typeLabel = getKbTypeLabel(kbType.value || 'milvus')
  if (!isCurrentDatabaseLoaded.value) return '正在加载知识库信息'

  const description = database.value.description?.trim()
  if (description) return description

  if (isConnector.value) return `${typeLabel} 连接器`
  return `${typeLabel} 知识库 · ${database.value.row_count || 0} 文件`
})

const tabs = computed(() => {
  if (isMilvus.value) {
    return [
      { key: 'filetable', label: '文件管理', icon: FileText },
      { key: 'query', label: '检索测试', icon: Search },
      { key: 'graph', label: '知识图谱', icon: Network },
      { key: 'mindmap', label: '知识导图', icon: MapIcon },
      { key: 'evaluation', label: 'RAG 评估', icon: BarChart3 },
      { key: 'benchmarks', label: '评估基准', icon: ClipboardList }
    ]
  }

  return [{ key: 'query', label: '检索测试', icon: Search }]
})

const visibleTabs = computed(() => tabs.value)
const activeTab = ref('filetable')

watch(
  () => [kbId.value, isMilvus.value],
  ([newDbId, isMilvusType]) => {
    if (!newDbId) return
    activeTab.value = isMilvusType ? 'filetable' : 'query'
  },
  { immediate: true }
)

watch(visibleTabs, (nextTabs) => {
  if (!nextTabs.some((tab) => tab.key === activeTab.value)) {
    activeTab.value = nextTabs[0]?.key || 'query'
  }
})

const pendingParseCount = computed(() => {
  const files = store.database.files || {}
  return Object.values(files).filter((f) => !f.is_folder && f.status === 'uploaded').length
})

const fileStats = computed(() => {
  const files = Object.values(store.database.files || {}).filter((file) => !file.is_folder)
  const totalSize = files.reduce((sum, file) => {
    const size = Number(file.file_size ?? file.size ?? 0)
    return Number.isFinite(size) ? sum + size : sum
  }, 0)
  const processedCount = files.filter((file) => ['done', 'indexed'].includes(file.status)).length

  return {
    count: files.length,
    sizeText: totalSize > 0 ? formatFileSize(totalSize) : '',
    processedCount,
    completionRate: files.length ? Math.round((processedCount / files.length) * 100) : 0
  }
})

const pendingIndexCount = computed(() => {
  const files = store.database.files || {}
  return Object.values(files).filter((f) => {
    if (f.is_folder) return false
    return f.status === 'parsed' || f.status === 'error_indexing'
  }).length
})

const confirmBatchParse = () => {
  const fileIds = Object.values(store.database.files || {})
    .filter((f) => f.status === 'uploaded')
    .map((f) => f.file_id)

  if (fileIds.length === 0) return

  Modal.confirm({
    title: '批量解析',
    content: `确定要解析 ${fileIds.length} 个文件吗？`,
    onOk: () => store.parseFiles(fileIds)
  })
}

const confirmBatchIndex = () => {
  const fileIds = Object.values(store.database.files || {})
    .filter((f) => {
      if (f.is_folder) return false
      return f.status === 'parsed' || f.status === 'error_indexing'
    })
    .map((f) => f.file_id)

  if (fileIds.length === 0) return

  Modal.confirm({
    title: '批量入库',
    content: `确定要入库 ${fileIds.length} 个文件吗？`,
    onOk: () => store.indexFiles(fileIds)
  })
}

const mindmapSectionRef = ref(null)
const querySectionRef = ref(null)
const searchConfigSaving = ref(false)
const searchConfigPanelRef = ref(null)

const handleSearchConfigSave = () => {
  store.getDatabaseInfo()
}

const handleInlineSearchConfigSave = async () => {
  if (!searchConfigPanelRef.value) return
  searchConfigSaving.value = true
  try {
    await searchConfigPanelRef.value.save()
  } finally {
    searchConfigSaving.value = false
  }
}

const addFilesModalVisible = ref(false)
const currentFolderId = ref(null)
const isFolderUploadMode = ref(false)
const addFilesMode = ref('file')
const isInitialLoad = ref(true)
const fileTableRef = ref(null)

const showAddFilesModal = (options = {}) => {
  const { isFolder = false, mode = 'file' } = options
  isFolderUploadMode.value = isFolder
  addFilesMode.value = mode
  addFilesModalVisible.value = true
  currentFolderId.value = null
}

const showCreateFolderModal = () => {
  fileTableRef.value?.showCreateFolderModal()
}

const folderTree = computed(() => {
  const files = store.database.files || {}
  const fileList = Object.values(files)
  const nodeMap = new Map()
  const roots = []

  fileList.forEach((file) => {
    if (file.is_folder) {
      const item = { ...file, title: file.filename, value: file.file_id, children: [] }
      nodeMap.set(file.file_id, item)
    }
  })

  fileList.forEach((file) => {
    if (file.is_folder && file.parent_id && nodeMap.has(file.parent_id)) {
      const parent = nodeMap.get(file.parent_id)
      const child = nodeMap.get(file.file_id)
      if (parent && child) parent.children.push(child)
    } else if (file.is_folder && !file.parent_id && nodeMap.has(file.file_id)) {
      roots.push(nodeMap.get(file.file_id))
    }
  })

  return roots
})

const onFileUploadSuccess = () => {
  taskerStore.loadTasks()
}

const resetFileSelectionState = () => {
  store.selectedRowKeys = []
  store.selectedFile = null
  store.state.fileDetailModalVisible = false
}

watch(
  () => route.params.kbId,
  async (nextKbId) => {
    isInitialLoad.value = true
    store.kbId = nextKbId
    resetFileSelectionState()
    store.stopAutoRefresh()
    await store.getDatabaseInfo(nextKbId, false)
    store.startAutoRefresh()
  },
  { immediate: true }
)

const previousFileCount = ref(0)

watch(
  () => database.value?.files,
  (newFiles) => {
    if (!newFiles) return

    const newFileCount = Object.keys(newFiles).length
    const oldFileCount = previousFileCount.value

    if (isInitialLoad.value) {
      previousFileCount.value = newFileCount
      isInitialLoad.value = false
      return
    }

    if (newFileCount !== oldFileCount) {
      if (newFileCount > 0) {
        setTimeout(async () => {
          if (querySectionRef.value) {
            if (database.value.additional_params?.auto_generate_questions) {
              await querySectionRef.value.generateSampleQuestions(true)
            }
          } else {
            setTimeout(async () => {
              if (
                querySectionRef.value &&
                database.value.additional_params?.auto_generate_questions
              ) {
                await querySectionRef.value.generateSampleQuestions(true)
              }
            }, 2000)
          }
        }, 3000)
      } else {
        setTimeout(() => {
          querySectionRef.value?.clearQuestions()
        }, 1000)
      }
    }

    previousFileCount.value = newFileCount
  },
  { deep: true }
)

const backToDatabase = () => {
  router.push({ path: '/extensions', query: { tab: 'knowledge' } })
}

const copyDatabaseId = async () => {
  if (!database.value.kb_id) {
    message.warning('知识库ID为空')
    return
  }

  try {
    await navigator.clipboard.writeText(database.value.kb_id)
    message.success('知识库ID已复制到剪贴板')
  } catch {
    const textArea = document.createElement('textarea')
    textArea.value = database.value.kb_id
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    message.success('知识库ID已复制到剪贴板')
  }
}

const departments = ref([])
const users = ref([])
const editModalVisible = ref(false)
const editFormRef = ref(null)
const shareConfigFormRef = ref(null)
const editForm = reactive({
  name: '',
  description: '',
  auto_generate_questions: false,
  chunk_preset_id: 'general',
  dify_api_url: '',
  dify_token: '',
  dify_dataset_id: '',
  notion_token: '',
  notion_data_source_id: '',
  notion_version: '2026-03-11'
})

const rules = {
  name: [{ required: true, message: '请输入知识库名称' }]
}

const chunkPresetOptions = CHUNK_PRESET_OPTIONS.map(({ label, value }) => ({ label, value }))
const editPresetDescription = computed(() => getChunkPresetDescription(editForm.chunk_preset_id))
const fileList = computed(() => {
  if (!database.value?.files) return []
  return Object.values(database.value.files)
    .map((f) => f.filename)
    .filter(Boolean)
})

const canEditShareConfig = computed(() => userStore.isSuperAdmin || userStore.isAdmin)

const shareConfigDisplay = computed(() => {
  const shareConfig = database.value?.share_config || { access_level: 'global' }
  if (shareConfig.access_level === 'department') {
    const departmentIds = shareConfig.department_ids || []
    const names = departmentIds.map((id) => getDepartmentName(id)).join('、') || '无'
    return {
      color: 'blue',
      label: '部门共享',
      detail: `${departmentIds.length} 个部门可访问：${names}`
    }
  }

  if (shareConfig.access_level === 'user') {
    const userUids = shareConfig.user_uids || []
    const names = userUids.map((uid) => getUserName(uid)).join('、') || '无'
    return {
      color: 'purple',
      label: '指定人可访问',
      detail: `${userUids.length} 个用户可访问：${names}`
    }
  }

  return {
    color: 'green',
    label: '全局共享',
    detail: '所有用户可访问'
  }
})

const getDepartmentName = (id) => {
  const dept = departments.value.find((item) => Number(item.id) === Number(id))
  return dept?.name || `部门${id}`
}

const getUserName = (uid) => {
  const user = users.value.find((item) => item.uid === uid)
  return user?.username || uid
}

const loadDepartments = async () => {
  try {
    const res = await departmentApi.getDepartments()
    departments.value = res.departments || res || []
  } catch {
    departments.value = []
  }
}

const loadUsers = async () => {
  try {
    users.value = await authApi.getUserAccessOptions()
  } catch {
    users.value = []
  }
}

const showEditModal = () => {
  editForm.name = database.value.name || ''
  editForm.description = database.value.description || ''
  editForm.auto_generate_questions =
    database.value.additional_params?.auto_generate_questions || false
  editForm.chunk_preset_id = database.value.additional_params?.chunk_preset_id || 'general'
  editForm.dify_api_url = database.value.additional_params?.dify_api_url || ''
  editForm.dify_token = database.value.additional_params?.dify_token || ''
  editForm.dify_dataset_id = database.value.additional_params?.dify_dataset_id || ''
  editForm.notion_token = ''
  editForm.notion_data_source_id = database.value.additional_params?.notion_data_source_id || ''
  editForm.notion_version = database.value.additional_params?.notion_version || '2026-03-11'
  editModalVisible.value = true
}

const handleEditSubmit = () => {
  editFormRef.value
    .validate()
    .then(async () => {
      if (shareConfigFormRef.value) {
        const validation = shareConfigFormRef.value.validate()
        if (!validation.valid) {
          message.warning(validation.message)
          return
        }
      }

      const formConfig = shareConfigFormRef.value?.config || { access_level: 'global' }
      const updateData = {
        name: editForm.name,
        description: editForm.description,
        additional_params: {},
        share_config: {
          access_level: formConfig.access_level,
          department_ids:
            formConfig.access_level === 'department' ? formConfig.department_ids || [] : [],
          user_uids: formConfig.access_level === 'user' ? formConfig.user_uids || [] : []
        }
      }

      if (isDifyKb.value) {
        if (
          !editForm.dify_api_url?.trim() ||
          !editForm.dify_token?.trim() ||
          !editForm.dify_dataset_id?.trim()
        ) {
          message.error('请完整填写 Dify API URL、Token 和 Dataset ID')
          return
        }
        if (!editForm.dify_api_url.trim().endsWith('/v1')) {
          message.error('Dify API URL 必须以 /v1 结尾')
          return
        }
        updateData.additional_params = {
          dify_api_url: editForm.dify_api_url.trim(),
          dify_token: editForm.dify_token.trim(),
          dify_dataset_id: editForm.dify_dataset_id.trim()
        }
      } else if (isNotionKb.value) {
        if (!editForm.notion_data_source_id?.trim()) {
          message.error('请填写 Notion Data Source ID')
          return
        }
        updateData.additional_params = {
          notion_data_source_id: editForm.notion_data_source_id.trim(),
          notion_version: editForm.notion_version?.trim() || '2026-03-11'
        }
        if (editForm.notion_token?.trim()) {
          updateData.additional_params.notion_token = editForm.notion_token.trim()
        }
      } else {
        updateData.additional_params = {
          auto_generate_questions: editForm.auto_generate_questions,
          chunk_preset_id: editForm.chunk_preset_id || 'general'
        }
      }

      await store.updateDatabaseInfo(updateData)
      editModalVisible.value = false
    })
    .catch((err) => {
      console.error('表单验证失败:', err)
    })
}

const deleteDatabase = () => {
  store.deleteDatabase()
}

onMounted(() => {
  loadDepartments()
  loadUsers()
})
</script>

<style lang="less" scoped>
@import '@/assets/css/extensions.less';
@import '@/assets/css/extension-detail.less';

.database-info-container {
  .detail-content-wrapper {
    flex: 1;
    min-height: 0;
  }

  .detail-subtitle {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.database-detail-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--gray-10);
  overflow: hidden;
}

.database-tab-bar {
  flex-shrink: 0;
  border-bottom: 1px solid var(--gray-150);
  background: var(--gray-0);
  padding: 8px 12px 0;
  overflow-x: auto;
  overflow-y: hidden;
}

.database-tab-list {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: max-content;
}

.database-tab-item {
  position: relative;
  min-height: 40px;
  border: none;
  border-radius: 8px 8px 0 0;
  background: transparent;
  color: var(--gray-600);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 14px 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 0.15s,
    color 0.15s;

  svg {
    flex-shrink: 0;
  }

  &:hover {
    color: var(--gray-900);
    background: var(--gray-50);
  }

  &:focus-visible {
    outline: 2px solid var(--main-200);
    outline-offset: 2px;
  }

  &.active {
    color: var(--main-color);
    background: var(--main-20);

    &::before {
      content: '';
      position: absolute;
      left: 12px;
      right: 12px;
      bottom: 0;
      height: 3px;
      border-radius: 3px 3px 0 0;
      background: var(--main-color);
    }
  }
}

.database-tab-content {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.tab-panel {
  flex: 1;
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 16px var(--page-padding);
}

.file-panel {
  gap: 8px;
}

.query-config-panel {
  overflow: hidden;
}

.query-config-layout {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: 12px;
}

.query-test-pane {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
}

.query-test-pane :deep(.query-section) {
  flex: 1;
  min-width: 0;
}

.query-config-pane {
  width: 360px;
  flex: 0 0 360px;
  min-height: 0;
  display: flex;
}

.query-config-pane .search-config-wrapper {
  width: 100%;
}

.query-config-pane :deep(.ant-row) {
  margin-right: 0 !important;
  margin-left: 0 !important;
}

.query-config-pane :deep(.ant-col) {
  max-width: 100%;
  flex: 0 0 100%;
  padding-right: 0 !important;
  padding-left: 0 !important;
}

.file-panel-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  padding: 10px 12px;
  background: var(--gray-0);
  border: 1px solid var(--gray-150);
  border-radius: 8px;
}

.file-panel-summary {
  display: flex;
  align-items: baseline;
  min-width: 0;
  gap: 8px;
}

.file-panel-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--gray-900);
  white-space: nowrap;
}

.file-panel-count {
  font-size: 12px;
  color: var(--gray-500);
  white-space: nowrap;
}

.file-management-info {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-shrink: 0;
}

.file-info-title {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 180px;
}

.file-info-title-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.file-panel-desc {
  font-size: 12px;
  color: var(--gray-500);
}

.file-panel-status {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.file-stat-card {
  min-width: 92px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--main-0);
  border: 1px solid var(--gray-100);
  color: var(--main-color);
  font: inherit;

  div {
    display: flex;
    flex-direction: column;
    gap: 1px;
  }

  strong {
    font-size: 14px;
    line-height: 1.2;
    color: var(--gray-900);
  }

  span {
    font-size: 11px;
    color: var(--gray-500);
    white-space: nowrap;
  }
}

.file-stat-action {
  cursor: pointer;
  color: var(--color-warning-500);
  border: 1px solid var(--color-warning-100);
  background-color: var(--color-warning-50);
  transition:
    background 0.15s,
    border-color 0.15s;

  &:hover {
    border-color: var(--color-warning-700);
  }
}

.search-config-wrapper {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  background: var(--gray-0);
  overflow: hidden;
}

.search-config-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--gray-150);
  flex-shrink: 0;

  h3 {
    margin: 0 0 4px;
    font-size: 16px;
    font-weight: 600;
    color: var(--gray-900);
  }

  p {
    margin: 0;
    font-size: 13px;
    color: var(--gray-500);
  }
}

.search-config-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px;
}

.share-config-readonly {
  display: flex;
  align-items: center;
  gap: 8px;

  .access-names {
    font-size: 13px;
    color: var(--gray-600);
  }
}

.chunk-preset-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.chunk-preset-help-icon {
  color: var(--gray-500);
  cursor: help;
  font-size: 14px;
}

@media (max-width: 1024px) {
  .query-config-layout {
    flex-direction: column;
    overflow-y: auto;
  }

  .query-test-pane {
    min-height: 360px;
  }

  .query-config-pane {
    width: 100%;
    flex: 0 0 auto;
    min-height: 320px;
  }
}

@media (max-width: 767px) {
  .detail-top-bar {
    gap: 10px;
  }

  .detail-actions :deep(.extension-panel-action span) {
    display: none;
  }

  .database-tab-bar {
    padding: 8px 8px 0;
  }

  .database-tab-item {
    min-width: 104px;
  }

  .query-config-layout {
    flex-direction: column;
  }

  .query-config-pane {
    width: 100%;
    flex: 0 0 auto;
    min-height: 320px;
  }

  .file-panel-toolbar {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>

<style lang="less">
@media (max-width: 767px) {
  .app-layout:has(.database-info-container) {
    min-width: 0;
  }
}

/* 全局样式作为备用方案 */
.ant-popover .query-params-compact {
  width: 220px;
}

.ant-popover .query-params-compact .params-loading {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 80px;
}

.ant-popover .query-params-compact .params-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
}

.ant-popover .query-params-compact .param-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
}

.ant-popover .query-params-compact .param-item label {
  font-weight: 500;
  color: var(--gray-700);
  margin-right: 8px;
}

/* Improve panel transitions */
.panel-section {
  display: flex;
  flex-direction: column;
  border-radius: 4px;
  transition: all 0.3s;
  min-height: 0;

  &.collapsed {
    height: 36px;
    flex: none;
  }

  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-bottom: 1px solid var(--gray-150);
    background-color: var(--gray-25);

    .header-left {
      display: flex;
      align-items: center;
      gap: 12px;
    }

    .section-title {
      font-size: 14px;
      font-weight: 500;
      color: var(--gray-700);
      margin: 0;
    }

    .panel-actions {
      display: flex;
      gap: 0px;
    }
  }

  .content {
    flex: 1;
    min-height: 0;
  }
}

.query-section,
.graph-section {
  .panel-section();

  .content {
    padding: 8px;
    flex: 1;
    overflow: hidden;
  }
}

.graph-section {
  border: 1px solid var(--gray-100);
  border-radius: 12px;
}

.benchmark-management-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.benchmark-content {
  flex: 1;
  overflow: hidden;
  min-height: 0;
}
</style>
