<script setup lang="ts">
import { ElMessage } from "element-plus";
import { onMounted, reactive, ref } from "vue";

import { api, clearToken, getToken, saveToken } from "./services/api";
import type {
  AdminProfile,
  AdminUser,
  AiLogRecord,
  ChatDetail,
  ChatRecord,
  DashboardStats,
  KnowledgeItem,
  ModelItem,
} from "./types/api";

const admin = ref<AdminProfile | null>(null);
const activeMenu = ref("dashboard");
const loading = ref(false);

const loginForm = reactive({ username: "admin", password: "admin123456" });
const stats = ref<DashboardStats | null>(null);
const users = ref<AdminUser[]>([]);
const userKeyword = ref("");
const knowledge = ref<KnowledgeItem[]>([]);
const models = ref<ModelItem[]>([]);
const configs = ref<Record<string, unknown>[]>([]);
const chats = ref<ChatRecord[]>([]);
const aiLogs = ref<AiLogRecord[]>([]);
const operationLogs = ref<Record<string, unknown>[]>([]);
const promptContent = ref("");
const chatDetail = ref<ChatDetail | null>(null);
const chatDetailOpen = ref(false);
const recordTab = ref("chats");
const editingModelId = ref<number | null>(null);

const knowledgeForm = reactive({
  name: "",
  feishuSpaceId: "",
  feishuNodeId: "",
  status: 1,
  remark: "",
});

const modelForm = reactive({
  provider: "openai",
  displayName: "",
  apiType: "openai_compatible",
  modelName: "",
  baseUrl: "https://api.openai.com/v1",
  apiUrl: "",
  apiKey: "",
  authType: "bearer",
  apiVersion: "",
  temperature: 0.2 as number | null,
  topP: null as number | null,
  topK: null as number | null,
  presencePenalty: null as number | null,
  frequencyPenalty: null as number | null,
  maxToken: 1024,
  contextWindow: null as number | null,
  streamEnabled: 1,
  responseFormat: "",
  extraParams: "",
  remark: "",
  timeoutSecond: 30,
});

const modelPresets = [
  {
    label: "OpenAI",
    provider: "openai",
    apiType: "openai_compatible",
    baseUrl: "https://api.openai.com/v1",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "DeepSeek",
    provider: "deepseek",
    apiType: "openai_compatible",
    baseUrl: "https://api.deepseek.com/v1",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "通义千问 DashScope",
    provider: "qwen",
    apiType: "openai_compatible",
    baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "Kimi / Moonshot",
    provider: "moonshot",
    apiType: "openai_compatible",
    baseUrl: "https://api.moonshot.cn/v1",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "硅基流动 SiliconFlow",
    provider: "siliconflow",
    apiType: "openai_compatible",
    baseUrl: "https://api.siliconflow.cn/v1",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "火山方舟 Ark",
    provider: "volcengine-ark",
    apiType: "openai_compatible",
    baseUrl: "https://ark.cn-beijing.volces.com/api/v3",
    apiUrl: "",
    authType: "bearer",
  },
  {
    label: "Anthropic Claude",
    provider: "anthropic",
    apiType: "anthropic_messages",
    baseUrl: "https://api.anthropic.com",
    apiUrl: "",
    authType: "api_key",
    apiVersion: "2023-06-01",
    temperature: null,
    topP: null,
    topK: null,
  },
  {
    label: "Google Gemini",
    provider: "gemini",
    apiType: "gemini_generate_content",
    baseUrl: "https://generativelanguage.googleapis.com/v1beta",
    apiUrl: "",
    authType: "api_key",
    temperature: null,
    topP: null,
    topK: null,
  },
];

const nullableModelFields = [
  "temperature",
  "topP",
  "topK",
  "presencePenalty",
  "frequencyPenalty",
  "contextWindow",
  "responseFormat",
  "extraParams",
  "remark",
] as const;

const configForm = reactive({
  configKey: "daily_chat_limit",
  configValue: "100",
  description: "默认每日聊天次数",
});

