<script setup lang="ts">
import { h, onMounted, ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { NButton, NCard, NDataTable, NDescriptions, NDrawer, NDrawerContent, NEmpty, NForm, NFormItem, NInput, NInputNumber, NModal, NPopconfirm, NSelect, NSkeleton, NSpace, NTag, NDropdown, NIcon, useMessage } from 'naive-ui'
import { DownloadOutline, TrashOutline, CheckmarkOutline, KeyOutline, CopyOutline, CloseOutline, SaveOutline } from '@vicons/ionicons5'
import { api } from '../../api/client'
import { toBeijingDate } from '../../utils/date'
import { copyToClipboard } from '../../utils/clipboard'
import type { SystematicReview, ReviewLiterature, PicoData, ExtractedDataResponse } from '../../types'

const route = useRoute()
const router = useRouter()
const message = useMessage()

const reviewId = route.params.id as string
const review = ref<SystematicReview | null>(null)
const literatures = ref<ReviewLiterature[]>([])
const loading = ref(false)
const methodsSummary = ref('')
const methodsLoading = ref(false)

// PRISMA 阶段计数
const stageCounts = computed(() => {
  const counts: Record<string, number> = { identification: 0, screening: 0, eligibility: 0, included: 0, excluded: 0 }
  for (const lit of literatures.value) {
    counts[lit.stage] = (counts[lit.stage] || 0) + 1
  }
  return counts
})

const prismaStages = [
  { key: 'identification', label: '识别', color: '#1890ff' },
  { key: 'screening', label: '初筛', color: '#52c41a' },
  { key: 'eligibility', label: '全文评估', color: '#faad14' },
  { key: 'included', label: '纳入', color: '#f5222d' },
]

function openPrismaSvg() {
  window.open(prismaSvgUrl.value, '_blank')
}

// ── PICO 编辑 Modal ──
const showPicoEdit = ref(false)
const editingPicoLit = ref<ReviewLiterature | null>(null)
const picoEditForm = ref<PicoData>({})
const savingPico = ref(false)

function openPicoEdit(lit: ReviewLiterature) {
  editingPicoLit.value = lit
  picoEditForm.value = {
    population: (lit.pico as any)?.population ?? null,
    intervention: (lit.pico as any)?.intervention ?? null,
    comparator: (lit.pico as any)?.comparator ?? null,
    outcome: (lit.pico as any)?.outcome ?? null,
    sample_size: (lit.pico as any)?.sample_size ?? null,
    effect_size: (lit.pico as any)?.effect_size ?? null,
  }
  showPicoEdit.value = true
}

async function savePico() {
  if (!editingPicoLit.value) return
  savingPico.value = true
  try {
    const body: Record<string, unknown> = {}
    for (const [k, v] of Object.entries(picoEditForm.value)) {
      if (v !== null && v !== undefined && v !== '') body[k] = v
    }
    const { data } = await api.put(`/reviews/${reviewId}/literature/${editingPicoLit.value.id}/pico`, body)
    // 更新本地数据
    editingPicoLit.value.pico = data.pico
    const match = literatures.value.find(l => l.id === editingPicoLit.value!.id)
    if (match) match.pico = data.pico
    message.success('PICO 已保存')
    showPicoEdit.value = false
  } catch (e: any) {
    message.error(e?.response?.data?.detail || '保存失败')
  } finally {
    savingPico.value = false
  }
}

// ── AI PICO 提取 ──
const extractingPicoId = ref<string | null>(null)

async function triggerExtractPico(lit: ReviewLiterature) {
  extractingPicoId.value = lit.id
  try {
    const { data } = await api.post(`/reviews/${reviewId}/literature/${lit.id}/extract-pico`)
    lit.pico = data.pico
    const match = literatures.value.find(l => l.id === lit.id)
    if (match) match.pico = data.pico
    message.success('PICO 提取完成')
  } catch (e: any) {
    message.error(e?.response?.data?.detail || '提取失败')
  } finally {
    extractingPicoId.value = null
  }
}

// ── 提取数据 Drawer ──
const showDataDrawer = ref(false)
const dataDrawerLitTitle = ref('')
const dataDrawerLitId = ref('')
const extractedData = ref<ExtractedDataResponse | null>(null)
const dataLoading = ref(false)

async function openExtractedData(lit: ReviewLiterature) {
  dataDrawerLitTitle.value = lit.title || `PMID ${lit.pmid}`
  dataDrawerLitId.value = lit.id
  dataLoading.value = true
  showDataDrawer.value = true
  try {
    const { data } = await api.get(`/reviews/${reviewId}/literature/${lit.id}/extracted-data`)
    extractedData.value = data
  } catch (e: any) {
    message.error(e?.response?.data?.detail || '加载数据失败')
    extractedData.value = null
  } finally {
    dataLoading.value = false
  }
}

const adoptingIndex = ref<number | null>(null)

async function adoptEffect(effect: any, idx: number) {
  adoptingIndex.value = idx
  try {
    const { data } = await api.post(
      `/reviews/${reviewId}/literature/${dataDrawerLitId.value}/adopt-effect`,
      {
        endpoint: effect.endpoint,
        effect_type: effect.effect_type,
        value: effect.value,
        ci_lower: effect.ci_lower,
        ci_upper: effect.ci_upper,
        p_value: effect.p_value,
      }
    )
    // 更新本地数据 + 重新加载 drawer
    extractedData.value!.pico = data.pico
    const match = literatures.value.find(l => l.id === dataDrawerLitId.value)
    if (match) match.pico = data.pico
    message.success('效应量已写入 PICO')
  } catch (e: any) {
    message.error(e?.response?.data?.detail || '写入失败')
  } finally {
    adoptingIndex.value = null
  }
}

// ── 评价内筛选 ──
const stageFilter = ref('')
const picoFilter = ref<'all' | 'has' | 'missing'>('all')

const filteredLiteratures = computed(() => {
  let list = literatures.value
  if (stageFilter.value) {
    list = list.filter(l => l.stage === stageFilter.value)
  }
  if (picoFilter.value === 'has') {
    list = list.filter(l => l.pico && ((l.pico as any).population || (l.pico as any).intervention))
  } else if (picoFilter.value === 'missing') {
    list = list.filter(l => !l.pico || !((l.pico as any).population || (l.pico as any).intervention))
  }
  return list
})

// ── PICO 展开行渲染 ──
function renderPicoExpand(row: ReviewLiterature) {
  const p = (row.pico || {}) as any
  const hasPico = p.population || p.intervention || p.comparator || p.outcome
  if (!hasPico) {
    return h('div', { style: 'padding:8px 16px;color:var(--text-muted);font-size:13px' }, '暂无 PICO 数据。点击操作列"PICO"进行提取或编辑。')
  }
  const items: { label: string; value: string | number | null | undefined }[] = [
    { label: '研究对象（P）', value: p.population },
    { label: '干预措施（I）', value: p.intervention },
    { label: '对照措施（C）', value: p.comparator },
    { label: '结局指标（O）', value: p.outcome },
    { label: '样本量', value: p.sample_size },
  ]
  const children = items
    .filter(i => i.value)
    .map(i =>
      h('div', { style: 'margin-bottom:4px;font-size:13px' }, [
        h('span', { style: 'font-weight:600;color:var(--text-secondary);margin-right:8px' }, i.label + ':'),
        h('span', { style: 'color:var(--text-primary)' }, String(i.value)),
      ])
    )

  // 效应量展示
  const es = p.effect_size
  if (es) {
    const esParts: string[] = []
    if (es.hr) esParts.push(`HR ${es.hr}`)
    if (es.or) esParts.push(`OR ${es.or}`)
    if (es.ci_lower !== undefined && es.ci_upper !== undefined) esParts.push(`95%CI ${es.ci_lower}-${es.ci_upper}`)
    if (es.p_value !== undefined) esParts.push(`p=${es.p_value}`)
    if (esParts.length) {
      children.push(
        h('div', { style: 'margin-top:4px;font-size:13px' }, [
          h('span', { style: 'font-weight:600;color:var(--text-secondary);margin-right:8px' }, '效应量:'),
          h('span', { style: 'color:var(--text-secondary)' }, esParts.join(', ')),
        ])
      )
    }
  }
  return h('div', { style: 'padding:8px 16px;background:var(--bg-card);border-radius:4px' }, children)
}

// 导出选项
const exportOptions = [
  { label: 'CSV（含研究设计/PICO/质量评分）', key: 'csv' },
  { label: 'RIS（RevMan 兼容）', key: 'ris' },
  { label: 'RevMan .rm5（含 PICO/效应量）', key: 'rm5' },
]

function handleExport(key: string) {
  ;(async () => {
    try {
      const res = await api.get(`/reviews/${reviewId}/export/${key}`, { responseType: 'blob' } as any)
      const mimeMap: Record<string, string> = { csv: 'text/csv', ris: 'application/x-research-info-systems', rm5: 'application/xml' }
      const blob = new Blob([res.data], { type: mimeMap[key] || 'application/octet-stream' })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `review_${reviewId.slice(0, 8)}.${key}`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)
      message.success('下载完成')
    } catch (e: any) {
      if (e?.response?.status === 402) {
        message.warning('导出功能需要 Pro 及以上方案')
      } else {
        message.error('导出失败')
      }
    }
  })()
}

