<template>
  <div class="mock-oa">
    <!-- ── Login Panel (shown when not logged in) ── -->
    <a-card v-if="!currentLogin" class="login-card" :bordered="false">
      <a-row :gutter="32" align="middle">
        <!-- Login form -->
        <a-col :xs="24" :sm="12" :md="10">
          <a-typography-title :level="4" style="margin-bottom: 20px">
            <UserOutlined style="margin-right: 8px" />账号登录
          </a-typography-title>
          <a-form layout="vertical" :model="loginForm" @finish="handleLogin">
            <a-form-item label="用户名" name="username" :rules="[{ required: true, message: '请输入用户名' }]">
              <a-input
                v-model:value="loginForm.username"
                placeholder="请输入用户名"
                size="large"
                allow-clear
              >
                <template #prefix><UserOutlined /></template>
              </a-input>
            </a-form-item>
            <a-form-item label="密码" name="password" :rules="[{ required: true, message: '请输入密码' }]">
              <a-input-password
                v-model:value="loginForm.password"
                placeholder="请输入密码"
                size="large"
              >
                <template #prefix><LockOutlined /></template>
              </a-input-password>
            </a-form-item>
            <a-button
              type="primary"
              html-type="submit"
              block
              size="large"
              :loading="loginLoading"
            >
              登 录
            </a-button>
          </a-form>
        </a-col>

        <!-- Quick select preset users -->
        <a-col :xs="24" :sm="12" :md="14">
          <a-divider type="vertical" style="height: 160px" class="divider-desktop" />
          <div class="quick-login-section">
            <a-typography-text type="secondary" style="display: block; margin-bottom: 12px">
              快速选择测试账号（点击即登录）
            </a-typography-text>
            <a-row :gutter="[12, 12]">
              <a-col :span="12" v-for="user in testUsers" :key="user.username">
                <a-card
                  hoverable
                  size="small"
                  class="user-card"
                  :class="{ 'user-card--admin': user.role === 'admin', 'user-card--manager': user.role === 'manager' }"
                  @click="quickLogin(user)"
                >
                  <a-space direction="vertical" :size="4" style="width: 100%">
                    <div style="display: flex; justify-content: space-between; align-items: center">
                      <a-typography-text strong>{{ user.user_name }}</a-typography-text>
                      <a-tag :color="roleColor(user.role)" style="margin: 0">{{ roleLabel(user.role) }}</a-tag>
                    </div>
                    <div>
                      <a-tag color="blue" style="font-size: 10px; margin-bottom: 2px">{{ user.area_id }}</a-tag>
                      <a-tag color="cyan" style="font-size: 10px; margin-bottom: 2px">{{ user.dept_id }}</a-tag>
                      <a-tag color="geekblue" style="font-size: 10px; margin-bottom: 2px">{{ user.office_id }}</a-tag>
                    </div>
                    <a-typography-text type="secondary" style="font-size: 11px">
                      {{ userPassword(user.role) }}
                    </a-typography-text>
                  </a-space>
                </a-card>
              </a-col>
            </a-row>
          </div>
        </a-col>
      </a-row>
    </a-card>

    <a-tabs v-if="currentLogin" v-model:activeKey="activeTab" class="main-tabs">
      <!-- ── Tab 1: Token Generator ──────────────────────────────── -->
      <a-tab-pane key="token" tab="① 令牌生成器">
        <a-row :gutter="24">
          <a-col :span="10">
            <a-card title="生成测试 JWT 令牌" :bordered="false">
              <a-form layout="vertical" :model="tokenForm">
                <a-form-item label="用户 ID (user_id)">
                  <a-input v-model:value="tokenForm.user_id" placeholder="test_user_001" />
                </a-form-item>
                <a-form-item label="科室 (office_id)">
                  <a-input v-model:value="tokenForm.office_id" placeholder="O_01" />
                </a-form-item>
                <a-form-item label="部门 (dept_id)">
                  <a-input v-model:value="tokenForm.dept_id" placeholder="D_01" />
                </a-form-item>
                <a-form-item label="地区 (area_id)">
                  <a-input v-model:value="tokenForm.area_id" placeholder="A_01" />
                </a-form-item>
                <a-form-item label="角色 (role_ids)">
                  <a-select
                    v-model:value="tokenForm.role_ids"
                    mode="tags"
                    placeholder="输入角色ID后按回车添加"
                    style="width: 100%"
                    :open="false"
                  />
                </a-form-item>
                <a-form-item label="有效时长 (分钟)">
                  <a-input-number
                    v-model:value="tokenForm.expires_minutes"
                    :min="5"
                    :max="10080"
                    style="width: 100%"
                  />
                </a-form-item>
                <a-button type="primary" block @click="generateToken" :loading="tokenLoading">
                  <template #icon><KeyOutlined /></template>
                  生成令牌
                </a-button>
              </a-form>
            </a-card>
          </a-col>

          <a-col :span="14">
            <a-card title="生成结果" :bordered="false" v-if="currentToken">
              <a-alert
                message="令牌已生成，已存入 localStorage，搜索/研究页将自动使用"
                type="success"
                show-icon
                style="margin-bottom: 16px"
              />
              <a-descriptions :column="1" bordered size="small">
                <a-descriptions-item label="用户 ID">{{ currentToken.user_id }}</a-descriptions-item>
                <a-descriptions-item label="科室">{{ currentToken.office_id }}</a-descriptions-item>
                <a-descriptions-item label="部门">{{ currentToken.dept_id }}</a-descriptions-item>
                <a-descriptions-item label="地区">{{ currentToken.area_id }}</a-descriptions-item>
                <a-descriptions-item label="角色">
                  <a-tag v-for="r in currentToken.role_ids" :key="r" color="blue">{{ r }}</a-tag>
                  <span v-if="!currentToken.role_ids.length" style="color: #999">无</span>
                </a-descriptions-item>
                <a-descriptions-item label="有效时长">
                  {{ Math.floor(currentToken.expires_in / 3600) }}h
                  {{ Math.floor((currentToken.expires_in % 3600) / 60) }}m
                </a-descriptions-item>
              </a-descriptions>
              <a-typography-paragraph style="margin-top: 12px">
                <a-text strong>Bearer Token:</a-text>
                <a-textarea
                  :value="currentToken.access_token"
                  :auto-size="{ minRows: 3, maxRows: 5 }"
                  read-only
                  style="font-family: monospace; font-size: 11px; margin-top: 4px"
                />
              </a-typography-paragraph>
              <a-button
                @click="copyToken"
                size="small"
                style="margin-top: 4px"
              >
                <template #icon><CopyOutlined /></template>
                复制令牌
              </a-button>
            </a-card>
            <a-empty v-else description="尚未生成令牌" />
          </a-col>
        </a-row>
      </a-tab-pane>

      <!-- ── Tab 2: Upload Document ──────────────────────────────── -->
      <a-tab-pane key="upload" tab="② 上传文档">
        <a-row :gutter="24">
          <a-col :span="12">
            <a-card :bordered="false">
              <template #title>
                <a-space>
                  文档元数据
                  <a-divider type="vertical" />
                  <a-space size="small">
                    <a-switch
                      v-model:checked="autoExtract"
                      size="small"
                      checked-children="AI"
                      un-checked-children="手动"
                    />
                    <span style="font-size: 13px; font-weight: 400; color: #595959">
                      AI 自动提取
                    </span>
                    <a-tooltip title="开启后，上传时将使用大语言模型从文档内容中自动识别标题、文号、发文机关等字段，无需手动填写">
                      <QuestionCircleOutlined style="color: #8c8c8c" />
                    </a-tooltip>
                  </a-space>
                </a-space>
              </template>

              <!-- Auto-extract mode banner -->
              <a-alert
                v-if="autoExtract"
                type="success"
                show-icon
                style="margin-bottom: 16px"
              >
                <template #message>
                  <strong>⚡ AI 自动识别模式</strong>已开启
                </template>
                <template #description>
                  上传后，后台将调用 LLM 自动识别以下字段并写入索引：<br />
                  <a-space style="margin-top: 6px" wrap>
                    <a-tag color="blue">标题</a-tag>
                    <a-tag color="blue">文号</a-tag>
                    <a-tag color="blue">发文机关</a-tag>
                    <a-tag color="blue">文件类型</a-tag>
                    <a-tag color="blue">发文日期</a-tag>
                    <a-tag color="blue">签发人</a-tag>
                    <a-tag color="blue">主题词</a-tag>
                  </a-space>
                  <div style="margin-top: 6px; color: #595959; font-size: 12px">
                    如需覆盖部分字段，请关闭自动提取后手动填写，或两者兼用（手动填写优先）
                  </div>
                </template>
              </a-alert>

              <a-form layout="vertical" :model="uploadForm">
                <!-- doc_id is always visible (system identifier, not document metadata) -->
                <a-form-item label="文档 ID (doc_id)" required>
                  <a-input-group compact>
                    <a-input
                      v-model:value="uploadForm.doc_id"
                      placeholder="自动生成或手动输入"
                      style="width: calc(100% - 80px)"
                    />
                    <a-button @click="genDocId">随机</a-button>
                  </a-input-group>
                </a-form-item>

                <!-- 知识分类 — 始终可见，需手动指定 -->
                <a-form-item label="知识分类" required>
                  <a-select
                    v-model:value="uploadForm.knowledge_category"
                    placeholder="请选择知识分类"
                    style="width: 100%"
                    allow-clear
                    :options="knowledgeCategoryOptions"
                  />
                </a-form-item>

                <!-- Manual metadata fields — hidden when auto-extract is ON -->
                <template v-if="!autoExtract">
                  <a-row :gutter="12">
                    <a-col :span="24">
                      <a-form-item label="标题">
                        <a-input v-model:value="uploadForm.title" placeholder="文档标题" />
                      </a-form-item>
                    </a-col>
                  </a-row>

                  <a-row :gutter="12">
                    <a-col :span="12">
                      <a-form-item label="文号">
                        <a-input v-model:value="uploadForm.doc_number" placeholder="国发〔2024〕1号" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="12">
                      <a-form-item label="发文机关">
                        <a-input v-model:value="uploadForm.issuing_org" placeholder="国务院" />
                      </a-form-item>
                    </a-col>
                  </a-row>

                  <a-row :gutter="12">
                    <a-col :span="12">
                      <a-form-item label="文件类型">
                        <a-select v-model:value="uploadForm.doc_type" style="width: 100%">
                          <a-select-option value="通知">通知</a-select-option>
                          <a-select-option value="意见">意见</a-select-option>
                          <a-select-option value="规定">规定</a-select-option>
                          <a-select-option value="办法">办法</a-select-option>
                          <a-select-option value="决定">决定</a-select-option>
                          <a-select-option value="公告">公告</a-select-option>
                          <a-select-option value="报告">报告</a-select-option>
                          <a-select-option value="请示">请示</a-select-option>
                          <a-select-option value="批复">批复</a-select-option>
                          <a-select-option value="函">函</a-select-option>
                          <a-select-option value="其他">其他</a-select-option>
                        </a-select>
                      </a-form-item>
                    </a-col>
                    <a-col :span="12">
                      <a-form-item label="发文日期">
                        <a-input v-model:value="uploadForm.publish_date" placeholder="2024-01-01" />
                      </a-form-item>
                    </a-col>
                  </a-row>

                  <a-row :gutter="12">
                    <a-col :span="12">
                      <a-form-item label="签发人">
                        <a-input v-model:value="uploadForm.signer" placeholder="张三" />
                      </a-form-item>
                    </a-col>
                    <a-col :span="12">
                      <a-form-item label="主题词">
                        <a-select
                          v-model:value="uploadForm.subject_words"
                          mode="tags"
                          placeholder="输入主题词回车添加"
                          style="width: 100%"
                          :open="false"
                        />
                      </a-form-item>
                    </a-col>
                  </a-row>
                </template>
              </a-form>
            </a-card>
          </a-col>

          <a-col :span="12">
            <a-card title="权限设置 & 文件上传" :bordered="false">
              <a-form layout="vertical">
                <a-form-item label="权限标识 (acl_ids)">
                  <a-select
                    v-model:value="uploadForm.acl_ids"
                    mode="tags"
                    placeholder="输入权限ID回车添加（如 U_001, O_01, D_01, A_01, R_01）"
                    style="width: 100%"
                    :open="false"
                  />
                  <a-space style="margin-top: 6px">
                    <a-button size="small" @click="copyAclFromToken">使用当前令牌权限</a-button>
                    <a-button
                      size="small"
                      @click="() => { uploadForm.acl_ids = []; }"
                    >
                      公开（无限制）
                    </a-button>
                  </a-space>
                </a-form-item>

                <a-form-item label="当前文档类型">
                  <a-radio-group v-model:value="uploadForm.current_relation_type">
                    <a-radio-button value="正文">正文</a-radio-button>
                    <a-radio-button value="附件">附件</a-radio-button>
                  </a-radio-group>
                  <span style="margin-left: 8px; font-size: 12px; color: #8c8c8c">
                    标记本文档在关联关系中的角色
                  </span>
                </a-form-item>

                <a-form-item label="关联文档">
                  <a-select
                    show-search
                    placeholder="输入文档ID或标题搜索已入库文档"
                    :filter-option="false"
                    :loading="relatedDocSearchLoading"
                    @search="handleRelatedDocSearch"
                    @select="handleRelatedDocSelect"
                    style="width: 100%"
                    :value="undefined"
                    :not-found-content="relatedDocSearchLoading ? '搜索中...' : '未找到匹配文档'"
                  >
                    <a-select-option
                      v-for="item in relatedDocSearchResults"
                      :key="item.doc_id"
                      :value="item.doc_id"
                    >
                      {{ item.title || item.doc_id }}
                      <span style="color: #8c8c8c; font-size: 12px; margin-left: 4px">({{ item.doc_id }})</span>
                    </a-select-option>
                  </a-select>
                  <div v-if="uploadForm.related_docs.length" style="margin-top: 8px">
                    <a-tag
                      v-for="(rel, idx) in uploadForm.related_docs"
                      :key="rel.doc_id"
                      closable
                      @close="uploadForm.related_docs.splice(idx, 1)"
                      :color="rel.relation_type === '正文' ? 'blue' : 'orange'"
                      style="margin-bottom: 4px"
                    >
                      <span style="font-weight: 500">[{{ rel.relation_type }}]</span>
                      {{ rel.title || rel.doc_id }}
                    </a-tag>
                  </div>
                </a-form-item>

                <a-form-item label="文档文件" required>
                  <a-upload-dragger
                    :file-list="fileList"
                    :before-upload="beforeUpload"
                    @change="({ fileList: fl }: any) => { fileList = fl }"
                    accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.wps,.et,.ofd,.png,.jpg,.jpeg,.tiff,.bmp,.txt,.md"
                    :max-count="1"
                  >
                    <p class="ant-upload-drag-icon">
                      <CloudUploadOutlined />
                    </p>
                    <p class="ant-upload-text">点击或拖拽文件到此区域</p>
                    <p class="ant-upload-hint">支持 PDF、Word、Excel、PPT、WPS、OFD、图片、文本等 18 种格式</p>
                  </a-upload-dragger>
                </a-form-item>

                <a-button
                  type="primary"
                  block
                  size="large"
                  @click="submitUpload"
                  :loading="uploadLoading"
                  :disabled="!fileList.length || !uploadForm.doc_id"
                >
                  <template #icon><UploadOutlined /></template>
                  提交文档入库
                </a-button>
              </a-form>
            </a-card>
          </a-col>
        </a-row>

        <!-- Upload result -->
        <a-alert
          v-if="lastUploadResult"
          style="margin-top: 16px"
          type="success"
          show-icon
        >
          <template #message>
            文档已提交
            <a-tag style="margin-left: 6px">{{ lastUploadResult.doc_id }}</a-tag>
            <a-tag v-if="lastUploadResult.auto_extract" color="green">⚡ AI自动提取</a-tag>
          </template>
          <template #description>
            task_id: <code>{{ lastUploadResult.task_id }}</code>
          </template>
          <template #action>
            <a-button
              size="small"
              @click="() => { activeTab = 'tasks'; monitorTaskId = lastUploadResult!.task_id; pollTask(); startAutoPoll(); }"
            >
              监控任务
            </a-button>
          </template>
        </a-alert>
      </a-tab-pane>

      <!-- ── Tab 3: Task Monitor ─────────────────────────────────── -->
      <a-tab-pane key="tasks" tab="③ 任务监控">
        <a-row :gutter="24">
          <a-col :span="12">
            <a-card title="任务状态查询" :bordered="false">
              <a-input-search
                v-model:value="monitorTaskId"
                placeholder="输入 Celery Task ID"
                enter-button="查询"
                size="large"
                @search="pollTask"
              />

              <div v-if="taskStatus" style="margin-top: 20px">
                <a-descriptions :column="2" bordered size="small">
                  <a-descriptions-item label="Task ID" :span="2">
                    <a-typography-text code>{{ taskStatus.task_id }}</a-typography-text>
                  </a-descriptions-item>
                  <a-descriptions-item label="状态">
                    <a-tag :color="taskStatusColor(taskStatus.status)">
                      {{ taskStatus.status }}
                    </a-tag>
                  </a-descriptions-item>
                  <a-descriptions-item label="进度">
                    <a-progress
                      :percent="Math.round(taskStatus.progress * 100)"
                      size="small"
                      style="width: 120px"
                    />
                  </a-descriptions-item>
                </a-descriptions>

                <a-alert
                  v-if="taskStatus.error"
                  type="error"
                  :message="taskStatus.error"
                  style="margin-top: 12px"
                  show-icon
                />

                <!-- AI 提取结果 — shown when auto_extract was used -->
                <a-card
                  v-if="taskStatus.result?.extracted_metadata"
                  size="small"
                  style="margin-top: 12px"
                  :head-style="{ background: '#f6ffed', borderBottom: '1px solid #b7eb8f' }"
                >
                  <template #title>
                    <span style="color: #52c41a">⚡ AI 自动提取结果</span>
                  </template>
                  <a-descriptions :column="2" size="small" bordered>
                    <a-descriptions-item label="标题" :span="2">
                      {{ taskStatus.result.extracted_metadata.title || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="文号">
                      {{ taskStatus.result.extracted_metadata.doc_number || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="文件类型">
                      {{ taskStatus.result.extracted_metadata.doc_type || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="发文机关">
                      {{ taskStatus.result.extracted_metadata.issuing_org || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="发文日期">
                      {{ taskStatus.result.extracted_metadata.publish_date || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="签发人">
                      {{ taskStatus.result.extracted_metadata.signer || '—' }}
                    </a-descriptions-item>
                    <a-descriptions-item label="主题词">
                      <a-tag
                        v-for="w in taskStatus.result.extracted_metadata.subject_words"
                        :key="w"
                        color="blue"
                      >{{ w }}</a-tag>
                      <span v-if="!taskStatus.result.extracted_metadata.subject_words?.length">—</span>
                    </a-descriptions-item>
                  </a-descriptions>
                </a-card>

                <a-card v-if="taskStatus.result" size="small" style="margin-top: 12px" title="任务结果（完整）">
                  <pre style="font-size: 11px; white-space: pre-wrap; word-break: break-all">{{
                    JSON.stringify(taskStatus.result, null, 2)
                  }}</pre>
                </a-card>

                <a-space style="margin-top: 12px">
                  <a-button
                    v-if="isTaskRunning"
                    @click="startAutoPoll"
                    :loading="autoPolling"
                    type="primary"
                    ghost
                  >
                    {{ autoPolling ? '自动轮询中...' : '开始自动轮询' }}
                  </a-button>
                  <a-button v-if="autoPolling" @click="stopAutoPoll" danger>停止轮询</a-button>
                </a-space>
              </div>
            </a-card>
          </a-col>

          <a-col :span="12">
            <a-card title="最近提交的任务" :bordered="false">
              <a-list :data-source="recentTasks" size="small">
                <template #renderItem="{ item }">
                  <a-list-item>
                    <a-list-item-meta>
                      <template #title>
                        <a-typography-text code style="font-size: 11px">{{ item.task_id }}</a-typography-text>
                      </template>
                      <template #description>{{ item.doc_id }}</template>
                    </a-list-item-meta>
                    <template #actions>
                      <a @click="() => { monitorTaskId = item.task_id; pollTask(); }">查看</a>
                    </template>
                  </a-list-item>
                </template>
                <template #empty>
                  <a-empty description="本次会话暂无任务记录" />
                </template>
              </a-list>
            </a-card>
          </a-col>
        </a-row>
      </a-tab-pane>

      <!-- ── Tab 4: Document List ────────────────────────────────── -->
      <a-tab-pane key="docs" tab="④ 已入库文档">
        <a-card :bordered="false">
          <a-row :gutter="12" style="margin-bottom: 16px">
            <a-col :span="16">
              <a-input-search
                v-model:value="docsKeyword"
                placeholder="搜索文档标题 / 文号 / 机关"
                enter-button
                @search="loadDocs"
              />
            </a-col>
            <a-col :span="8">
              <a-button @click="loadDocs" :loading="docsLoading">
                <template #icon><ReloadOutlined /></template>
                刷新列表
              </a-button>
            </a-col>
          </a-row>

          <a-table
            :columns="docColumns"
            :data-source="docList"
            :loading="docsLoading"
            row-key="doc_id"
            size="small"
            :pagination="{ pageSize: 10 }"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'acl'">
                <div>
                  <a-tag
                    v-for="d in (record.acl_ids || []).slice(0, 3)"
                    :key="d"
                    color="blue"
                    style="font-size: 10px"
                  >{{ d }}</a-tag>
                  <a-tag
                    v-if="(record.acl_ids || []).length > 3"
                    color="blue"
                  >+{{ record.acl_ids.length - 3 }}</a-tag>
                  <span v-if="!(record.acl_ids || []).length" style="color: #52c41a">
                    公开
                  </span>
                </div>
              </template>
              <template v-else-if="column.key === 'actions'">
                <a-popconfirm
                  title="确认删除此文档？将从 ES 和 Neo4j 中移除。"
                  @confirm="deleteDoc(record.doc_id)"
                >
                  <a-button size="small" danger type="text">删除</a-button>
                </a-popconfirm>
              </template>
            </template>
          </a-table>
        </a-card>
      </a-tab-pane>

      <!-- ── Tab 5: Search Test ─────────────────────────────────── -->
      <a-tab-pane key="search" tab="⑤ 搜索验证">
        <a-row :gutter="24">
          <a-col :span="16">
            <a-card title="权限感知搜索测试" :bordered="false">
              <a-alert
                v-if="!currentToken"
                message="请先在「令牌生成器」标签页生成令牌，搜索将使用该令牌的权限范围。"
                type="warning"
                show-icon
                style="margin-bottom: 16px"
              />
              <a-alert
                v-else
                :message="`当前令牌: ${currentToken.user_id} | ${currentToken.area_id}/${currentToken.dept_id}/${currentToken.office_id}`"
                type="info"
                show-icon
                style="margin-bottom: 16px"
              />

              <a-input-search
                v-model:value="searchQuery"
                placeholder="输入搜索关键词（将通过后端权限过滤）"
                size="large"
                enter-button="搜索"
                :loading="searchLoading"
                @search="runSearch"
              />

              <div v-if="searchResults !== null" style="margin-top: 16px">
                <a-typography-text type="secondary">
                  共 {{ searchResults.total }} 条结果（仅展示有权限的文档）
                </a-typography-text>
                <a-list
                  :data-source="searchResults.documents"
                  style="margin-top: 8px"
                >
                  <template #renderItem="{ item, index }">
                    <a-list-item>
                      <a-list-item-meta>
                        <template #title>
                          <span style="font-size: 13px">
                            <a-tag color="blue" style="margin-right: 4px">{{ index + 1 }}</a-tag>
                            {{ item.title || item.doc_id }}
                          </span>
                        </template>
                        <template #description>
                          <a-space size="small">
                            <a-tag v-if="item.doc_number">{{ item.doc_number }}</a-tag>
                            <a-tag v-if="item.issuing_org" color="cyan">{{ item.issuing_org }}</a-tag>
                            <a-tag v-if="item.doc_type" color="geekblue">{{ item.doc_type }}</a-tag>
                            <a-tag v-if="item.publish_date">{{ item.publish_date }}</a-tag>
                            <a-tag color="orange">得分: {{ item.score?.toFixed(4) }}</a-tag>
                          </a-space>
                          <div
                            v-for="(hl, i) in item.highlights?.slice(0, 2)"
                            :key="i"
                            class="highlight-text"
                            v-html="hl"
                          />
                        </template>
                      </a-list-item-meta>
                    </a-list-item>
                  </template>
                  <template #empty>
                    <a-empty description="无结果（当前令牌权限内无匹配文档）" />
                  </template>
                </a-list>
              </div>
            </a-card>
          </a-col>

          <a-col :span="8">
            <a-card title="测试提示" :bordered="false" size="small">
              <a-timeline>
                <a-timeline-item color="blue">
                  生成令牌A (O_01, D_01, A_01)
                </a-timeline-item>
                <a-timeline-item color="blue">
                  上传文档X (acl_ids: [D_01])
                </a-timeline-item>
                <a-timeline-item color="green">
                  用令牌A搜索 → 可见文档X ✓
                </a-timeline-item>
                <a-timeline-item color="red">
                  生成令牌B (D_08) 搜索 → 不可见文档X ✗
                </a-timeline-item>
                <a-timeline-item color="purple">
                  权限验证通过！
                </a-timeline-item>
              </a-timeline>
            </a-card>

            <a-card title="快捷操作" :bordered="false" size="small" style="margin-top: 12px">
              <a-space direction="vertical" style="width: 100%">
                <a-button block @click="goToSearchPage">
                  前往搜索页（使用当前令牌）
                </a-button>
                <a-button block @click="goToResearch">
                  前往研究分析页
                </a-button>
                <a-button block @click="goToGraph">
                  前往知识图谱页
                </a-button>
              </a-space>
            </a-card>
          </a-col>
        </a-row>
      </a-tab-pane>
    </a-tabs>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { message } from 'ant-design-vue'
import axios from 'axios'
import {
  ReloadOutlined,
  KeyOutlined,
  CopyOutlined,
  CloudUploadOutlined,
  UploadOutlined,
  UserOutlined,
  LockOutlined,
  QuestionCircleOutlined,
} from '@ant-design/icons-vue'
import {
  mockApi,
  type LoginResponse,
  type TestUserInfo,
  type TokenResponse,
  type TaskStatus,
  type DocListItem,
} from '@/api/mock'
import { fetchFilterOptions, searchDocsForBinding } from '@/api/search'
import { useUserStore } from '@/stores/user'

const router = useRouter()
const userStore = useUserStore()

// ── State ────────────────────────────────────────────────────────────

const activeTab = ref('token')

// ── Login state ───────────────────────────────────────────────────────

const loginLoading = ref(false)
const loginForm = ref({ username: '', password: '' })
const currentLogin = ref<LoginResponse | null>(null)
const testUsers = ref<TestUserInfo[]>([])

// Token tab
const tokenLoading = ref(false)
const tokenForm = ref({
  user_id: 'test_user_001',
  office_id: 'O_01',
  dept_id: 'D_01',
  area_id: 'A_01',
  role_ids: [] as string[],
  expires_minutes: 480,
})
const currentToken = ref<TokenResponse | null>(null)

// Upload tab
const uploadLoading = ref(false)
const autoExtract = ref(true)          // AI auto-extract metadata toggle
const fileList = ref<any[]>([])
const uploadForm = ref({
  doc_id: '',
  title: '',
  doc_number: '',
  issuing_org: '',
  doc_type: '通知',
  knowledge_category: undefined as string | undefined,
  publish_date: '',
  signer: '',
  subject_words: [] as string[],
  acl_ids: [] as string[],
  related_docs: [] as { doc_id: string; title: string; relation_type: string }[],
  current_relation_type: '正文' as string,
})
const relatedDocSearchResults = ref<{ doc_id: string; title: string }[]>([])
const relatedDocSearchLoading = ref(false)
const knowledgeCategoryOptions = ref<{ label: string; value: string }[]>([])
const lastUploadResult = ref<{ doc_id: string; task_id: string; auto_extract?: boolean } | null>(null)

// Task monitor tab
const monitorTaskId = ref('')
const taskStatus = ref<TaskStatus | null>(null)
const autoPolling = ref(false)
let pollInterval: ReturnType<typeof setInterval> | null = null
const recentTasks = ref<{ task_id: string; doc_id: string }[]>([])

// Docs tab
const docsLoading = ref(false)
const docsKeyword = ref('')
const docList = ref<DocListItem[]>([])

// Search tab
const searchLoading = ref(false)
const searchQuery = ref('')
const searchResults = ref<{ total: number; documents: any[] } | null>(null)

// ── Computed ─────────────────────────────────────────────────────────

const isTaskRunning = computed(() =>
  taskStatus.value && ['PENDING', 'PROCESSING', 'STARTED'].includes(taskStatus.value.status)
)

const docColumns = [
  { title: '文档ID', dataIndex: 'doc_id', key: 'doc_id', width: 160, ellipsis: true },
  { title: '标题', dataIndex: 'title', key: 'title', ellipsis: true },
  { title: '文号', dataIndex: 'doc_number', key: 'doc_number', width: 130 },
  { title: '发文机关', dataIndex: 'issuing_org', key: 'issuing_org', width: 100 },
  { title: 'Chunks', dataIndex: 'chunk_count', key: 'chunk_count', width: 70 },
  { title: '权限部门', key: 'acl', width: 160 },
  { title: '操作', key: 'actions', width: 60 },
]

// ── Helpers ──────────────────────────────────────────────────────────

function taskStatusColor(status: string) {
  const map: Record<string, string> = {
    COMPLETED: 'success',
    SUCCESS: 'success',
    FAILED: 'error',
    FAILURE: 'error',
    PROCESSING: 'processing',
    PENDING: 'default',
    STARTED: 'processing',
  }
  return map[status] ?? 'default'
}

function genDocId() {
  uploadForm.value.doc_id = 'doc_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6)
}

// ── Login helpers ─────────────────────────────────────────────────────

function roleColor(role: string) {
  return role === 'admin' ? 'red' : role === 'manager' ? 'orange' : 'default'
}
function roleLabel(role: string) {
  return role === 'admin' ? '管理员' : role === 'manager' ? '经理' : '员工'
}
function userPassword(role: string) {
  return role === 'admin' ? '密码: admin123' : role === 'manager' ? '密码: manager123' : '密码: user123'
}

function applyLogin(res: LoginResponse) {
  currentLogin.value = res
  // Sync to token tab display
  currentToken.value = {
    access_token: res.access_token,
    token_type: res.token_type,
    expires_in: res.expires_in,
    user_id: res.user_id,
    office_id: res.office_id,
    dept_id: res.dept_id,
    area_id: res.area_id,
    role_ids: res.role_ids,
  }
  // 通过 userStore 统一管理 token 和用户信息（JWT 解析会自动填充大部分字段）
  userStore.setToken(res.access_token)
  // 补充 JWT 中可能没有的 user_name（login 返回的 user_name 可能比 JWT 中的更友好）
  userStore.setUserInfo({ userName: res.user_name || res.username })
  axios.defaults.headers.common['Authorization'] = `Bearer ${res.access_token}`
}

async function handleLogin() {
  if (!loginForm.value.username || !loginForm.value.password) return
  loginLoading.value = true
  try {
    const res = await mockApi.login(loginForm.value)
    applyLogin(res)
    message.success(`欢迎，${res.user_name}！`)
    loginForm.value = { username: '', password: '' }
    await loadDocs()
    fetchFilterOptions().then(opts => { knowledgeCategoryOptions.value = opts.knowledge_categories || [] }).catch(() => {})
  } catch (e: any) {
    message.error(e.response?.data?.detail || '用户名或密码错误')
  } finally {
    loginLoading.value = false
  }
}

async function quickLogin(user: TestUserInfo) {
  const passwordMap: Record<string, string> = {
    admin: 'admin123',
    manager: 'manager123',
    user: 'user123',
  }
  loginLoading.value = true
  try {
    const res = await mockApi.login({ username: user.username, password: passwordMap[user.role] })
    applyLogin(res)
    message.success(`已切换为 ${res.user_name}`)
    await loadDocs()
    fetchFilterOptions().then(opts => { knowledgeCategoryOptions.value = opts.knowledge_categories || [] }).catch(() => {})
  } catch (e: any) {
    message.error('快速登录失败')
  } finally {
    loginLoading.value = false
  }
}

function handleLogout() {
  currentLogin.value = null
  currentToken.value = null
  userStore.logout()
  delete axios.defaults.headers.common['Authorization']
  message.info('已退出登录')
}

// ── Actions ──────────────────────────────────────────────────────────

async function generateToken() {
  tokenLoading.value = true
  try {
    const res = await mockApi.generateToken({
      user_id: tokenForm.value.user_id,
      office_id: tokenForm.value.office_id,
      dept_id: tokenForm.value.dept_id,
      area_id: tokenForm.value.area_id,
      role_ids: tokenForm.value.role_ids,
      expires_minutes: tokenForm.value.expires_minutes,
    })
    currentToken.value = res
    // 通过 userStore 统一管理 token 和用户信息
    userStore.setToken(res.access_token)
    axios.defaults.headers.common['Authorization'] = `Bearer ${res.access_token}`
    message.success('令牌已生成并存入 localStorage')
  } catch (e: any) {
    message.error('生成令牌失败: ' + (e.response?.data?.detail || e.message))
  } finally {
    tokenLoading.value = false
  }
}

// generateBatchDepts removed: not applicable with unified ACL model

function copyToken() {
  if (!currentToken.value) return
  navigator.clipboard.writeText(currentToken.value.access_token)
    .then(() => message.success('已复制到剪贴板'))
    .catch(() => message.warning('复制失败，请手动复制'))
}

function copyAclFromToken() {
  if (!currentToken.value) {
    message.warning('当前无令牌')
    return
  }
  const t = currentToken.value
  const ids: string[] = []
  if (t.office_id) ids.push(t.office_id)
  if (t.dept_id) ids.push(t.dept_id)
  if (t.area_id) ids.push(t.area_id)
  for (const r of t.role_ids) ids.push(r)
  ids.push(t.user_id)
  uploadForm.value.acl_ids = ids
  message.success('已填入当前令牌的权限标识')
}

function beforeUpload(file: File) {
  if (!uploadForm.value.doc_id) {
    genDocId()
  }
  if (!uploadForm.value.title) {
    uploadForm.value.title = file.name.replace(/\.[^.]+$/, '')
  }
  return false // prevent auto upload
}

let relatedDocSearchTimer: ReturnType<typeof setTimeout> | null = null
function handleRelatedDocSearch(query: string) {
  if (relatedDocSearchTimer) clearTimeout(relatedDocSearchTimer)
  if (!query || query.length < 2) {
    relatedDocSearchResults.value = []
    return
  }
  relatedDocSearchLoading.value = true
  relatedDocSearchTimer = setTimeout(async () => {
    try {
      const res = await searchDocsForBinding(query)
      relatedDocSearchResults.value = (res.documents || []).map((d: any) => ({
        doc_id: d.doc_id,
        title: d.title,
      }))
    } catch {
      relatedDocSearchResults.value = []
    } finally {
      relatedDocSearchLoading.value = false
    }
  }, 300)
}

function handleRelatedDocSelect(docId: string) {
  const already = uploadForm.value.related_docs.find((r) => r.doc_id === docId)
  if (already) {
    message.info('该文档已添加')
    return
  }
  const found = relatedDocSearchResults.value.find((r) => r.doc_id === docId)
  // Reverse logic: if current doc is "正文", the related doc is "附件", and vice versa
  const relationType = uploadForm.value.current_relation_type === '正文' ? '附件' : '正文'
  uploadForm.value.related_docs.push({
    doc_id: docId,
    title: found?.title || docId,
    relation_type: relationType,
  })
}

async function submitUpload() {
  if (!fileList.value.length) {
    message.warning('请选择文档文件')
    return
  }
  if (!uploadForm.value.doc_id) {
    message.warning('请填写文档 ID')
    return
  }

  uploadLoading.value = true
  try {
    // When auto-extract is ON: send only doc_id + ACL + knowledge_category + the flag.
    // When manual: send all metadata fields as filled by the user.
    const meta: Record<string, any> = {
      doc_id: uploadForm.value.doc_id,
      acl_ids: uploadForm.value.acl_ids,
      knowledge_category: uploadForm.value.knowledge_category || '',
      related_docs: uploadForm.value.related_docs.map(({ doc_id, title, relation_type }) => ({
        doc_id, title, relation_type,
      })),
    }
    if (autoExtract.value) {
      meta.auto_extract = true
    } else {
      meta.title = uploadForm.value.title
      meta.doc_number = uploadForm.value.doc_number
      meta.issuing_org = uploadForm.value.issuing_org
      meta.doc_type = uploadForm.value.doc_type
      meta.publish_date = uploadForm.value.publish_date
      meta.signer = uploadForm.value.signer
      meta.subject_words = uploadForm.value.subject_words
    }

    const formData = new FormData()
    formData.append('metadata', JSON.stringify(meta))
    formData.append('file', fileList.value[0].originFileObj || fileList.value[0])

    const res = await mockApi.uploadDoc(formData)
    lastUploadResult.value = { ...res, auto_extract: autoExtract.value }
    recentTasks.value.unshift({ task_id: res.task_id, doc_id: res.doc_id })
    message.success(`文档已提交！task_id: ${res.task_id}`)

    // Reset form
    fileList.value = []
    uploadForm.value.doc_id = ''
    uploadForm.value.title = ''
  } catch (e: any) {
    message.error('上传失败: ' + (e.response?.data?.detail || e.message))
  } finally {
    uploadLoading.value = false
  }
}

async function pollTask() {
  if (!monitorTaskId.value) return
  try {
    taskStatus.value = await mockApi.getTaskStatus(monitorTaskId.value)
  } catch (e: any) {
    message.error('查询失败: ' + (e.response?.data?.detail || e.message))
  }
}

function startAutoPoll() {
  if (autoPolling.value) return
  autoPolling.value = true
  pollInterval = setInterval(async () => {
    await pollTask()
    if (!isTaskRunning.value) {
      stopAutoPoll()
    }
  }, 2000)
}

function stopAutoPoll() {
  autoPolling.value = false
  if (pollInterval) {
    clearInterval(pollInterval)
    pollInterval = null
  }
}

async function loadDocs() {
  docsLoading.value = true
  try {
    docList.value = await mockApi.listDocs({ keyword: docsKeyword.value, size: 50 })
  } catch (e: any) {
    message.error('加载失败: ' + (e.response?.data?.detail || e.message))
  } finally {
    docsLoading.value = false
  }
}

async function deleteDoc(docId: string) {
  try {
    await mockApi.deleteDoc(docId)
    message.success(`文档 ${docId} 已删除`)
    await loadDocs()
  } catch (e: any) {
    message.error('删除失败: ' + (e.response?.data?.detail || e.message))
  }
}

async function runSearch() {
  if (!searchQuery.value.trim()) return
  if (!currentToken.value) {
    message.warning('请先生成令牌')
    activeTab.value = 'token'
    return
  }
  searchLoading.value = true
  try {
    const res = await axios.post(
      '/api/v1/search',
      { query: searchQuery.value, page: 1, page_size: 10 },
      { headers: { Authorization: `Bearer ${currentToken.value.access_token}` } }
    )
    searchResults.value = res.data
  } catch (e: any) {
    message.error('搜索失败: ' + (e.response?.data?.detail || e.message))
  } finally {
    searchLoading.value = false
  }
}

function goToSearchPage() {
  router.push({ path: '/search', query: { q: searchQuery.value || undefined } })
}
function goToResearch() { router.push('/research') }
function goToGraph() { router.push('/graph') }

// ── Lifecycle ────────────────────────────────────────────────────────

onMounted(async () => {
  // Restore session from userStore (which reads from localStorage)
  const savedToken = userStore.token
  const savedUserId = userStore.userId

  if (savedToken && savedUserId) {
    currentLogin.value = {
      access_token: savedToken,
      token_type: 'bearer',
      expires_in: 0,
      user_id: savedUserId,
      username: userStore.userName || savedUserId,
      user_name: userStore.userName || savedUserId,
      office_id: userStore.officeId,
      office_name: userStore.officeName || '',
      dept_id: userStore.deptId,
      dept_name: userStore.deptName || '',
      area_id: userStore.areaId,
      area_name: userStore.areaName || '',
      role_ids: [...userStore.roleIds],
      role: 'user',
    }
    currentToken.value = {
      access_token: savedToken,
      token_type: 'bearer',
      expires_in: 0,
      user_id: savedUserId,
      office_id: userStore.officeId,
      dept_id: userStore.deptId,
      area_id: userStore.areaId,
      role_ids: [...userStore.roleIds],
    }
    axios.defaults.headers.common['Authorization'] = `Bearer ${savedToken}`
    await loadDocs()

    // Load knowledge category options (requires auth)
    try {
      const opts = await fetchFilterOptions()
      knowledgeCategoryOptions.value = opts.knowledge_categories || []
    } catch {
      knowledgeCategoryOptions.value = []
    }
  }

  // Always load test users for the quick-login panel
  try {
    testUsers.value = await mockApi.listUsers()
  } catch {
    // fallback: hardcoded list if backend unreachable
    testUsers.value = [
      { username: 'admin', user_name: '系统管理员', office_id: 'O_01', office_name: '综合办公室', dept_id: 'D_01', dept_name: '市政务服务中心', area_id: 'A_01', area_name: '市本级', role_ids: ['R_01'], role: 'admin' },
      { username: 'zhang_san', user_name: '张三', office_id: 'O_17', office_name: '财务科', dept_id: 'D_05', dept_name: '市财政局', area_id: 'A_01', area_name: '市本级', role_ids: [], role: 'user' },
      { username: 'li_si', user_name: '李四', office_id: 'O_22', office_name: '技术科', dept_id: 'D_08', dept_name: '市工信局', area_id: 'A_02', area_name: '高新区', role_ids: [], role: 'user' },
      { username: 'wang_wu', user_name: '王五', office_id: 'O_01', office_name: '综合办公室', dept_id: 'D_05', dept_name: '市财政局', area_id: 'A_01', area_name: '市本级', role_ids: ['R_03'], role: 'manager' },
    ]
  }
})

onUnmounted(() => stopAutoPoll())
</script>

<style scoped>
.mock-oa {
  padding: 0 24px 24px;
  max-width: 1400px;
  margin: 0 auto;
}

.main-tabs {
  background: transparent;
}

:deep(.main-tabs .ant-tabs-nav) {
  margin-bottom: 0;
}

:deep(.main-tabs .ant-tabs-tabpane) {
  padding-top: 16px;
}

.dept-input-area {
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  padding: 8px;
}

.highlight-text {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
  line-height: 1.5;
}

:deep(.highlight-text em) {
  color: #f5222d;
  font-style: normal;
  font-weight: 600;
}

/* Login panel */
.login-card {
  margin-bottom: 16px;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
}

.quick-login-section {
  padding-left: 24px;
}

.divider-desktop {
  display: inline-block;
  margin-right: 0;
  vertical-align: middle;
}

@media (max-width: 576px) {
  .divider-desktop { display: none; }
  .quick-login-section { padding-left: 0; margin-top: 16px; }
}

.user-card {
  cursor: pointer;
  border: 1px solid #e8e8e8;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.user-card:hover {
  border-color: #1677ff;
  box-shadow: 0 2px 8px rgba(22, 119, 255, 0.15);
}
.user-card--admin {
  border-color: #ffccc7;
  background: #fff2f0;
}
.user-card--admin:hover {
  border-color: #ff4d4f;
  box-shadow: 0 2px 8px rgba(255, 77, 79, 0.15);
}
.user-card--manager {
  border-color: #ffe7ba;
  background: #fffbe6;
}
.user-card--manager:hover {
  border-color: #fa8c16;
  box-shadow: 0 2px 8px rgba(250, 140, 22, 0.15);
}
</style>