const chatFilters = reactive({
  keyword: "",
  userId: undefined as number | undefined,
  status: "",
  dateRange: [] as string[],
});

onMounted(async () => {
  if (!getToken()) return;
  try {
    admin.value = await api.profile();
    await loadCurrentMenu();
  } catch {
    clearToken();
  }
});

async function login() {
  loading.value = true;
  try {
    const result = await api.login(loginForm.username, loginForm.password);
    saveToken(result.token);
    admin.value = result.admin;
    await loadCurrentMenu();
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : "登录失败");
  } finally {
    loading.value = false;
  }
}

function logout() {
  clearToken();
  admin.value = null;
}

async function switchMenu(menu: string) {
  activeMenu.value = menu;
  await loadCurrentMenu();
}

async function loadCurrentMenu() {
  loading.value = true;
  try {
    if (activeMenu.value === "dashboard") stats.value = await api.dashboard();
    if (activeMenu.value === "users") users.value = await api.users(userKeyword.value);
    if (activeMenu.value === "knowledge") knowledge.value = await api.knowledge();
    if (activeMenu.value === "prompt") promptContent.value = (await api.prompt()).promptContent;
    if (activeMenu.value === "models") models.value = await api.models();
    if (activeMenu.value === "configs") configs.value = await api.configs();
    if (activeMenu.value === "records") {
      chats.value = await api.chats(buildChatQuery());
      aiLogs.value = await api.aiLogs();
      operationLogs.value = await api.operationLogs();
    }
  } finally {
    loading.value = false;
  }
}

async function saveUser(row: AdminUser) {
  await api.updateUser(row.id, { status: row.status, dailyChatLimit: row.dailyChatLimit });
  ElMessage.success("用户已更新");
  await loadCurrentMenu();
}

async function saveKnowledge() {
  await api.createKnowledge({ ...knowledgeForm });
  ElMessage.success("知识库已新增");
  Object.assign(knowledgeForm, { name: "", feishuSpaceId: "", feishuNodeId: "", status: 1, remark: "" });
  await loadCurrentMenu();
}

async function savePrompt() {
  const result = await api.savePrompt(promptContent.value);
  promptContent.value = result.promptContent;
  ElMessage.success("Prompt 已保存");
}

async function resetPrompt() {
  const result = await api.resetPrompt();
  promptContent.value = result.promptContent;
  ElMessage.success("Prompt 已恢复默认");
}

async function saveModel() {
  if (!validateModelForm()) return;
  const payload = buildModelPayload();
  if (editingModelId.value) {
    await api.updateModel(editingModelId.value, payload);
    ElMessage.success("模型已更新");
  } else {
    await api.createModel(payload);
    ElMessage.success("模型已新增");
  }
  resetModelForm();
  await loadCurrentMenu();
}

function buildModelPayload() {
  const payload = { ...modelForm } as Record<string, unknown>;
  nullableModelFields.forEach((field) => {
    if (payload[field] === undefined || payload[field] === "") {
      payload[field] = null;
    }
  });
  return payload;
}

async function enableModel(id: number) {
  await api.enableModel(id);
  ElMessage.success("模型已启用");
  await loadCurrentMenu();
}

async function testModel(id: number) {
  const result = await api.testModel(id);
  if (result.ok) {
    ElMessage.success(result.message);
  } else {
    ElMessage.error(result.message);
  }
}

function applyModelPreset(label: string) {
  const preset = modelPresets.find((item) => item.label === label);
  if (!preset) return;
  Object.assign(
    modelForm,
    {
      apiVersion: "",
      authType: "bearer",
      temperature: 0.2,
      topP: null,
      topK: null,
      presencePenalty: null,
      frequencyPenalty: null,
      responseFormat: "",
      streamEnabled: 1,
    },
    preset,
  );
}