// 生成方法学小结
async function generateSummary() {
  methodsLoading.value = true
  try {
    const res = await api.get(`/reviews/${reviewId}/methods-summary`)
    methodsSummary.value = res.data.summary
  } catch (e) {
    message.error('生成失败')
  } finally {
    methodsLoading.value = false
  }
}

async function copySummary() {
  const ok = await copyToClipboard(methodsSummary.value)
  if (ok) message.success('已复制')
  else message.info(methodsSummary.value)
}

// PRISMA SVG URL
const prismaSvgUrl = computed(() => `/api/v1/reviews/${reviewId}/prisma/svg`)

// ── PICO 汇总 ──
const picoSummary = computed(() => {
  const included = literatures.value.filter(l => l.stage === 'included')
  const hasPico = included.filter(l => l.pico && ((l.pico as any).population || (l.pico as any).intervention || (l.pico as any).outcome))
  if (!hasPico.length) return null

  // 按干预措施分组
  const interventions = new Map<string, number>()
  const populations = new Set<string>()
  const outcomes = new Set<string>()
  const effectTypes = new Set<string>()
  let totalSampleSize = 0
  let withEffect = 0

  for (const lit of included) {
    const p = (lit.pico || {}) as any
    if (p.population) populations.add(p.population.slice(0, 60))
    if (p.outcome) outcomes.add(p.outcome.slice(0, 60))
    if (p.intervention) {
      const key = p.intervention.slice(0, 80)
      interventions.set(key, (interventions.get(key) || 0) + 1)
    }
    if (p.sample_size) totalSampleSize += Number(p.sample_size)
    if (p.effect_size) { withEffect++; if (p.effect_type) effectTypes.add(p.effect_type) }
  }

  return {
    total: included.length,
    withPico: hasPico.length,
    interventions: [...interventions.entries()].sort((a, b) => b[1] - a[1]),
    populations: [...populations],
    outcomes: [...outcomes],
    totalSampleSize,
    withEffect,
  }
})

