<!-- 研究进度时间线：展示研究执行过程中的各阶段进度和冲突/待确认项 -->
<template>
  <div class="timeline-wrapper">
    <!-- 进度时间线 -->
    <a-card class="progress-card" :bordered="false" title="研究进度">
      <a-empty v-if="progress.length === 0" description="执行后会在这里显示阶段进度" />
      <a-timeline v-else>
        <a-timeline-item
          v-for="item in progress"
          :key="`${item.timestamp}-${item.content}`"
          :color="timelineColor(item)"
        >
          <div :class="['timeline-item', { 'timeline-item--guide': item.stage === 'guide' }]">
            <div class="timeline-item__title-row">
              <div class="timeline-item__title">{{ stageLabel(item.stage) }}</div>
              <a-tag v-if="item.stage === 'guide'" color="gold">结构化来源</a-tag>
            </div>
            <div class="timeline-item__content">{{ item.content }}</div>
          </div>
          <div class="timeline-item__time">{{ formatSessionTime(item.timestamp) }}</div>
        </a-timeline-item>
      </a-timeline>
    </a-card>

    <!-- 冲突、缺口与待确认项 -->
    <a-card class="risk-card" :bordered="false" title="冲突、缺口与待确认项">
      <a-empty
        v-if="!report.conflicts.length && !report.openQuestions.length"
        description="执行后会归纳冲突、证据缺口和待确认问题"
      />

      <div v-if="report.conflicts.length" class="risk-section">
        <div class="risk-section__title">冲突与证据缺口</div>
        <a-card
          v-for="conflict in report.conflicts"
          :key="`${conflict.title}-${conflict.content}`"
          size="small"
          class="risk-item"
        >
          <template #title>
            <div class="finding-card__title-row">
              <span>{{ conflict.title }}</span>
              <a-tag :color="severityColor(conflict.severity)">{{ severityLabel(conflict.severity) }}</a-tag>
            </div>
          </template>
          <MarkdownRenderer :content="conflict.content" @reference-click="handleReferenceClick" />
        </a-card>
      </div>

      <div v-if="report.openQuestions.length" class="risk-section">
        <div class="risk-section__title">待确认问题</div>
        <a-card
          v-for="question in report.openQuestions"
          :key="`${question.question}-${question.reason}`"
          size="small"
          class="risk-item"
        >
          <div class="open-question__title">{{ question.question }}</div>
          <div class="open-question__reason">{{ question.reason }}</div>
        </a-card>
      </div>
    </a-card>

    <!-- 研究笔记 -->
    <a-card class="notes-card" :bordered="false" title="研究笔记">
      <a-textarea
        :value="notes"
        :auto-size="{ minRows: 4, maxRows: 10 }"
        placeholder="记录人工判断、补充事实、后续核查路径等。"
        @update:value="emit('update:notes', $event)"
      />
    </a-card>
  </div>
</template>

<script setup lang="ts">
import MarkdownRenderer from '@/components/MarkdownRenderer.vue'
import type { ResearchProgressItem, ResearchReport } from '@/types/research'
import type { ResearchReference } from '@/types/document'
import { formatSessionTime } from '@/utils/basketKeys'

const props = defineProps<{
  /** 研究进度列表 */
  progress: ResearchProgressItem[]
  /** 研究报告（用于展示冲突和待确认项） */
  report: ResearchReport
  /** 研究笔记内容 */
  notes: string
  /** 引用材料列表，按 [1]/[2] 顺序映射 */
  references: ResearchReference[]
}>()

const emit = defineEmits<{
  (e: 'update:notes', value: string): void
  (e: 'preview-reference', reference: ResearchReference): void
  (e: 'preview-reference-by-index', index: number): void
}>()

function handleReferenceClick(index: number) {
  emit('preview-reference-by-index', index)
}

/** 阶段名称映射 */
function stageLabel(stage: string): string {
  const mapping: Record<string, string> = {
    init: '任务装载',
    scope: '显式范围',
    retrieve: '混合检索',
    graph: '图谱补证',
    guide: '办事指南证据',
    analysis: '研究汇总',
    complete: '研究完成',
    document: '文档生成',
  }
  return mapping[stage] || stage
}

function timelineColor(item: ResearchProgressItem): string {
  if (item.stage === 'guide') return 'orange'
  if (item.status === 'completed') return 'green'
  if (item.status === 'error') return 'red'
  return 'blue'
}

function severityLabel(severity: string): string {
  if (severity === 'high') return '高风险'
  if (severity === 'low') return '低风险'
  return '中风险'
}

function severityColor(severity: string): string {
  if (severity === 'high') return 'red'
  if (severity === 'low') return 'blue'
  return 'gold'
}
</script>

<style scoped lang="less">
.timeline-wrapper {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.progress-card, .risk-card, .notes-card {
  border-radius: 18px;
  box-shadow: 0 10px 40px rgba(14, 30, 62, 0.06);
}

.timeline-item {
  padding: 2px 0;
}

.timeline-item--guide {
  padding: 10px 12px;
  border-radius: 12px;
  background: linear-gradient(180deg, #fff8e1 0%, #fffdf5 100%);
  border: 1px solid #ffe58f;
}

.timeline-item__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}

.timeline-item__title { font-weight: 600; margin-bottom: 4px; }
.timeline-item__content { color: #595959; line-height: 1.6; }
.timeline-item__time { margin-top: 4px; font-size: 12px; color: #8c8c8c; }

.risk-section + .risk-section { margin-top: 16px; }
.risk-section__title { margin-bottom: 10px; font-size: 13px; font-weight: 600; }

.risk-item { border-radius: 14px; }
.risk-item + .risk-item { margin-top: 12px; }

.finding-card__title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.open-question__title { font-weight: 600; margin-bottom: 6px; }
.open-question__reason { color: #595959; line-height: 1.6; }
</style>