function editModel(row: ModelItem) {
  editingModelId.value = row.id;
  Object.assign(modelForm, {
    provider: row.provider,
    displayName: row.displayName ?? "",
    apiType: row.apiType,
    modelName: row.modelName,
    baseUrl: row.baseUrl ?? "",
    apiUrl: row.apiUrl,
    apiKey: "",
    authType: row.authType,
    apiVersion: row.apiVersion ?? "",
    temperature: row.temperature ?? null,
    topP: row.topP ?? null,
    topK: row.topK ?? null,
    presencePenalty: row.presencePenalty ?? null,
    frequencyPenalty: row.frequencyPenalty ?? null,
    maxToken: row.maxToken ?? 1024,
    contextWindow: row.contextWindow ?? null,
    streamEnabled: row.streamEnabled,
    responseFormat: row.responseFormat ?? "",
    extraParams: row.extraParams ?? "",
    remark: row.remark ?? "",
    timeoutSecond: row.timeoutSecond,
  });
}

function resetModelForm() {
  editingModelId.value = null;
  Object.assign(modelForm, {
    provider: "openai",
    displayName: "",
    apiType: "openai_compatible",
    modelName: "",
    baseUrl: "https://api.openai.com/v1",
    apiUrl: "",
    apiKey: "",
    authType: "bearer",
    apiVersion: "",
    temperature: 0.2,
    topP: null,
    topK: null,
    presencePenalty: null,
    frequencyPenalty: null,
    maxToken: 1024,
    contextWindow: null,
    streamEnabled: 1,
    responseFormat: "",
    extraParams: "",
    remark: "",
    timeoutSecond: 30,
  });
}

function validateModelForm() {
  if (!modelForm.apiUrl && !modelForm.baseUrl) {
    ElMessage.error("请填写 Base URL 或 API URL");
    return false;
  }
  if (!editingModelId.value && !modelForm.apiKey) {
    ElMessage.error("新增模型必须填写 API Key");
    return false;
  }
  if (modelForm.extraParams.trim()) {
    try {
      const extraParams = JSON.parse(modelForm.extraParams);
      if (!extraParams || Array.isArray(extraParams) || typeof extraParams !== "object") {
        throw new Error("高级 JSON 参数必须是对象");
      }
    } catch (error) {
      ElMessage.error(error instanceof Error ? error.message : "高级 JSON 参数不是合法 JSON");
      return false;
    }
  }
  return true;
}

async function saveConfig() {
  await api.saveConfig({ ...configForm });
  ElMessage.success("配置已保存");
  await loadCurrentMenu();
}

async function searchChats() {
  chats.value = await api.chats(buildChatQuery());
}

async function resetChatFilters() {
  Object.assign(chatFilters, { keyword: "", userId: undefined, status: "", dateRange: [] });
  await searchChats();
}

async function openChatDetail(row: ChatRecord) {
  chatDetail.value = await api.chatDetail(row.id);
  chatDetailOpen.value = true;
}

async function exportChats() {
  await api.exportChats(buildChatQuery());
}

function buildChatQuery() {
  return {
    keyword: chatFilters.keyword,
    userId: chatFilters.userId,
    status: chatFilters.status,
    dateFrom: chatFilters.dateRange?.[0],
    dateTo: chatFilters.dateRange?.[1],
  };
}
</script>