// 文献表格列
const litColumns = [
  { type: 'expand' as const, width: 40, renderExpand: renderPicoExpand },
  { title: 'PMID', key: 'pmid', width: 90 },
  { title: '标题', key: 'title', ellipsis: { tooltip: true } },
  { title: '第一作者', key: 'first_author', width: 120 },
  { title: '期刊', key: 'journal', width: 160, ellipsis: { tooltip: true } },
  { title: '日期', key: 'pub_date', width: 95 },
  { title: 'PRISMA', key: 'stage', width: 100,
    render: (row: ReviewLiterature) => {
      const stageLabel: Record<string, string> = { identification: '识别', screening: '初筛', eligibility: '全文评估', included: '纳入', excluded: '排除' }
      return h(NTag, { size: 'small' }, { default: () => stageLabel[row.stage] || row.stage })
    }
  },
  { title: '研究设计', key: 'study_design', width: 110,
    render: (row: any) => {
      const label = row.study_design?.label_zh || ''
      return label ? h(NTag, { size: 'tiny', type: 'info', bordered: false }, { default: () => label }) : ''
    }
  },
  { title: '质量', key: 'quality_score', width: 70 },
  { title: '撤稿', key: 'retracted', width: 60,
    render: (row: any) => row.retracted ? h(NTag, { size: 'tiny', type: 'error', bordered: false }, { default: () => '是' }) : ''
  },
  { title: '操作', key: 'actions', width: 280,
    render: (row: ReviewLiterature) => {
      const stageOptions = [
        { label: '识别', value: 'identification' },
        { label: '初筛', value: 'screening' },
        { label: '全文评估', value: 'eligibility' },
        { label: '纳入', value: 'included' },
        { label: '排除', value: 'excluded' },
      ]
      const hasPico = !!(row.pico && ((row.pico as any).population || (row.pico as any).intervention || (row.pico as any).outcome))
      const isExtracting = extractingPicoId.value === row.id
      return h(NSpace, { size: 'small' }, {
        default: () => [
          h(NSelect, {
            size: 'tiny',
            value: row.stage,
            options: stageOptions,
            style: 'width:90px',
            'onUpdate:value': (val: string) => updateLitStage(row.id, val),
          }),
          h(NButton, {
            size: 'tiny', secondary: true,
            style: 'font-size:11px;padding:0 6px',
            onClick: () => openPicoEdit(row),
          }, { default: () => 'PICO' }),
          h(NButton, {
            size: 'tiny', secondary: true, type: hasPico ? 'default' : 'warning',
            style: 'font-size:11px;padding:0 6px',
            loading: isExtracting,
            onClick: () => triggerExtractPico(row),
          }, { default: () => '抽取' }),
          h(NButton, {
            size: 'tiny', quaternary: true,
            style: 'font-size:11px;padding:0 6px',
            onClick: () => openExtractedData(row),
          }, { default: () => '数据' }),
          h(NPopconfirm, { onPositiveClick: () => removeLiterature(row.id) }, {
            default: () => '确定移除？',
            trigger: () => h(NButton, { size: 'tiny', type: 'error', ghost: true, style: 'padding:0 6px' }, { default: () => '移除' }),
          }),
        ]
      })
    }
  },
]

