<script setup lang="ts">
import { ElMessage, ElMessageBox } from "element-plus";
import { computed, onMounted, reactive, ref } from "vue";
import { api } from "../services/api";
import type { RetrievalLogItem } from "../types/api";
import AdminPagination from "./AdminPagination.vue";

const loading = ref(false);
const logs = ref<RetrievalLogItem[]>([]);
const pager = reactive({ page: 1, pageSize: 20, total: 0 });
const cleanupBefore = ref("");
const retentionDays = ref<number | null>(90);
const retentionChoice = computed({
  get: () => retentionDays.value ?? -1,
  set: (value: number) => {
    retentionDays.value = value === -1 ? null : value;
  },
});
const retentionState = ref<{
  lastRunAt: string | null;
  lastResult: string | null;
} | null>(null);
const selected = ref<Record<string, any> | null>(null);
const detailOpen = ref(false);

onMounted(async () => {
  loading.value = true;
  try {
    await Promise.all([loadLogs(), loadRetention()]);
  } finally {
    loading.value = false;
  }
});
async function loadLogs(page = 1, pageSize = pager.pageSize) {
  const result = await api.retrievalLogs({ page, pageSize });
  logs.value = result.items;
  Object.assign(pager, {
    page: result.page,
    pageSize: result.pageSize,
    total: result.total,
  });
}
async function loadRetention() {
  const result = await api.retrievalRetention();
  retentionDays.value = result.retentionDays;
  retentionState.value = result;
}
async function cleanup() {
  if (!cleanupBefore.value) return ElMessage.warning("请选择清理日期");
  const estimate = await api.estimateRetrievalCleanup(cleanupBefore.value);
  await ElMessageBox.confirm(
    `预计清理 ${estimate.estimatedCount} 条检索日志及关联明细，操作日志不会被删除。`,
    "确认清理",
    { type: "warning" },
  );
  const result = await api.cleanupRetrievalLogs(cleanupBefore.value);
  ElMessage.success(`已清理 ${result.deleted} 条日志`);
  await loadLogs(1);
}
async function saveRetention() {
  await api.saveRetrievalRetention(retentionDays.value);
  ElMessage.success(
    retentionDays.value == null
      ? "已设为永久保留"
      : `已设为保留 ${retentionDays.value} 天`,
  );
  await loadRetention();
}
async function openDetail(row: RetrievalLogItem) {
  selected.value = await api.retrievalLogDetail(row.id);
  detailOpen.value = true;
}
</script>

<template>
  <section v-loading="loading" class="feature-page">
    <div class="page-head inline">
      <div>
        <h2>检索日志</h2>
        <p>
          查看每条回答使用的知识目录、Agent 决策、搜索候选、重排和章节回读。
        </p>
      </div>
      <div class="cleanup-controls">
        <el-date-picker
          v-model="cleanupBefore"
          value-format="YYYY-MM-DD"
          type="date"
          placeholder="清理此日期前"
        /><el-button type="danger" plain @click="cleanup">清理日志</el-button>
      </div>
    </div>
    <section class="retention-panel">
      <div>
        <strong>定期清理</strong
        ><span>每日自动分批删除过期检索日志和关联候选明细</span>
      </div>
      <el-select v-model="retentionChoice" placeholder="保留时间"
        ><el-option label="永久保留" :value="-1" /><el-option
          label="30天"
          :value="30" /><el-option label="90天" :value="90" /><el-option
          label="180天"
          :value="180" /></el-select
      ><el-button type="primary" @click="saveRetention">保存规则</el-button
      ><small>最近执行：{{ retentionState?.lastRunAt || "尚未执行" }}</small>
    </section>
    <el-table :data="logs" stripe
      ><el-table-column prop="id" label="ID" width="80" /><el-table-column
        prop="sessionId"
        label="会话"
        width="90"
      /><el-table-column
        prop="question"
        label="用户问题"
        min-width="280"
        show-overflow-tooltip
      /><el-table-column label="调用知识" width="100"
        ><template #default="{ row }"
          ><el-tag :type="row.knowledgeCalled ? 'success' : 'info'">{{
            row.knowledgeCalled ? "已调用" : "未调用"
          }}</el-tag></template
        ></el-table-column
      ><el-table-column
        prop="selectedKnowledgeIds"
        label="知识库"
        width="120"
      /><el-table-column
        prop="status"
        label="状态"
        width="100"
      /><el-table-column
        prop="toolCostMs"
        label="工具耗时"
        width="110"
      /><el-table-column
        prop="totalCostMs"
        label="总耗时"
        width="100"
      /><el-table-column
        prop="createdAt"
        label="时间"
        width="180"
      /><el-table-column label="操作" width="90" fixed="right"
        ><template #default="{ row }"
          ><el-button link type="primary" @click="openDetail(row)"
            >详情</el-button
          ></template
        ></el-table-column
      ></el-table
    >
    <AdminPagination
      :page="pager.page"
      :page-size="pager.pageSize"
      :total="pager.total"
      @change="loadLogs"
    />
    <el-drawer v-model="detailOpen" size="820px" title="检索日志详情"
      ><template v-if="selected"
        ><dl class="knowledge-meta">
          <dt>问题</dt>
          <dd>{{ selected.question }}</dd>
          <dt>安全规则</dt>
          <dd>{{ selected.safetyRuleVersion }}</dd>
          <dt>目录哈希</dt>
          <dd>{{ selected.catalogHash }}</dd>
          <dt>最终章节</dt>
          <dd>{{ selected.finalSectionIds || "未读取知识章节" }}</dd>
        </dl>
        <h3>本轮 KnowledgeList</h3>
        <pre class="trace-json">{{
          JSON.stringify(selected.catalogSnapshot, null, 2)
        }}</pre>
        <h3>Agent 工具轨迹</h3>
        <pre class="trace-json">{{
          JSON.stringify(selected.toolTrace, null, 2)
        }}</pre>
        <h3>候选切片与取舍</h3>
        <el-table :data="selected.candidates"
          ><el-table-column
            prop="knowledgeId"
            label="知识库"
            width="90" /><el-table-column
            prop="knowledgeName"
            label="名称"
            min-width="150"
            show-overflow-tooltip /><el-table-column
            prop="knowledgeTypeLabel"
            label="类型优先级"
            width="170" /><el-table-column
            prop="versionId"
            label="版本"
            width="80" /><el-table-column
            prop="sectionId"
            label="章节"
            width="80" /><el-table-column
            prop="lexicalScore"
            label="词法分"
            width="100" /><el-table-column
            prop="rerankScore"
            label="重排分"
            width="100" /><el-table-column label="采用" width="80"
            ><template #default="{ row }">{{
              row.selected ? "是" : "否"
            }}</template></el-table-column
          ><el-table-column
            prop="discardReason"
            label="舍弃原因"
            min-width="180"
        /></el-table>
        <h3>最终回答</h3>
        <pre class="trace-json">{{
          selected.finalAnswer || "尚未生成回答"
        }}</pre>
      </template></el-drawer
    >
  </section>
</template>
