<template>
  <div class="rag-evaluation-container">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <!-- 基准选择 -->
        <div class="benchmark-selector">
          <label class="selector-label">评估基准</label>
          <a-select
            v-model:value="selectedBenchmarkId"
            placeholder="请选择评估基准"
            style="width: 240px"
            @change="onBenchmarkChanged"
            :loading="benchmarksLoading"
          >
            <a-select-option
              v-for="benchmark in availableBenchmarks"
              :key="benchmark.benchmark_id"
              :value="benchmark.benchmark_id"
            >
              {{ benchmark.name }} ({{ benchmark.question_count }} 个问题)
            </a-select-option>
          </a-select>
          <a-button
            type="text"
            size="middle"
            :loading="benchmarksLoading"
            @click="() => loadBenchmarks(true)"
            :icon="h(ReloadOutlined)"
            class="refresh-benchmarks-btn"
            title="刷新评估基准列表"
          />
        </div>
      </div>
      <div class="toolbar-right">
        <!-- 检索配置按钮 -->
        <a-button size="middle" @click="openSearchConfigModal" :icon="h(SettingOutlined)" />
        <!-- 开始评估按钮 -->
        <a-button
          type="primary"
          :loading="startingEvaluation"
          @click="startEvaluation"
          :disabled="!selectedBenchmark"
          size="middle"
        >
          开始评估
        </a-button>
      </div>
    </div>

    <!-- 评估结果区域 -->
    <div class="evaluation-results">
      <!-- 模型配置（仅在选中基准且需要时显示） -->
      <div
        v-if="
          selectedBenchmark &&
          (selectedBenchmark.has_gold_chunks || selectedBenchmark.has_gold_answers)
        "
        class="model-config-section"
      >
        <a-row :gutter="24">
          <a-col :span="12">
            <a-form-item
              :label="
                selectedBenchmark.has_gold_answers
                  ? '答案生成模型（可选）'
                  : '答案生成模型（当前基准无需）'
              "
            >
              <ModelSelectorComponent
                v-model:model_spec="configForm.answer_llm"
                size="small"
                :disabled="!selectedBenchmark || !selectedBenchmark.has_gold_answers"
                @select-model="(value) => (configForm.answer_llm = value)"
                style="width: 100%"
              />
            </a-form-item>
          </a-col>

          <a-col :span="12">
            <a-form-item
              :label="
                selectedBenchmark.has_gold_answers
                  ? '答案评判模型（可选）'
                  : '答案评判模型（当前基准无需）'
              "
            >
              <ModelSelectorComponent
                v-model:model_spec="configForm.judge_llm"
                size="small"
                :disabled="!selectedBenchmark || !selectedBenchmark.has_gold_answers"
                @select-model="(value) => (configForm.judge_llm = value)"
                style="width: 100%"
              />
            </a-form-item>
          </a-col>
        </a-row>
      </div>

      <template v-if="!selectedBenchmark">
        <div class="empty-state">
          <a-empty description="请在顶部选择评估基准或前往基准管理">
            <a-space>
              <a-button @click="$emit('switch-to-benchmarks')"> 前往基准管理 </a-button>
            </a-space>
          </a-empty>
        </div>
      </template>
      <template v-else>
        <!-- 历史评估记录 -->
        <div class="history-section">
          <div class="section-header">
            <h4 class="section-title">历史评估记录</h4>
            <a-button
              type="text"
              size="small"
              :loading="refreshingHistory"
              @click="refreshHistory"
              :icon="h('ReloadOutlined')"
              class="refresh-btn"
            >
              刷新
            </a-button>
          </div>
          <a-table
            class="history-table"
            :columns="historyColumns"
            :data-source="evaluationHistory"
            :pagination="{ pageSize: 10 }"
            size="small"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'status'">
                <a-tag :color="getStatusColor(record.status)">
                  {{ getStatusText(record.status) }}
                </a-tag>
              </template>
              <template v-else-if="column.key === 'overall_score'">
                <span v-if="record.overall_score !== null">
                  <a-tag :color="getScoreTagColor(record.overall_score)">
                    {{ (record.overall_score * 100).toFixed(0) }}%
                  </a-tag>
                </span>
                <span v-else>-</span>
              </template>
              <template v-else-if="column.key === 'actions'">
                <a-space>
                  <a-button
                    v-if="record.status === 'completed'"
                    type="link"
                    size="small"
                    @click="viewResults(record.task_id)"
                  >
                    查看结果
                  </a-button>
                  <a-popconfirm
                    title="确定要删除这条评估记录吗？"
                    description="删除后将无法恢复"
                    @confirm="deleteEvaluationRecord(record.task_id)"
                    ok-text="确定"
                    cancel-text="取消"
                  >
                    <a-button type="link" size="small" danger :loading="record.deleting">
                      删除
                    </a-button>
                  </a-popconfirm>
                </a-space>
              </template>
            </template>
          </a-table>
        </div>
      </template>
    </div>
  </div>

  <!-- 评估结果详情模态框 -->
  <a-modal
    v-model:open="resultModalVisible"
    :title="`评估结果 - ${selectedResult?.task_id?.slice(0, 8) || ''}`"
    width="1200px"
    :footer="null"
  >
    <div v-if="resultsLoading" class="loading-container">
      <a-spin size="large" />
      <p style="margin-top: 16px; color: var(--gray-600)">正在加载评估结果...</p>
    </div>

    <div v-else-if="selectedResult && detailedResults.length > 0">
      <!-- 基本信息 -->
      <a-descriptions
        title="基本信息"
        :column="3"
        size="small"
        bordered
        style="margin-bottom: 20px"
      >
        <a-descriptions-item label="任务ID">{{ selectedResult.task_id }}</a-descriptions-item>
        <a-descriptions-item label="状态">
          <a-tag :color="getStatusColor(selectedResult.status)">
            {{ getStatusText(selectedResult.status) }}
          </a-tag>
        </a-descriptions-item>
        <a-descriptions-item label="总体评分">
          <span v-if="selectedResult.overall_score !== null">
            <a-tag :color="getScoreTagColor(selectedResult.overall_score)">
              {{ (selectedResult.overall_score * 100).toFixed(1) }}%
            </a-tag>
          </span>
          <span v-else>-</span>
        </a-descriptions-item>
        <a-descriptions-item label="总问题数">{{
          selectedResult.total_questions
        }}</a-descriptions-item>
        <a-descriptions-item label="完成数">{{
          selectedResult.completed_questions
        }}</a-descriptions-item>
        <a-descriptions-item label="总耗时">
          <span v-if="evaluationStats.totalDuration">
            {{ formatDuration(evaluationStats.totalDuration) }}
          </span>
          <span v-else>-</span>
        </a-descriptions-item>
      </a-descriptions>

      <!-- 检索配置和整体评估报告 -->
      <a-row :gutter="16" style="margin-bottom: 20px">
        <!-- 检索配置 -->
        <a-col :span="12" v-if="selectedResult.retrieval_config">
          <a-card size="small" title="检索配置">
            <div class="json-viewer-container">
              <pre class="json-viewer">{{
                JSON.stringify(selectedResult.retrieval_config, null, 2)
              }}</pre>
            </div>
          </a-card>
        </a-col>

        <!-- 整体评估报告 -->
        <a-col :span="selectedResult.retrieval_config ? 12 : 24">
          <a-card size="small" title="整体评估报告">
            <!-- 检索指标 -->
            <div style="margin-bottom: 20px">
              <h5 style="margin-bottom: 12px; font-size: 14px; font-weight: 500">检索指标</h5>
              <div v-if="Object.keys(evaluationStats.retrievalMetrics || {}).length > 0">
                <div
                  v-for="(value, key) in evaluationStats.retrievalMetrics"
                  :key="key"
                  class="report-metric"
                >
                  <span class="metric-label">{{ getMetricTitle(key) }}：</span>
                  <span class="metric-value" :style="{ color: getScoreColor(value) }">
                    {{ formatMetricValue(value) }}
                  </span>
                </div>
              </div>
              <span v-else class="no-metrics">-</span>
            </div>

            <!-- 答案准确性 -->
            <div>
              <h5 style="margin-bottom: 12px; font-size: 14px; font-weight: 500">答案准确性</h5>
              <div class="accuracy-stats">
                <div class="accuracy-item">
                  <span class="accuracy-label">正确答案数：</span>
                  <span class="accuracy-value"
                    >{{ evaluationStats.correctAnswers || 0 }} /
                    {{ evaluationStats.totalQuestions || 0 }}</span
                  >
                </div>
                <div class="accuracy-item">
                  <span class="accuracy-label">准确率：</span>
                  <span
                    class="accuracy-value"
                    :style="{ color: getScoreColor(evaluationStats.answerAccuracy) }"
                  >
                    {{ (evaluationStats.answerAccuracy * 100).toFixed(1) }}%
                  </span>
                </div>
              </div>
            </div>
          </a-card>
        </a-col>
      </a-row>

      <!-- 详细结果表格 -->
      <div
        style="
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 16px;
        "
      >
        <div>
          <h4 style="margin: 0">详细评估结果</h4>
          <span style="font-size: 12px; color: var(--gray-600); margin-left: 8px">
            {{
              showErrorsOnly
                ? `仅显示错误结果（共 ${paginationTotal} 条）`
                : `显示全部结果（共 ${paginationTotal} 条）`
            }}
          </span>
        </div>
        <a-button
          type="default"
          size="small"
          @click="toggleErrorOnly"
          :class="{ 'error-only-active': showErrorsOnly }"
        >
          {{ showErrorsOnly ? '显示全部' : '仅查看错误' }}
        </a-button>
      </div>
      <a-table
        :columns="resultColumns"
        :data-source="detailedResults"
        :pagination="{
          current: currentPage,
          pageSize: pageSize,
          total: paginationTotal,
          showSizeChanger: true,
          showQuickJumper: true,
          showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条，共 ${total} 条`,
          onChange: handlePageChange,
          onShowSizeChange: handlePageSizeChange
        }"
        :scroll="{ x: 1000 }"
        size="small"
        :loading="resultsLoading"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'query'">
            <a-tooltip :title="record.query">
              <div class="query-text">{{ record.query }}</div>
            </a-tooltip>
          </template>
          <template v-else-if="column.key === 'generated_answer'">
            <a-tooltip :title="record.generated_answer">
              <div class="answer-text">{{ record.generated_answer || '-' }}</div>
            </a-tooltip>
          </template>
          <template v-else-if="column.key === 'retrieval_score'">
            <div
              v-if="
                record.metrics &&
                Object.keys(record.metrics).some(
                  (k) =>
                    k.startsWith('recall') ||
                    k.startsWith('precision') ||
                    k === 'map' ||
                    k === 'ndcg'
                )
              "
              class="retrieval-metrics"
            >
              <div v-for="(val, key) in record.metrics" :key="key" class="metric-item">
                <span
                  v-if="
                    key.startsWith('recall') ||
                    key.startsWith('precision') ||
                    key === 'map' ||
                    key === 'ndcg'
                  "
                  class="metric-content"
                  :class="`metric-${getMetricType(key)}`"
                >
                  <span class="metric-name">{{ getMetricShortName(key) }}</span>
                  <span class="metric-value">{{ formatMetricValue(val) }}</span>
                </span>
              </div>
            </div>
            <span v-else class="no-metrics">-</span>
          </template>
          <template v-else-if="column.key === 'answer_score'">
            <div v-if="record.metrics && record.metrics.score !== undefined">
              <a-tag :color="record.metrics.score > 0.5 ? 'green' : 'red'">
                {{ record.metrics.score === 1.0 ? '正确' : '错误' }}
              </a-tag>
              <div v-if="record.metrics.reasoning" class="answer-reasoning">
                <a-tooltip :title="record.metrics.reasoning">
                  {{ record.metrics.reasoning }}
                </a-tooltip>
              </div>
            </div>
            <span v-else>-</span>
          </template>
        </template>
      </a-table>
    </div>

    <div v-else-if="selectedResult" class="empty-results">
      <a-empty description="暂无详细结果数据">
        <a-button @click="viewDetails(selectedResult)">查看基本信息</a-button>
      </a-empty>
    </div>
  </a-modal>

  <!-- 检索配置弹窗 -->
  <SearchConfigModal
    v-model="searchConfigModalVisible"
    :database-id="databaseId"
    @save="handleSearchConfigSave"
  />
</template>

<script setup>
import { ref, reactive, onMounted, computed, h } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { evaluationApi } from '@/apis/knowledge_api'
import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'
import SearchConfigModal from './SearchConfigModal.vue'
import { SettingOutlined, ReloadOutlined } from '@ant-design/icons-vue'
import { useTaskerStore } from '@/stores/tasker'

const props = defineProps({
  databaseId: {
    type: String,
    required: true
  }
})

const emit = defineEmits(['switch-to-benchmarks'])

// 使用任务中心 store
const taskerStore = useTaskerStore()

// 状态
const selectedBenchmarkId = ref(null)
const selectedBenchmark = ref(null)
const benchmarksLoading = ref(false)
const availableBenchmarks = ref([])
const startingEvaluation = ref(false)
const evaluationHistory = ref([])
const resultModalVisible = ref(false)
const selectedResult = ref(null)
const detailedResults = ref([])
const evaluationStats = ref({})
const resultsLoading = ref(false)
const searchConfigModalVisible = ref(false)
const refreshingHistory = ref(false)
const showErrorsOnly = ref(false)
const currentPage = ref(1)
const pageSize = ref(20)
const paginationTotal = ref(0)
const paginationTotalPages = ref(0)

// 评估配置表单（使用知识库默认配置）
const configForm = reactive({
  answer_llm: '', // 答案生成模型
  judge_llm: '' // 评判模型
})

// 表格列定义
const resultColumns = computed(() => {
  const columns = [
    {
      title: '问题',
      dataIndex: 'query',
      key: 'query',
      width: 100
    },
    {
      title: '生成答案',
      key: 'generated_answer',
      width: 180
    },
    {
      title: '答案评判',
      key: 'answer_score',
      width: 260
    }
  ]

  // 检查是否有检索指标数据
  const hasRetrievalMetrics = detailedResults.value.some((item) => {
    if (!item.metrics) return false
    return Object.keys(item.metrics).some(
      (key) =>
        key.startsWith('recall') || key.startsWith('precision') || key === 'map' || key === 'ndcg'
    )
  })

  // 如果有检索指标数据，添加检索指标列
  if (hasRetrievalMetrics) {
    columns.splice(2, 0, {
      title: '检索指标',
      key: 'retrieval_score',
      width: 100
    })
  }

  return columns
})

const historyColumns = [
  {
    title: '开始时间',
    dataIndex: 'started_at',
    key: 'started_at',
    width: 180,
    customRender: ({ record }) => formatTime(record.started_at)
  },
  {
    title: '评估基准',
    key: 'benchmark_name',
    width: 200,
    customRender: ({ record }) => {
      // 根据 benchmark_id 查找基准名称
      const benchmark = availableBenchmarks.value.find(
        (b) => b.benchmark_id === record.benchmark_id
      )
      return benchmark ? benchmark.name : record.benchmark_id?.slice(0, 8) || '-'
    }
  },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
    width: 100
  },
  {
    title: 'Recall@10',
    key: 'recall_10',
    width: 100,
    customRender: ({ record }) => {
      // 使用后端返回的 metrics.recall@10 数据
      if (
        record.metrics &&
        record.metrics['recall@10'] !== undefined &&
        record.metrics['recall@10'] !== null
      ) {
        const recallValue = record.metrics['recall@10']
        const displayValue = formatMetricValue(recallValue)
        return h(
          'a-tag',
          {
            color: getScoreTagColor(recallValue)
          },
          displayValue
        )
      }

      // 如果是运行中的任务，显示计算中
      if (record.status === 'running') {
        return h(
          'a-tag',
          {
            color: 'processing'
          },
          '计算中'
        )
      }

      // 已完成但没有 recall@10 数据
      if (record.status === 'completed') {
        return h(
          'a-tag',
          {
            color: 'default'
          },
          '无数据'
        )
      }

      // 其他情况显示横线
      return h('span', '-')
    }
  },
  {
    title: '操作',
    key: 'actions',
    width: 150
  }
]

// 计算属性：当前选中的基准对象
const currentBenchmark = computed(() => {
  if (!selectedBenchmarkId.value || !availableBenchmarks.value) {
    return null
  }
  return availableBenchmarks.value.find((b) => b.benchmark_id === selectedBenchmarkId.value)
})

// 切换错误显示模式
const toggleErrorOnly = async () => {
  resultsLoading.value = true
  showErrorsOnly.value = !showErrorsOnly.value
  currentPage.value = 1 // 切换模式时重置到第一页

  // 立即加载新的分页数据
  await loadResultsWithPagination()
}

// 处理分页变化
const handlePageChange = (page, size) => {
  currentPage.value = page
  if (size !== pageSize.value) {
    pageSize.value = size
  }
  loadResultsWithPagination()
}

// 处理页面大小变化
const handlePageSizeChange = (current, size) => {
  currentPage.value = 1
  pageSize.value = size
  loadResultsWithPagination()
}

// 加载分页结果
const loadResultsWithPagination = async () => {
  if (!selectedResult.value) return

  try {
    resultsLoading.value = true
    const response = await evaluationApi.getEvaluationResultsByDb(
      props.databaseId,
      selectedResult.value.task_id,
      {
        page: currentPage.value,
        pageSize: pageSize.value,
        errorOnly: showErrorsOnly.value
      }
    )

    if (response.message === 'success' && response.data) {
      const resultData = response.data

      // 更新详细结果
      detailedResults.value = resultData.interim_results || []

      // 更新分页信息
      if (resultData.pagination) {
        paginationTotal.value = resultData.pagination.total
        paginationTotalPages.value = resultData.pagination.total_pages
      } else {
        // 兼容旧格式数据
        paginationTotal.value = detailedResults.value.length
        paginationTotalPages.value = 1
      }

      // 更新统计信息
      // 如果是过滤模式，需要基于过滤后的总数计算统计
      if (showErrorsOnly.value) {
        // 在过滤模式下，只计算当前页的统计（避免重复计算）
        evaluationStats.value = {
          ...evaluationStats.value,
          totalQuestions: paginationTotal.value
          // 可以在这里添加其他基于过滤后数据的统计
        }
      } else if (currentPage.value === 1) {
        // 非过滤模式且是第一页时，才计算完整统计
        evaluationStats.value = calculateEvaluationStats(detailedResults.value)
      }

      // 更新其他基本信息（保持原有的信息不变）
      if (resultData.started_at && resultData.completed_at) {
        const startTime = new Date(resultData.started_at)
        const endTime = new Date(resultData.completed_at)
        evaluationStats.value.totalDuration = (endTime - startTime) / 1000
      }
    }
  } catch (error) {
    console.error('加载评估结果失败:', error)
    message.error('加载评估结果失败')
  } finally {
    resultsLoading.value = false
  }
}

// 打开检索配置弹窗
const openSearchConfigModal = () => {
  searchConfigModalVisible.value = true
}

// 处理检索配置保存
const handleSearchConfigSave = (config) => {
  console.log('RAG评估中的检索配置已更新:', config)
  // 可以在这里添加配置更新后的处理逻辑
}

// 加载基准列表
const loadBenchmarks = async (showSuccessMessage = false) => {
  if (!props.databaseId) return

  benchmarksLoading.value = true
  try {
    const response = await evaluationApi.getBenchmarks(props.databaseId)

    if (response && response.message === 'success' && Array.isArray(response.data)) {
      availableBenchmarks.value = response.data

      // 如果没有选中的基准，且有可用基准，默认选中第一个
      if (!selectedBenchmarkId.value && response.data.length > 0) {
        selectedBenchmarkId.value = response.data[0].benchmark_id
        selectedBenchmark.value = response.data[0]
      } else if (selectedBenchmarkId.value) {
        // 如果之前有选中的基准，重新验证其有效性
        const exists = response.data.some((b) => b.benchmark_id === selectedBenchmarkId.value)
        if (!exists) {
          selectedBenchmarkId.value = null
          selectedBenchmark.value = null
        } else {
          // 更新选中的基准对象
          selectedBenchmark.value = response.data.find(
            (b) => b.benchmark_id === selectedBenchmarkId.value
          )
        }
      }

      // 如果是手动刷新，显示成功提示
      if (showSuccessMessage) {
        message.success(`已刷新，找到 ${response.data.length} 个评估基准`)
      }
    } else {
      console.error('响应格式不符合预期:', response)
      message.error('基准数据格式错误')
    }
  } catch (error) {
    console.error('加载评估基准失败:', error)
    message.error('加载评估基准失败')
  } finally {
    benchmarksLoading.value = false
  }
}

// 下拉框选择变化
const onBenchmarkChanged = (benchmarkId) => {
  const benchmark = availableBenchmarks.value.find((b) => b.benchmark_id === benchmarkId)
  selectedBenchmark.value = benchmark || null
}

// 刷新历史评估记录
const refreshHistory = async () => {
  refreshingHistory.value = true
  try {
    await loadEvaluationHistory()
    message.success('历史记录已刷新')
  } catch (error) {
    console.error('刷新历史记录失败:', error)
    message.error('刷新历史记录失败')
  } finally {
    refreshingHistory.value = false
  }
}

// 开始评估
const startEvaluation = async () => {
  if (!selectedBenchmark.value) {
    message.error('请先选择评估基准')
    return
  }

  // 校验模型选择：必须同时选择或同时不选择
  const hasAnswerModel = !!configForm.answer_llm
  const hasJudgeModel = !!configForm.judge_llm

  if (hasAnswerModel !== hasJudgeModel) {
    message.warning('生成模型和评估模型必须同时选择或者同时不选择')
    return
  }

  const runEvaluation = async () => {
    startingEvaluation.value = true

    // 只传递模型配置，检索配置由服务器从知识库读取
    const params = {
      benchmark_id: selectedBenchmark.value.benchmark_id,
      model_config: {
        answer_llm: configForm.answer_llm, // 传递答案生成模型
        judge_llm: configForm.judge_llm // 传递评判模型
      }
    }

    try {
      const response = await evaluationApi.runEvaluation(props.databaseId, params)

      if (response.message === 'success') {
        message.success('评估任务已开始')
        loadEvaluationHistory()
        // 刷新任务中心的任务列表
        taskerStore.loadTasks()
      } else {
        message.error(response.message || '启动评估失败')
      }
    } catch (error) {
      console.error('启动评估失败:', error)
      message.error('启动评估失败')
    } finally {
      startingEvaluation.value = false
    }
  }

  if (!hasAnswerModel) {
    Modal.confirm({
      title: '确认评估模式',
      content: '您未选择答案生成模型，将仅进行检索测试，不会进行问答测试。是否继续？',
      okText: '继续',
      cancelText: '取消',
      onOk: runEvaluation
    })
  } else {
    runEvaluation()
  }
}

// 加载评估历史
const loadEvaluationHistory = async () => {
  try {
    const response = await evaluationApi.getEvaluationHistory(props.databaseId)
    if (response.message === 'success') {
      evaluationHistory.value = response.data || []
    }
  } catch (error) {
    console.error('加载评估历史失败:', error)
    message.error('加载评估历史失败')
  }
}

// 计算评估统计信息
const calculateEvaluationStats = (results) => {
  if (!results || results.length === 0) {
    return {}
  }

  const stats = {
    totalQuestions: results.length,
    retrievalMetrics: {},
    answerAccuracy: 0,
    correctAnswers: 0,
    averageResponseTime: 0,
    totalResponseTime: 0
  }

  const metricSums = {}
  const metricCounts = {}

  results.forEach((item) => {
    // 答案准确率
    if (item.metrics && item.metrics.score !== undefined) {
      if (item.metrics.score > 0.5) {
        stats.correctAnswers++
      }
    }

    // 检索指标统计
    if (item.metrics) {
      Object.keys(item.metrics).forEach((key) => {
        if (
          key.startsWith('recall') ||
          key.startsWith('precision') ||
          key === 'map' ||
          key === 'ndcg'
        ) {
          if (!metricSums[key]) {
            metricSums[key] = 0
            metricCounts[key] = 0
          }
          metricSums[key] += item.metrics[key]
          metricCounts[key]++
        }
      })
    }
  })

  // 计算平均值
  Object.keys(metricSums).forEach((key) => {
    stats.retrievalMetrics[key] = metricSums[key] / metricCounts[key]
  })

  // 计算答案准确率
  stats.answerAccuracy = stats.totalQuestions > 0 ? stats.correctAnswers / stats.totalQuestions : 0

  return stats
}

// 查看结果
const viewResults = async (taskId) => {
  try {
    resultsLoading.value = true

    // 重置分页状态
    currentPage.value = 1
    showErrorsOnly.value = false

    // 先获取基本信息（不分页）
    const response = await evaluationApi.getEvaluationResultsByDb(props.databaseId, taskId)

    if (response.message === 'success' && response.data) {
      const resultData = response.data

      // 从历史记录中找到对应的任务信息，如果没有则使用API返回的数据
      selectedResult.value = evaluationHistory.value.find((r) => r.task_id === taskId) || {
        task_id: resultData.task_id,
        status: resultData.status,
        started_at: resultData.started_at,
        completed_at: resultData.completed_at,
        total_questions: resultData.total_questions || 0,
        completed_questions: resultData.completed_questions || 0,
        overall_score: resultData.overall_score,
        retrieval_config: resultData.retrieval_config
      }

      // 如果是从历史记录获取的，确保也有 retrieval_config
      if (selectedResult.value && !selectedResult.value.retrieval_config) {
        selectedResult.value.retrieval_config = resultData.retrieval_config
      }

      // 打开模态框
      resultModalVisible.value = true

      // 加载分页数据
      await loadResultsWithPagination()
    } else {
      message.error('获取评估结果失败：数据格式错误')
    }
  } catch (error) {
    console.error('获取评估结果失败:', error)
    message.error('获取评估结果失败')
  } finally {
    resultsLoading.value = false
  }
}

// 删除评估记录
const deleteEvaluationRecord = async (taskId) => {
  try {
    // 找到对应的记录并设置loading状态
    const record = evaluationHistory.value.find((r) => r.task_id === taskId)
    if (record) {
      record.deleting = true
    }

    const response = await evaluationApi.deleteEvaluationResultByDb(props.databaseId, taskId)
    if (response.message === 'success') {
      message.success('删除成功')
      // 重新加载评估历史
      await loadEvaluationHistory()
    }
  } catch (error) {
    console.error('删除评估记录失败:', error)
    message.error('删除评估记录失败')
  } finally {
    // 清除loading状态
    const record = evaluationHistory.value.find((r) => r.task_id === taskId)
    if (record) {
      record.deleting = false
    }
  }
}

// 工具函数
const truncateText = (text, maxLength) => {
  if (!text) return ''
  return text.length > maxLength ? text.substring(0, maxLength) + '...' : text
}

const formatTime = (timeStr) => {
  if (!timeStr) return '-'
  const date = new Date(timeStr)
  return date.toLocaleString('zh-CN')
}

const getScoreColor = (score) => {
  if (score >= 0.8) return 'var(--color-success-500)'
  if (score >= 0.6) return 'var(--color-warning-500)'
  return 'var(--color-error-500)'
}

const getScoreTagColor = (score) => {
  if (score >= 0.8) return 'success'
  if (score >= 0.6) return 'warning'
  return 'error'
}

const getStatusColor = (status) => {
  const colors = {
    running: 'blue',
    completed: 'green',
    failed: 'red',
    paused: 'orange'
  }
  return colors[status] || 'default'
}

const getStatusText = (status) => {
  const texts = {
    running: '运行中',
    completed: '已完成',
    failed: '失败',
    paused: '已暂停'
  }
  return texts[status] || status
}

const getMetricTitle = (key) => {
  const titles = {
    precision: '精确率',
    recall: '召回率',
    map: '平均精度',
    ndcg: 'NDCG',
    bleu: 'BLEU分数',
    rouge: 'ROUGE分数',
    answer_correctness: '答案准确性',
    score: '评分',
    reasoning: '理由',
    overall_score: '综合评分'
  }
  // 处理 recall@k
  if (key.startsWith('recall@')) return `召回率 (${key.split('@')[1]})`
  if (key.startsWith('precision@')) return `精确率 (${key.split('@')[1]})`

  return titles[key] || key
}

// 获取指标类型
const getMetricType = (key) => {
  if (key.startsWith('recall')) return 'recall'
  if (key.startsWith('precision')) return 'precision'
  if (key === 'map') return 'map'
  if (key === 'ndcg') return 'ndcg'
  return 'default'
}

// 获取指标短名称
const getMetricShortName = (key) => {
  if (key.startsWith('recall@')) return `R@${key.split('@')[1]}`
  if (key.startsWith('precision@')) return `P@${key.split('@')[1]}`
  if (key === 'precision') return 'Precision'
  if (key === 'recall') return 'Recall'
  if (key === 'map') return 'MAP'
  if (key === 'ndcg') return 'NDCG'
  return key
}

// 格式化指标值
const formatMetricValue = (val) => {
  if (typeof val !== 'number') return '-'
  // 检索指标（recall, precision, f1 等）范围是 0.0-1.0，统一转换为百分比
  if (val <= 1) return (val * 100).toFixed(1) + '%'
  return val.toFixed(3)
}

// 格式化持续时间
const formatDuration = (seconds) => {
  if (seconds < 60) {
    return `${Math.round(seconds)}秒`
  } else if (seconds < 3600) {
    const minutes = Math.floor(seconds / 60)
    const remainingSeconds = Math.round(seconds % 60)
    return `${minutes}分${remainingSeconds}秒`
  } else {
    const hours = Math.floor(seconds / 3600)
    const minutes = Math.floor((seconds % 3600) / 60)
    return `${hours}小时${minutes}分`
  }
}

// 组件挂载时加载数据
onMounted(() => {
  loadBenchmarks()
  loadEvaluationHistory()
})
</script>

<style lang="less" scoped>
.rag-evaluation-container {
  height: 100%;
  background: var(--gray-0);
  display: flex;
  flex-direction: column;
}

// 顶部工具栏
.toolbar {
  padding: 12px 16px;
  background: var(--gray-0);
  border-bottom: 1px solid var(--gray-200);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;

  .toolbar-left {
    display: flex;
    align-items: center;
  }

  .benchmark-selector {
    display: flex;
    align-items: center;
    gap: 12px;

    .selector-label {
      font-size: 14px;
      font-weight: 500;
      color: var(--gray-700);
      margin: 0;
      white-space: nowrap;
    }

    .refresh-benchmarks-btn {
      color: var(--gray-600);
    }
  }

  .toolbar-right {
    display: flex;
    align-items: center;
    gap: 6px;
  }
}

// 评估内容区域
.evaluation-content {
  flex: 1;
  overflow: hidden;
  min-height: 0;
  padding: 10px 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

// 评估结果区域
.evaluation-results {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: auto;
  padding: 16px;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {
    background-color: rgba(0, 0, 0, 0.2);
    border-radius: 3px;

    &:hover {
      background-color: rgba(0, 0, 0, 0.3);
    }
  }
}

.empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--gray-0);
  border-radius: 8px;
  border: 1px solid var(--gray-200);
}

.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;

  .progress-stats {
    flex: 1;
    margin-right: 24px;
    min-width: 300px;

    .ant-statistic {
      margin-bottom: 12px;

      .ant-statistic-title {
        font-size: 13px;
        color: var(--gray-600);
      }

      .ant-statistic-content {
        font-size: 18px;
        font-weight: 500;
      }
    }
  }

  .progress-actions {
    flex-shrink: 0;
    padding-top: 24px;
  }
}

.query-text {
  font-size: 12px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-height: 1.5;
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
}

.answer-text {
  font-size: 12px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-height: 1.5;
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--gray-700);
}

.log-time {
  color: var(--gray-500);
  margin-left: 8px;
  font-size: 12px;
}

// 优化表格样式
:deep(.ant-table) {
  .ant-table-tbody > tr > td {
    padding: 12px 12px;
    vertical-align: top;
  }

  .ant-table-thead > tr > th {
    padding: 8px 12px;
    font-weight: 500;
    background-color: var(--gray-50);
  }
}

// 优化卡片间距
:deep(.ant-card) {
  .ant-card-head {
    padding: 8px 16px;
    min-height: 40px;

    .ant-card-head-title {
      font-size: 14px;
      font-weight: 500;
      padding: 4px 0;
    }
  }
}

// 优化时间线样式
:deep(.ant-timeline) {
  .ant-timeline-item-content {
    margin-left: 20px;
    padding-bottom: 12px;
  }
}

// 优化描述列表样式
:deep(.ant-descriptions) {
  .ant-descriptions-item-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--gray-600);
  }

  .ant-descriptions-item-content {
    font-size: 13px;
  }
}

// 优化表单项间距
:deep(.ant-form) {
  .ant-form-item {
    margin-bottom: 16px;
  }
}

:deep(.ant-form-inline) {
  .ant-form-item {
    margin-right: 24px;
    margin-bottom: 16px;

    &:last-child {
      margin-right: 0;
    }
  }
}

// 优化模型配置表单项
.model-config-section {
  padding: 6px 8px;
  background: var(--gray-10);
  border-radius: 8px;
  border: 1px solid var(--gray-150);

  .ant-form-item {
    margin-bottom: 0;

    .ant-form-item-label {
      font-weight: 500;
    }

    .ant-form-item-extra {
      font-size: 12px;
      color: var(--gray-500);
      margin-top: 4px;
    }
  }

  // 为模型配置部分内的列添加特定样式
  .ant-col {
    &:not(:last-child) .ant-form-item {
      padding-right: 12px;
    }
  }
}

// 优化统计数字样式
:deep(.ant-row) {
  .ant-col {
    .ant-statistic {
      padding: 12px;
      border: 1px solid var(--gray-200);
      border-radius: 6px;
      text-align: center;
      transition: all 0.3s;

      &:hover {
        border-color: var(--gray-300);
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
      }
    }
  }
}

// 检索指标样式
.retrieval-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 20px;
  align-items: center;
}

.metric-item {
  display: flex;
  align-items: center;
}

.metric-content {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  line-height: 1.4;
  font-weight: 500;
  white-space: nowrap;

  &.metric-recall {
    background-color: var(--color-info-50);
    color: var(--color-info-900);
  }

  &.metric-precision {
    background-color: var(--color-success-50);
    color: var(--color-success-900);
  }

  &.metric-map,
  &.metric-ndcg {
    background-color: var(--color-accent-50);
    color: var(--color-accent-900);
  }
}

.metric-name {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.metric-value {
  font-weight: 700;
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
}

.no-metrics {
  color: var(--gray-400);
  font-style: italic;
}

// 答案推理样式
.answer-reasoning {
  font-size: 12px;
  color: var(--gray-600);
  margin-top: 8px;
  line-height: 1.4;
  cursor: pointer;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;

  &:hover {
    color: var(--gray-800);
  }
}

// 加载和空状态样式
.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
}

.empty-results {
  padding: 40px 0;
  text-align: center;
}

// 评估报告样式
.evaluation-report {
  margin-bottom: 20px;

  .report-metric {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    border-bottom: 1px solid var(--gray-100);

    &:last-child {
      border-bottom: none;
    }

    .metric-label {
      font-size: 14px;
      padding-right: 18px;
      color: var(--gray-700);
    }

    .metric-value {
      font-size: 14px;
      font-weight: 600;
      font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
    }
  }

  .accuracy-stats {
    .accuracy-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 12px 0;
      border-bottom: 1px solid var(--gray-100);

      &:last-child {
        border-bottom: none;
      }

      .accuracy-label {
        font-size: 14px;
        color: var(--gray-700);
      }

      .accuracy-value {
        font-size: 16px;
        font-weight: 600;
        font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
      }
    }
  }

  :deep(.ant-card) {
    .ant-card-head {
      border-bottom: 1px solid var(--gray-200);

      .ant-card-head-title {
        font-size: 14px;
        font-weight: 500;
      }
    }
  }
}

// 历史评估记录区域
.history-section {
  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;

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

    .refresh-btn {
      color: var(--gray-600);
      border: none;
      box-shadow: none;
      padding: 4px 8px;
      height: auto;
      font-size: 13px;

      &:hover {
        color: var(--color-primary-600);
        background-color: var(--color-primary-50);
      }

      &:active {
        color: var(--color-primary-700);
        background-color: var(--color-primary-100);
      }

      .anticon {
        font-size: 14px;
      }
    }
  }

  :deep(.ant-table) {
    border: 1px solid var(--gray-100);
  }
}

// JSON 查看器样式
.json-viewer-container {
  max-height: 400px;
  overflow: auto;

  .json-viewer {
    margin: 0;
    padding: 0;
    font-family: 'SF Mono', 'Monaco', 'Consolas', 'Menlo', monospace;
    font-size: 13px;
    line-height: 1.5;
    color: var(--gray-800);
    white-space: pre-wrap;
    word-wrap: break-word;
    background: var(--gray-50);
    border: 1px solid var(--gray-200);
    border-radius: 6px;
    padding: 12px;
  }
}

// 仅查看错误按钮样式
.error-only-active {
  background-color: var(--color-error-500) !important;
  border-color: var(--color-error-500) !important;
  color: white !important;

  &:hover {
    background-color: var(--color-error-600) !important;
    border-color: var(--color-error-600) !important;
  }

  &:focus {
    background-color: var(--color-error-500) !important;
    border-color: var(--color-error-500) !important;
  }
}
</style>