<template>
  <main v-if="!admin" class="login-page">
    <section class="login-box">
      <div class="brand">AI</div>
      <h1>AI 知识库后台</h1>
      <p>用于维护用户、知识库、Prompt、模型和审计记录。</p>
      <el-form label-position="top" @submit.prevent="login">
        <el-form-item label="管理员账号">
          <el-input v-model="loginForm.username" />
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="loginForm.password" type="password" show-password />
        </el-form-item>
        <el-button type="primary" :loading="loading" class="full-btn" @click="login">登录</el-button>
      </el-form>
    </section>
  </main>

  <main v-else class="admin-shell">
    <aside class="sidebar">
      <div class="sidebar-title">AI 知识库</div>
      <button :class="{ active: activeMenu === 'dashboard' }" @click="switchMenu('dashboard')">Dashboard</button>
      <button :class="{ active: activeMenu === 'users' }" @click="switchMenu('users')">用户管理</button>
      <button :class="{ active: activeMenu === 'knowledge' }" @click="switchMenu('knowledge')">知识库管理</button>
      <button :class="{ active: activeMenu === 'prompt' }" @click="switchMenu('prompt')">Prompt 管理</button>
      <button :class="{ active: activeMenu === 'models' }" @click="switchMenu('models')">模型管理</button>
      <button :class="{ active: activeMenu === 'configs' }" @click="switchMenu('configs')">系统配置</button>
      <button :class="{ active: activeMenu === 'records' }" @click="switchMenu('records')">记录审计</button>
    </aside>

    <section class="workspace">
      <header class="topbar">
        <div>
          <strong>{{ admin.name }}</strong>
          <span>管理员</span>
        </div>
        <el-button @click="logout">退出</el-button>
      </header>

      <section v-loading="loading" class="content">
        <template v-if="activeMenu === 'dashboard'">
          <div class="page-head">
            <h2>Dashboard</h2>
            <p>核心业务数据概览。</p>
          </div>
          <div class="stats-grid">
            <div class="stat"><span>用户数</span><strong>{{ stats?.userCount ?? 0 }}</strong></div>
            <div class="stat"><span>会话数</span><strong>{{ stats?.sessionCount ?? 0 }}</strong></div>
            <div class="stat"><span>消息数</span><strong>{{ stats?.messageCount ?? 0 }}</strong></div>
            <div class="stat"><span>AI 请求</span><strong>{{ stats?.aiRequestCount ?? 0 }}</strong></div>
            <div class="stat"><span>知识库</span><strong>{{ stats?.knowledgeCount ?? 0 }}</strong></div>
          </div>
        </template>

        <template v-if="activeMenu === 'users'">
          <div class="page-head inline">
            <div><h2>用户管理</h2><p>查询用户、启用禁用和调整额度。</p></div>
            <el-input v-model="userKeyword" placeholder="手机号或姓名" clearable @change="loadCurrentMenu" />
          </div>
          <el-table :data="users" stripe>
            <el-table-column prop="phone" label="手机号" width="150" />
            <el-table-column prop="name" label="姓名" width="140" />
            <el-table-column label="状态" width="130">
              <template #default="{ row }"><el-switch v-model="row.status" :active-value="1" :inactive-value="0" /></template>
            </el-table-column>
            <el-table-column label="每日额度" width="150">
              <template #default="{ row }"><el-input-number v-model="row.dailyChatLimit" :min="0" size="small" /></template>
            </el-table-column>
            <el-table-column prop="dailyChatUsed" label="已用" width="90" />
            <el-table-column label="操作" width="110">
              <template #default="{ row }"><el-button size="small" @click="saveUser(row)">保存</el-button></template>
            </el-table-column>
          </el-table>
        </template>

        <template v-if="activeMenu === 'knowledge'">
          <div class="page-head"><h2>知识库管理</h2><p>维护飞书知识库 SpaceID 和 NodeID。</p></div>
          <el-form class="inline-form" :model="knowledgeForm">
            <el-input v-model="knowledgeForm.name" placeholder="知识库名称" />
            <el-input v-model="knowledgeForm.feishuSpaceId" placeholder="SpaceID" />
            <el-input v-model="knowledgeForm.feishuNodeId" placeholder="NodeID" />
            <el-button type="primary" @click="saveKnowledge">新增</el-button>
          </el-form>
          <el-table :data="knowledge" stripe>
            <el-table-column prop="name" label="名称" />
            <el-table-column prop="feishuSpaceId" label="SpaceID" />
            <el-table-column prop="feishuNodeId" label="NodeID" />
            <el-table-column prop="status" label="状态" width="90" />
          </el-table>
        </template>

        <template v-if="activeMenu === 'prompt'">
          <div class="page-head inline">
            <div><h2>Prompt 管理</h2><p>保存后会影响后续问答 Prompt 组装。</p></div>
            <el-button @click="resetPrompt">恢复默认</el-button>
          </div>
          <el-input v-model="promptContent" type="textarea" :rows="16" />
          <div class="actions"><el-button type="primary" @click="savePrompt">保存 Prompt</el-button></div>
        </template>

        <template v-if="activeMenu === 'models'">
          <div class="page-head inline">
            <div><h2>模型管理</h2><p>支持 OpenAI 兼容、Anthropic Messages、Gemini generateContent 和常见第三方 LLM。</p></div>
            <el-button @click="resetModelForm">清空表单</el-button>
          </div>
          <el-form class="model-config-panel" label-position="top" :model="modelForm">
            <div class="model-config-grid">
              <el-form-item label="供应商预设">
                <el-select placeholder="选择预设" clearable @change="applyModelPreset">
                  <el-option v-for="preset in modelPresets" :key="preset.label" :label="preset.label" :value="preset.label" />
                </el-select>
              </el-form-item>
              <el-form-item label="供应商标识">
                <el-input v-model="modelForm.provider" placeholder="openai / deepseek / qwen" />
              </el-form-item>
              <el-form-item label="显示名称">
                <el-input v-model="modelForm.displayName" placeholder="例如：DeepSeek V3 生产" />
              </el-form-item>
              <el-form-item label="协议类型">
                <el-select v-model="modelForm.apiType">
                  <el-option label="OpenAI 兼容" value="openai_compatible" />
                  <el-option label="Anthropic Messages" value="anthropic_messages" />
                  <el-option label="Gemini generateContent" value="gemini_generate_content" />
                </el-select>
              </el-form-item>
              <el-form-item label="模型名">
                <el-input v-model="modelForm.modelName" placeholder="gpt-4.1 / deepseek-chat / claude..." />
              </el-form-item>
              <el-form-item label="Base URL">
                <el-input v-model="modelForm.baseUrl" placeholder="https://api.example.com/v1" />
              </el-form-item>
              <el-form-item label="API URL（可覆盖）">
                <el-input v-model="modelForm.apiUrl" placeholder="留空则按协议自动拼接" />
              </el-form-item>
              <el-form-item label="鉴权方式">
                <el-select v-model="modelForm.authType">
                  <el-option label="Bearer Token" value="bearer" />
                  <el-option label="x-api-key" value="api_key" />
                </el-select>
              </el-form-item>
              <el-form-item label="API Key">
                <el-input v-model="modelForm.apiKey" placeholder="保存时会覆盖旧 Key" show-password />
              </el-form-item>
              <el-form-item label="API Version">
                <el-input v-model="modelForm.apiVersion" placeholder="Anthropic 默认 2023-06-01" />
              </el-form-item>
              <el-form-item label="Temperature">
                <el-input-number v-model="modelForm.temperature" :min="0" :max="2" :step="0.1" />
              </el-form-item>
              <el-form-item label="Top P">
                <el-input-number v-model="modelForm.topP" :min="0" :max="1" :step="0.05" />
              </el-form-item>
              <el-form-item label="Top K">
                <el-input-number v-model="modelForm.topK" :min="1" :max="1000" />
              </el-form-item>
              <el-form-item label="Max Tokens">
                <el-input-number v-model="modelForm.maxToken" :min="1" :max="100000" />
              </el-form-item>
              <el-form-item label="上下文窗口">
                <el-input-number v-model="modelForm.contextWindow" :min="1" :max="2000000" />
              </el-form-item>
              <el-form-item label="Presence Penalty">
                <el-input-number v-model="modelForm.presencePenalty" :min="-2" :max="2" :step="0.1" />
              </el-form-item>
              <el-form-item label="Frequency Penalty">
                <el-input-number v-model="modelForm.frequencyPenalty" :min="-2" :max="2" :step="0.1" />
              </el-form-item>
              <el-form-item label="流式输出">
                <el-switch v-model="modelForm.streamEnabled" :active-value="1" :inactive-value="0" />
              </el-form-item>
              <el-form-item label="响应格式">
                <el-select v-model="modelForm.responseFormat" clearable>
                  <el-option label="默认文本" value="" />
                  <el-option label="JSON Object" value="json_object" />
                </el-select>
              </el-form-item>
              <el-form-item label="超时秒数">
                <el-input-number v-model="modelForm.timeoutSecond" :min="1" :max="300" />
              </el-form-item>
            </div>
            <el-form-item label="高级 JSON 参数">
              <el-input
                v-model="modelForm.extraParams"
                type="textarea"
                :rows="4"
                placeholder='例如：{"stop":["###"],"seed":42}'
              />
            </el-form-item>
            <el-form-item label="备注">
              <el-input v-model="modelForm.remark" placeholder="用途、额度、注意事项等" />
            </el-form-item>
            <div class="actions">
              <el-button type="primary" @click="saveModel">{{ editingModelId ? "保存模型" : "新增模型" }}</el-button>
              <el-button @click="resetModelForm">取消编辑</el-button>
            </div>
          </el-form>
          <el-table :data="models" stripe>
            <el-table-column prop="displayName" label="显示名称" width="170" />
            <el-table-column prop="provider" label="Provider" />
            <el-table-column prop="apiType" label="协议" width="170" />
            <el-table-column prop="modelName" label="模型" />
            <el-table-column prop="baseUrl" label="Base URL" min-width="220" show-overflow-tooltip />
            <el-table-column prop="temperature" label="温度" width="80" />
            <el-table-column prop="topP" label="Top P" width="80" />
            <el-table-column prop="maxToken" label="Max" width="90" />
            <el-table-column prop="enabled" label="启用" width="90" />
            <el-table-column label="操作" width="210" fixed="right">
              <template #default="{ row }">
                <el-button size="small" @click="editModel(row)">编辑</el-button>
                <el-button size="small" @click="testModel(row.id)">测试</el-button>
                <el-button size="small" type="primary" @click="enableModel(row.id)">启用</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>

        <template v-if="activeMenu === 'configs'">
          <div class="page-head"><h2>系统配置</h2><p>维护运行时配置项。</p></div>
          <el-form class="inline-form" :model="configForm">
            <el-input v-model="configForm.configKey" placeholder="配置 Key" />
            <el-input v-model="configForm.configValue" placeholder="配置值" />
            <el-input v-model="configForm.description" placeholder="说明" />
            <el-button type="primary" @click="saveConfig">保存</el-button>
          </el-form>
          <el-table :data="configs" stripe>
            <el-table-column prop="configKey" label="Key" />
            <el-table-column prop="configValue" label="Value" />
            <el-table-column prop="description" label="说明" />
          </el-table>
        </template>

        <template v-if="activeMenu === 'records'">
          <div class="page-head"><h2>记录审计</h2><p>聊天、AI 请求和后台操作记录。</p></div>
          <el-tabs v-model="recordTab">
            <el-tab-pane label="聊天记录" name="chats">
              <div class="record-filter">
                <el-input v-model="chatFilters.keyword" placeholder="搜索标题、手机号、姓名、聊天内容" clearable />
                <el-input-number v-model="chatFilters.userId" :min="1" placeholder="用户ID" />
                <el-select v-model="chatFilters.status" placeholder="消息状态" clearable>
                  <el-option label="全部状态" value="" />
                  <el-option label="已完成" value="FINISHED" />
                  <el-option label="生成中" value="GENERATING" />
                  <el-option label="已停止" value="STOPPED" />
                  <el-option label="失败" value="FAILED" />
                </el-select>
                <el-date-picker
                  v-model="chatFilters.dateRange"
                  type="datetimerange"
                  start-placeholder="开始时间"
                  end-placeholder="结束时间"
                  value-format="YYYY-MM-DDTHH:mm:ss"
                />
                <el-button type="primary" @click="searchChats">搜索</el-button>
                <el-button @click="resetChatFilters">重置</el-button>
                <el-button @click="exportChats">导出</el-button>
              </div>
              <el-table :data="chats" stripe>
                <el-table-column prop="id" label="会话ID" width="90" />
                <el-table-column prop="userPhone" label="手机号" width="140" />
                <el-table-column prop="userName" label="用户" width="120" />
                <el-table-column prop="title" label="会话标题" min-width="220" show-overflow-tooltip />
                <el-table-column prop="messageCount" label="消息数" width="90" />
                <el-table-column prop="lastMessageAt" label="最后消息" width="180" />
                <el-table-column label="操作" width="100" fixed="right">
                  <template #default="{ row }">
                    <el-button size="small" @click="openChatDetail(row)">详情</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="AI 请求" name="aiLogs">
              <el-table :data="aiLogs" stripe>
                <el-table-column prop="sessionId" label="会话ID" width="90" />
                <el-table-column prop="modelName" label="模型" width="160" />
                <el-table-column prop="knowledgeIds" label="知识库" width="120" />
                <el-table-column prop="retrieveCount" label="命中" width="80" />
                <el-table-column prop="totalToken" label="Token" width="90" />
                <el-table-column prop="costMs" label="耗时(ms)" width="100" />
                <el-table-column prop="status" label="状态" width="100" />
                <el-table-column prop="errorMessage" label="错误" min-width="220" show-overflow-tooltip />
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="操作日志" name="operationLogs">
              <el-table :data="operationLogs" stripe>
                <el-table-column prop="module" label="模块" />
                <el-table-column prop="action" label="动作" />
                <el-table-column prop="result" label="结果" />
                <el-table-column prop="createdAt" label="时间" />
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </template>
      </section>
    </section>

    <el-drawer v-model="chatDetailOpen" size="760px" title="聊天详情">
      <template v-if="chatDetail">
        <section class="chat-summary">
          <div><span>会话ID</span><strong>{{ chatDetail.session.id }}</strong></div>
          <div><span>用户</span><strong>{{ chatDetail.session.userName || '-' }}</strong></div>
          <div><span>手机号</span><strong>{{ chatDetail.session.userPhone || '-' }}</strong></div>
          <div><span>消息数</span><strong>{{ chatDetail.session.messageCount }}</strong></div>
        </section>

        <h3 class="detail-title">完整对话</h3>
        <section class="conversation-list">
          <article
            v-for="message in chatDetail.messages"
            :key="message.id"
            class="conversation-message"
            :class="message.role"
          >
            <div class="message-meta">
              <strong>{{ message.role === 'user' ? '用户' : 'AI 助手' }}</strong>
              <span>{{ message.createdAt }}</span>
            </div>
            <pre>{{ message.content }}</pre>
            <div class="message-extra">
              <span>状态：{{ message.messageStatus }}</span>
              <span v-if="message.tokenInput">输入 Token：{{ message.tokenInput }}</span>
              <span v-if="message.tokenOutput">输出 Token：{{ message.tokenOutput }}</span>
              <span v-if="message.responseTimeMs">耗时：{{ message.responseTimeMs }}ms</span>
            </div>
          </article>
        </section>

        <h3 class="detail-title">关联 AI 请求</h3>
        <el-collapse>
          <el-collapse-item v-for="log in chatDetail.aiLogs" :key="log.id" :title="`请求 #${log.id} / ${log.status}`">
            <div class="ai-log-grid">
              <span>模型：{{ log.modelName || '-' }}</span>
              <span>知识库：{{ log.knowledgeIds || '-' }}</span>
              <span>命中数：{{ log.retrieveCount }}</span>
              <span>Token：{{ log.totalToken || '-' }}</span>
              <span>耗时：{{ log.costMs || '-' }}ms</span>
              <span>时间：{{ log.createdAt }}</span>
            </div>
            <pre class="prompt-preview">{{ log.prompt || '无 Prompt 记录' }}</pre>
            <p v-if="log.errorMessage" class="error-text">{{ log.errorMessage }}</p>
          </el-collapse-item>
        </el-collapse>
      </template>
    </el-drawer>
  </main>
</template>