const litScrollX = 1425

async function loadReview() {
  loading.value = true
  try {
    const [revRes, litRes] = await Promise.all([
      api.get(`/reviews/${reviewId}`),
      api.get(`/reviews/${reviewId}/literature`),
    ])
    review.value = revRes.data
    literatures.value = litRes.data.items || []
  } catch (e) {
    message.error('加载失败')
    router.push('/app/reviews')
  } finally {
    loading.value = false
  }
}

async function updateLitStage(relId: string, stage: string) {
  try {
    await api.put(`/reviews/${reviewId}/literature/${relId}`, { stage })
    const lit = literatures.value.find(l => l.id === relId)
    if (lit) lit.stage = stage
    message.success('已更新')
  } catch (e) {
    message.error('更新失败')
  }
}

async function removeLiterature(relId: string) {
  try {
    await api.delete(`/reviews/${reviewId}/literature/${relId}`)
    literatures.value = literatures.value.filter(l => l.id !== relId)
    message.success('已移除')
  } catch (e) {
    message.error('移除失败')
  }
}

async function deleteReview() {
  try {
    await api.delete(`/reviews/${reviewId}`)
    message.success('已删除')
    router.push('/app/reviews')
  } catch (e) {
    message.error('删除失败')
  }
}

onMounted(loadReview)
</script>

<template>
  <div class="review-detail-page">
    <NSkeleton v-if="loading" text :repeat="8" />
    <template v-else-if="review">
      <div class="page-header">
        <div>
          <NButton text @click="router.push('/app/reviews')">← 返回</NButton>
          <h2>{{ review.title }}</h2>
        </div>
        <NSpace>
          <NDropdown :options="exportOptions" @select="handleExport">
            <NButton type="primary" ghost class="sky-btn"><template #icon><NIcon size="14"><DownloadOutline /></NIcon></template>导出</NButton>
          </NDropdown>
          <NPopconfirm @positive-click="deleteReview">
            <template #trigger>
              <NButton type="error" ghost class="sky-btn"><template #icon><NIcon size="14"><TrashOutline /></NIcon></template>删除项目</NButton>
            </template>
            确定删除此系统评价？此操作不可撤销。
          </NPopconfirm>
        </NSpace>
      </div>

      <!-- PRISMA 流程 -->
      <NCard title="PRISMA 流程" class="section-card">
        <div class="prisma-flow">
          <div v-for="(stage, idx) in prismaStages" :key="stage.key" class="prisma-node">
            <div class="prisma-circle" :style="{ borderColor: stage.color }">
              <span class="prisma-count">{{ stageCounts[stage.key] || 0 }}</span>
            </div>
            <span class="prisma-label">{{ stage.label }}</span>
            <span v-if="idx < prismaStages.length - 1" class="prisma-arrow">→</span>
          </div>
        </div>
        <div style="text-align:center;margin-top:12px">
          <NButton class="sky-btn" size="small" @click="openPrismaSvg"><template #icon><NIcon size="14"><CheckmarkOutline /></NIcon></template>查看 PRISMA 流程图</NButton>
        </div>
      </NCard>

      <!-- 项目信息 -->
      <NCard title="项目信息" class="section-card">
        <NDescriptions :column="2" bordered>
          <NDescriptionsItem label="状态">
            <NTag :type="review.status === 'active' ? 'info' : review.status === 'completed' ? 'success' : 'default'" size="small">
              {{ { draft: '草稿', active: '进行中', completed: '已完成', archived: '已归档' }[review.status] || review.status }}
            </NTag>
          </NDescriptionsItem>
          <NDescriptionsItem label="PRISMA 阶段">{{ review.prisma_stage }}</NDescriptionsItem>
          <NDescriptionsItem v-if="review.objective" label="研究目的" :span="2">{{ review.objective }}</NDescriptionsItem>
          <NDescriptionsItem v-if="review.databases_searched?.length" label="检索数据库">{{ review.databases_searched.join(', ') }}</NDescriptionsItem>
          <NDescriptionsItem v-if="review.created_at" label="创建时间">{{ toBeijingDate(review.created_at) }}</NDescriptionsItem>
        </NDescriptions>
      </NCard>

      <!-- 方法学小结 -->
      <NCard title="方法学小结" class="section-card">
        <div v-if="methodsSummary" class="methods-summary-text">{{ methodsSummary }}</div>
        <div v-else-if="methodsLoading" style="color:var(--text-muted)">生成中...</div>
        <div v-else style="color:var(--text-muted)">点击下方按钮生成方法学描述</div>
        <NSpace style="margin-top:8px">
          <NButton class="sky-btn" size="small" @click="generateSummary" :loading="methodsLoading"><template #icon><NIcon size="14"><KeyOutline /></NIcon></template>生成方法学小结</NButton>
          <NButton class="sky-btn" v-if="methodsSummary" size="small" ghost @click="copySummary"><template #icon><NIcon size="14"><CopyOutline /></NIcon></template>复制</NButton>
        </NSpace>
      </NCard>

      <!-- PICO 汇总 -->
      <NCard v-if="picoSummary" title="PICO 汇总" class="section-card">
        <div style="display:flex;flex-wrap:wrap;gap:16px">
          <div class="pico-stat">
            <div class="pico-stat-num">{{ picoSummary.total }}</div>
            <div class="pico-stat-label">纳入文献</div>
          </div>
          <div class="pico-stat">
            <div class="pico-stat-num">{{ picoSummary.withPico }}</div>
            <div class="pico-stat-label">已提取 PICO</div>
          </div>
          <div class="pico-stat" v-if="picoSummary.totalSampleSize">
            <div class="pico-stat-num">{{ picoSummary.totalSampleSize.toLocaleString() }}</div>
            <div class="pico-stat-label">总样本量</div>
          </div>
          <div class="pico-stat" v-if="picoSummary.withEffect">
            <div class="pico-stat-num">{{ picoSummary.withEffect }}</div>
            <div class="pico-stat-label">含效应量</div>
          </div>
        </div>

        <div v-if="picoSummary.interventions.length" style="margin-top:12px">
          <div style="font-size:13px;font-weight:600;color:var(--text-secondary);margin-bottom:6px">干预措施分布</div>
          <div style="display:flex;flex-wrap:wrap;gap:4px">
            <NTag v-for="[name, count] in picoSummary.interventions" :key="name" size="small" type="info">
              {{ name }} ({{ count }})
            </NTag>
          </div>
        </div>

        <div v-if="picoSummary.populations.length" style="margin-top:8px">
          <div style="font-size:13px;font-weight:600;color:var(--text-secondary);margin-bottom:4px">研究对象</div>
          <ul style="margin:0;padding-left:18px;font-size:12px;color:var(--text-secondary)">
            <li v-for="p in picoSummary.populations.slice(0, 5)" :key="p">{{ p }}</li>
            <li v-if="picoSummary.populations.length > 5" style="color:var(--text-muted)">...还有 {{ picoSummary.populations.length - 5 }} 种</li>
          </ul>
        </div>

        <div v-if="picoSummary.outcomes.length" style="margin-top:8px">
          <div style="font-size:13px;font-weight:600;color:var(--text-secondary);margin-bottom:4px">结局指标</div>
          <ul style="margin:0;padding-left:18px;font-size:12px;color:var(--text-secondary)">
            <li v-for="o in picoSummary.outcomes.slice(0, 5)" :key="o">{{ o }}</li>
            <li v-if="picoSummary.outcomes.length > 5" style="color:var(--text-muted)">...还有 {{ picoSummary.outcomes.length - 5 }} 种</li>
          </ul>
        </div>
      </NCard>

      <!-- 文献列表 -->
      <NCard title="文献列表" class="section-card">
        <div style="display:flex;gap:8px;margin-bottom:12px;align-items:center">
          <NSelect
            v-model:value="stageFilter" size="tiny" clearable placeholder="全部阶段" style="width:120px"
            :options="[{label:'识别',value:'identification'},{label:'初筛',value:'screening'},{label:'全文评估',value:'eligibility'},{label:'纳入',value:'included'},{label:'排除',value:'excluded'}]"
          />
          <NSelect
            v-model:value="picoFilter" size="tiny" style="width:120px"
            :options="[{label:'全部',value:'all'},{label:'有PICO',value:'has'},{label:'无PICO',value:'missing'}]"
          />
          <span style="font-size:12px;color:var(--text-muted)">共 {{ filteredLiteratures.length }} 条</span>
        </div>
        <NDataTable
          :columns="litColumns"
          :data="filteredLiteratures"
          :loading="loading"
          :bordered="false"
          :row-key="(r: ReviewLiterature) => r.id"
          :scroll-x="litScrollX"
          :empty="h(NEmpty, { description: '暂无文献，请从搜索页面添加' })"
        />
      </NCard>
    </template>
  </div>

  <!-- PICO 编辑 Modal -->
  <NModal preset="card" title="编辑 PICO" style="width:640px" v-model:show="showPicoEdit" :mask-closable="false">
    <NForm label-placement="top">
      <NFormItem label="研究对象 / 人群（Population）">
        <NInput v-model:value="picoEditForm.population" type="textarea" :rows="2" placeholder="癌种、分期、样本量特征" />
      </NFormItem>
      <NFormItem label="干预措施（Intervention）">
        <NInput v-model:value="picoEditForm.intervention" type="textarea" :rows="2" placeholder="药物名称、剂量、方案" />
      </NFormItem>
      <NFormItem label="对照措施（Comparator）">
        <NInput v-model:value="picoEditForm.comparator" type="textarea" :rows="2" placeholder="对照组治疗方案" />
      </NFormItem>
      <NFormItem label="结局指标（Outcome）">
        <NInput v-model:value="picoEditForm.outcome" type="textarea" :rows="2" placeholder="主要终点 / 次要终点" />
      </NFormItem>
      <NFormItem label="样本量">
        <NInputNumber v-model:value="picoEditForm.sample_size" style="width:200px" :min="0" placeholder="总样本量" />
      </NFormItem>
    </NForm>
    <template #footer>
      <NSpace justify="end">
        <NButton class="sky-btn" @click="showPicoEdit = false"><template #icon><NIcon size="14"><CloseOutline /></NIcon></template>取消</NButton>
        <NButton class="sky-btn" type="primary" :loading="savingPico" @click="savePico"><template #icon><NIcon size="14"><SaveOutline /></NIcon></template>保存</NButton>
      </NSpace>
    </template>
  </NModal>

  <!-- 提取数据 Drawer -->
  <NDrawer v-model:show="showDataDrawer" :width="640" placement="right">
    <NDrawerContent title="提取数据" closable>
      <template #header>
        <div style="font-size:14px;font-weight:600;max-width:500px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
          {{ dataDrawerLitTitle }}
        </div>
      </template>

      <NSkeleton v-if="dataLoading" text :repeat="4" style="padding:16px" />
      <template v-else-if="extractedData">
        <!-- PICO -->
        <NCard title="PICO 要素" size="small" class="data-card" v-if="extractedData.pico">
          <div v-if="(extractedData.pico as any).population" class="data-row"><span class="data-label">研究对象</span><span class="data-value">{{ (extractedData.pico as any).population }}</span></div>
          <div v-if="(extractedData.pico as any).intervention" class="data-row"><span class="data-label">干预措施</span><span class="data-value">{{ (extractedData.pico as any).intervention }}</span></div>
          <div v-if="(extractedData.pico as any).comparator" class="data-row"><span class="data-label">对照措施</span><span class="data-value">{{ (extractedData.pico as any).comparator }}</span></div>
          <div v-if="(extractedData.pico as any).outcome" class="data-row"><span class="data-label">结局指标</span><span class="data-value">{{ (extractedData.pico as any).outcome }}</span></div>
          <div v-if="(extractedData.pico as any).sample_size" class="data-row"><span class="data-label">样本量</span><span class="data-value">{{ (extractedData.pico as any).sample_size }}</span></div>
          <div v-if="(extractedData.pico as any).effect_size" class="data-row">
            <span class="data-label">效应量</span>
            <span class="data-value">{{ JSON.stringify((extractedData.pico as any).effect_size) }}</span>
          </div>
        </NCard>

        <!-- 基线特征 -->
        <NCard title="基线特征（Table 1）" size="small" class="data-card" v-if="extractedData.baseline?.extracted_fields">
          <div v-if="extractedData.baseline.table1_caption" style="font-size:12px;color:var(--text-secondary);margin-bottom:8px">
            {{ extractedData.baseline.table1_caption }}
          </div>
          <div v-if="extractedData.baseline.header_sample_sizes" style="margin-bottom:8px">
            <NTag v-for="(v, k) in extractedData.baseline.header_sample_sizes" :key="k" size="tiny" style="margin-right:4px">
              {{ k }} (n={{ (v as any).n }})
            </NTag>
          </div>
          <table class="data-table" v-if="extractedData.baseline.extracted_fields">
            <thead>
              <tr>
                <th>字段</th>
                <th v-for="arm in extractedData.baseline.arms" :key="arm">{{ arm }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(vals, key) in extractedData.baseline.extracted_fields" :key="key">
                <td class="field-key">{{ key }}</td>
                <td v-for="arm in extractedData.baseline.arms" :key="arm">{{ (vals as any)[arm] || '-' }}</td>
              </tr>
            </tbody>
          </table>
        </NCard>

        <!-- Outcome 表 -->
        <NCard title="结局 / 终点表" size="small" class="data-card" v-if="extractedData.tables?.length">
          <div v-for="(tbl, ti) in extractedData.tables" :key="ti" style="margin-bottom:16px">
            <div style="font-size:13px;font-weight:600;margin-bottom:6px">{{ tbl.caption }}</div>
            <table class="data-table">
              <thead>
                <tr>
                  <th v-for="h in tbl.headers" :key="h">{{ h }}</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(row, ri) in tbl.rows" :key="ri">
                  <td v-for="(cell, ci) in row" :key="ci">{{ cell }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </NCard>

        <!-- Outcome 表元数据（无表格数据时） -->
        <NCard title="结局表元数据" size="small" class="data-card" v-if="extractedData.outcome_tables?.length && !extractedData.tables?.length">
          <div v-for="(ot, oi) in extractedData.outcome_tables" :key="oi" class="data-row">
            <span class="data-label">{{ ot.caption }}</span>
            <span class="data-value" style="font-size:12px;color:var(--text-muted)">{{ ot.headers.join(' · ') }}</span>
          </div>
        </NCard>

        <!-- 解析效应量 -->
        <NCard title="解析效应量" size="small" class="data-card" v-if="extractedData.parsed_effects?.length">
          <div v-for="(effect, ei) in extractedData.parsed_effects" :key="ei" style="margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid var(--border-color)">
            <div style="display:flex;justify-content:space-between;align-items:flex-start">
              <div>
                <div style="font-weight:600;font-size:13px">{{ effect.endpoint }}</div>
                <div style="font-size:12px;margin-top:2px">
                  <NTag size="tiny" type="warning" style="margin-right:4px">{{ effect.effect_type || '?' }}</NTag>
                  <span v-if="effect.value != null"><strong>{{ effect.value }}</strong></span>
                  <span v-if="effect.ci_lower != null && effect.ci_upper != null"> (95%CI {{ effect.ci_lower }}-{{ effect.ci_upper }})</span>
                  <span v-if="effect.p_value != null"> p={{ effect.p_value }}</span>
                </div>
              </div>
              <NButton class="sky-btn" size="tiny" type="primary" ghost :loading="adoptingIndex === ei" @click="adoptEffect(effect, ei)">应用</NButton>
            </div>
            <div style="font-size:11px;color:var(--text-muted);margin-top:2px">{{ effect.raw?.slice(0, 80) }}</div>
          </div>
          <div style="font-size:11px;color:var(--text-muted)">点击"应用"将效应量写入当前文献的 PICO</div>
        </NCard>

        <!-- 无数据 -->
        <NEmpty v-if="!extractedData.pico && !extractedData.baseline?.extracted_fields && !extractedData.tables?.length && !extractedData.outcome_tables?.length" description="暂无预提取数据" />

        <div style="font-size:11px;color:var(--text-muted);margin-top:12px">{{ extractedData._note }}</div>
      </template>
    </NDrawerContent>
  </NDrawer>
</template>

<style scoped>
.review-detail-page { padding: 24px; }
.page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; }
.page-header h2 { margin: 8px 0 0; }
.section-card { margin-bottom: 16px; }

.prisma-flow { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 12px 0; }
.prisma-node { display: flex; align-items: center; gap: 6px; }
.prisma-circle { width: 48px; height: 48px; border-radius: 50%; border: 3px solid; display: flex; align-items: center; justify-content: center; background: var(--bg-card); }
.prisma-count { font-size: 18px; font-weight: 700; color: var(--text-primary); }
.prisma-label { font-size: 13px; color: var(--text-secondary); white-space: nowrap; }
.prisma-arrow { font-size: 18px; color: var(--border-color); margin: 0 4px; }

.methods-summary-text { font-size: 13px; line-height: 1.6; color: var(--text-primary); background: var(--bg-hover); padding: 12px; border-radius: 6px; }

.pico-stat { text-align: center; min-width: 80px; padding: 8px 16px; background: var(--bg-hover); border-radius: 8px; }
.pico-stat-num { font-size: 22px; font-weight: 700; color: #1a5276; }
.pico-stat-label { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* 提取数据样式 */
.data-card { margin-bottom: 12px; }
.data-row { display: flex; gap: 8px; margin-bottom: 6px; font-size: 13px; }
.data-label { flex-shrink: 0; font-weight: 600; color: var(--text-secondary); min-width: 64px; }
.data-value { color: var(--text-primary); word-break: break-word; }

.data-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.data-table th, .data-table td { border: 1px solid var(--border-color); padding: 4px 8px; text-align: left; }
.data-table th { background: var(--bg-page); font-weight: 600; white-space: nowrap; }
.data-table .field-key { font-weight: 600; color: var(--text-secondary); white-space: nowrap; }

@media (max-width: 768px) {
  .review-detail-page { padding: 12px; }
  .page-header { flex-direction: column; gap: 12px; }
  .page-header h2 { font-size: 20px; }
  .prisma-flow { flex-wrap: wrap; gap: 8px; justify-content: center; }
  .prisma-circle { width: 40px; height: 40px; }
  .prisma-count { font-size: 15px; }
  .prisma-arrow { font-size: 14px; margin: 0 2px; }
  .pico-stat { min-width: calc(50% - 8px); padding: 6px 12px; }
  .pico-stat-num { font-size: 18px; }
}
</style>
