<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { NCard, NTag, NButton, NSkeleton, NGrid, NGridItem, NDivider, NPagination, NTabPane, NTabs, NEmpty, NIcon, NDrawer, NDrawerContent, NDataTable } from 'naive-ui'
import { CheckmarkOutline } from '@vicons/ionicons5'
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, ArcElement, Tooltip, Legend, CategoryScale, LinearScale, BarElement, PointElement, LineElement, Filler } from 'chart.js'
import { api } from '../../api/client'
import { useAuthStore } from '../../stores/auth'
import { useToast } from '../../composables/useToast'

ChartJS.register(ArcElement, Tooltip, Legend, CategoryScale, LinearScale, BarElement, PointElement, LineElement, Filler)

const router = useRouter()
const auth = useAuthStore()
const toast = useToast()
const approvals = ref<any[]>([])
const loading = ref(true)
const agency = ref<string | null>(null)
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const subscribedTargets = ref<string[]>([])
const activeTab = ref('list')

// ── Swimlane Timeline ──
const HOT_TARGETS = ['EGFR', 'ALK', 'PD-1', 'HER2', 'CDK4/6', 'PARP', 'BTK', 'BRAF', 'MEK', 'FLT3', 'VEGFR', 'FGFR']
const timelineTarget = ref('EGFR')
const timelineData = ref<any[]>([])
const timelineLoading = ref(false)
const showTlTooltip = ref(false)
const tlTooltip = ref({ x: 0, y: 0, item: null as any })
const customTargetInput = ref('')

const swimlaneDrugs = computed(() => {
  const groups: Record<string, any[]> = {}
  for (const a of timelineData.value) {
    const key = a.drug_name || a.generic_name || 'Unknown'
    if (!groups[key]) groups[key] = []
    groups[key].push(a)
  }
  return Object.entries(groups).sort(([,a], [,b]) => {
    return (a[0].date || '').localeCompare(b[0].date || '')
  }).map(([drug, items]) => ({
    drug,
    items: items.sort((x: any, y: any) => (x.date || '').localeCompare(y.date || '')),
  }))
})

const tlStats = computed(() => {
  const d = timelineData.value
  if (!d.length) return { drugs: 0, total: 0, newDrugs: 0, expanded: 0, years: '' }
  const drugs = swimlaneDrugs.value.length
  const newDrugs = d.filter(a => a.approval_type === 'new_drug').length
  const dates = d.map(a => a.date).filter(Boolean).sort()
  return {
    drugs, total: d.length, newDrugs,
    expanded: d.length - newDrugs,
    years: dates.length > 1 ? dates[0].slice(0,4) + ' - ' + dates[dates.length-1].slice(0,4) : dates[0]?.slice(0,4) || '',
  }
})

function tlYearRange() {
  const d = timelineData.value.map((a: any) => parseInt((a.date || '').slice(0, 4))).filter((y: number) => !isNaN(y))
  if (!d.length) return { min: 2000, max: 2030, span: 30 }
  return { min: Math.min(...d) - 1, max: Math.max(...d) + 2, span: Math.max(...d) - Math.min(...d) + 3 }
}

function tlX(dateStr: string, width: number): number {
  const { min, span } = tlYearRange()
  const y = parseInt((dateStr || '').slice(0, 4))
  if (isNaN(y) || span <= 0) return 140
  return 140 + ((y - min) / span) * (width - 160)
}

function intervals(items: any[]) {
  const r: { from: string; to: string; months: number }[] = []
  for (let i = 1; i < items.length; i++) {
    const a = items[i-1], b = items[i]
    if (a.date && b.date) {
      const da = new Date(a.date), db = new Date(b.date)
      const m = (db.getFullYear() - da.getFullYear()) * 12 + db.getMonth() - da.getMonth()
      r.push({ from: a.date, to: b.date, months: m })
    }
  }
  return r
}

function fmtInterval(m: number) {
  if (m < 12) return `${m}个月`
  const y = Math.floor(m / 12)
  const mo = m % 12
  return mo ? `${y}年${mo}个月` : `${y}年`
}

const svgWidth = computed(() => {
  if (!timelineData.value.length) return 600
  const { min, max } = tlYearRange()
  const span = max - min
  return Math.max(600, 160 + span * 90)
})

const svgHeight = computed(() => {
  return Math.max(200, swimlaneDrugs.value.length * 80 + 60)
})

const yearTicks = computed(() => {
  const { min, max } = tlYearRange()
  const ticks: number[] = []
  for (let y = min; y <= max; y++) ticks.push(y)
  return ticks
})

function searchCustomTarget() {
  const t = customTargetInput.value.trim().toUpperCase()
  if (t) { timelineTarget.value = t; loadTimeline(t) }
  customTargetInput.value = ''
}

async function loadTimeline(target: string) {
  timelineTarget.value = target
  timelineLoading.value = true
  try {
    const { data } = await api.get('/approvals/drug-approvals/timeline', { params: { target } })
    timelineData.value = data.approvals || []
    activeTab.value = 'timeline'
  } catch { toast.error('加载时间线失败') }
  finally { timelineLoading.value = false }
}

// ── Yearly aggregation ──
const yearlyData = computed(() => {
  const map: Record<string, number> = {}
  for (const a of approvals.value) {
    const year = a.approval_date?.slice(0, 4)
    if (year) map[year] = (map[year] || 0) + 1
  }
  return Object.entries(map).sort(([a], [b]) => b.localeCompare(a))
})

// ── Calendar ──
const calendarYear = ref(new Date().getFullYear())
const calendarMonth = ref(new Date().getMonth() + 1)
const monthApprovals = ref<any[]>([])
const calLoading = ref(false)
const expandedCell = ref('') // dateStr of expanded cell
const showYearPicker = ref(false)

const weekDays = ['日', '一', '二', '三', '四', '五', '六']
const todayStr = new Date().toISOString().slice(0, 10)

const years = computed(() => {
  const y = new Date().getFullYear()
  return Array.from({ length: 11 }, (_, i) => y - 10 + i)
})

const calendarDays = computed(() => {
  const year = calendarYear.value
  const month = calendarMonth.value
  const firstDay = new Date(year, month - 1, 1)
  const lastDay = new Date(year, month, 0)
  const daysInMonth = lastDay.getDate()
  const startWeekday = firstDay.getDay()
  const grid: Array<{ day: number | null; dateStr: string }> = []
  for (let i = 0; i < startWeekday; i++) {
    grid.push({ day: null, dateStr: '' })
  }
  for (let d = 1; d <= daysInMonth; d++) {
    const ds = `${year}-${String(month).padStart(2, '0')}-${String(d).padStart(2, '0')}`
    grid.push({ day: d, dateStr: ds })
  }
  return grid
})

// Map date → approvals for current month
const approvalsByDate = computed(() => {
  const map: Record<string, any[]> = {}
  for (const a of monthApprovals.value) {
    const d = a.approval_date?.slice(0, 10)
    if (d) {
      if (!map[d]) map[d] = []
      map[d].push(a)
    }
  }
  return map
})

const monthStats = computed(() => {
  const total = monthApprovals.value.length
  const newDrugs = monthApprovals.value.filter(a => a.approval_type === 'new_drug').length
  const expanded = monthApprovals.value.filter(a => a.approval_type === 'expanded_indication').length
  const targets = [...new Set(monthApprovals.value.map(a => a.target).filter(Boolean))]
  return { total, newDrugs, expanded, targets }
})

function typeColor(type: string): string {
  return type === 'new_drug' ? '#18a058' : '#2080f0'
}

function typeLabel(type: string): string {
  return type === 'new_drug' ? '新药获批' : '适应症扩展'
}

function typeIcon(type: string): string {
  return type === 'new_drug' ? '🏷️' : '📎'
}

function prevMonth() {
  if (calendarMonth.value === 1) {
    calendarMonth.value = 12
    calendarYear.value--
  } else {
    calendarMonth.value--
  }
  loadCalendarData()
}

function nextMonth() {
  if (calendarMonth.value === 12) {
    calendarMonth.value = 1
    calendarYear.value++
  } else {
    calendarMonth.value++
  }
  loadCalendarData()
}

function goToToday() {
  calendarYear.value = new Date().getFullYear()
  calendarMonth.value = new Date().getMonth() + 1
  expandedCell.value = ''
  loadCalendarData()
}

function selectYear(y: number) {
  calendarYear.value = y
  showYearPicker.value = false
  loadCalendarData()
}

function toggleCell(dateStr: string) {
  if (expandedCell.value === dateStr) {
    expandedCell.value = ''
  } else {
    expandedCell.value = dateStr
  }
}

function formatDate(dateStr: string) {
  const d = new Date(dateStr + 'T00:00:00')
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

async function loadCalendarData() {
  calLoading.value = true
  expandedCell.value = ''
  try {
    const { data } = await api.get('/approvals/drug-approvals', {
      params: { year: calendarYear.value, month: calendarMonth.value, page: 1, page_size: 200 },
    })
    monthApprovals.value = data.items || []
  } catch (e) { toast.apiError(e, '加载审批日历失败') }
  finally { calLoading.value = false }
}

onMounted(async () => {
  await loadData()
  if (auth.isAuthenticated) { loadSubscriptions(); loadSubStats() }
  // Preload default timeline
  loadTimeline(timelineTarget.value)
})

watch(activeTab, (tab) => {
  if (tab === 'calendar' && !monthApprovals.value.length) loadCalendarData()
  if (tab === 'timeline' && !timelineData.value.length) loadTimeline(timelineTarget.value)
  if (tab === 'subs' && auth.isAuthenticated) loadSubStats()
  if (tab === 'landscape') loadLandscape()
})

async function loadData() {
  loading.value = true
  try {
    const params: any = { page: page.value, page_size: pageSize.value }
    if (agency.value) params.agency = agency.value
    const { data } = await api.get('/approvals/drug-approvals', { params })
    approvals.value = data.items || []
    total.value = data.total || 0
  } finally { loading.value = false }
}

async function loadSubscriptions() {
  try {
    const { data } = await api.get('/approvals/subscribed-targets')
    subscribedTargets.value = data.targets || []
  } catch { /* ignore */ }
}

async function toggleSubscribe(target: string) {
  if (!auth.isAuthenticated) {
    router.push('/auth/login')
    return
  }
  const idx = subscribedTargets.value.indexOf(target)
  if (idx >= 0) {
    subscribedTargets.value.splice(idx, 1)
    try { await api.post('/approvals/unsubscribe-target', { target }) } catch {}
  } else {
    subscribedTargets.value.push(target)
    try { await api.post('/approvals/subscribe-target', { target }) } catch {}
  }
}

// ── Subscription Stats ──
const targetStats = ref<Record<string, any>>({})
const allTargetStats = ref<Record<string, any>>({})
const subLoading = ref(false)

const subscribedTargetsWithStats = computed(() =>
  subscribedTargets.value.map(t =>
    targetStats.value[t] || { target: t, approval_count: 0, drug_count: 0, latest_date: null, latest_drug: '' }
  )
)

const discoverTargets = computed(() => {
  const pool = [...new Set([...HOT_TARGETS, ...Object.keys(allTargetStats.value)])]
  return pool
    .filter(t => !subscribedTargets.value.includes(t))
    .map(t => allTargetStats.value[t] || { target: t, approval_count: 0, drug_count: 0 })
    .sort((a, b) => (b.approval_count || 0) - (a.approval_count || 0))
    .slice(0, 20)
})

async function loadSubStats() {
  subLoading.value = true
  try {
    const allT = [...new Set([...subscribedTargets.value, ...HOT_TARGETS])]
    if (!allT.length) return
    const { data } = await api.get('/approvals/drug-approvals/target-stats', { params: { targets: allT.join(',') } })
    targetStats.value = data.stats || {}
    allTargetStats.value = data.stats || {}
  } catch { /* ignore */ }
  finally { subLoading.value = false }
}

// ── Competitive Landscape ──
const landscapeData = ref<any[]>([])
const landscapeTargets = ref<string[]>([])
const landscapeLoading = ref(false)
const landscapeFilter = ref<string | null>(null)

const landscapeChartData = computed(() => {
  const items = landscapeFilter.value
    ? landscapeData.value.filter((l: any) => l.target === landscapeFilter.value)
    : landscapeData.value.slice(0, 1)
  if (!items.length) return null
  const item = items[0]
  const labels = item.cancers?.length ? item.cancers : ['其他']
  const values = labels.map((c: string) =>
    item.drugs?.filter((d: any) => d.cancers?.includes(c)).length || 0
  )
  if (values.every((v: number) => v === 0)) return null
  return {
    labels,
    datasets: [{
      label: `${item.target} — 药物覆盖癌种数`,
      backgroundColor: '#1a5276',
      data: values,
    }]
  }
})

const landscapeChartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: false } },
  scales: {
    y: { beginAtZero: true, ticks: { stepSize: 1 } },
    x: { ticks: { maxRotation: 45, font: { size: 10 } } },
  },
}

const landscapeCols = [
  { title: '靶点', key: 'target', width: 80, sortable: true },
  { title: '药物数', key: 'drug_count', width: 70, sortable: true },
  { title: '审批数', key: 'total_approvals', width: 70, sortable: true },
  { title: '最早获批', key: 'first_year', width: 80, sortable: true },
  { title: '覆盖癌种', key: 'cancers',
    render: (r: any) => (r.cancers || []).slice(0, 4).join(', ') + ((r.cancers?.length || 0) > 4 ? '…' : ''),
  },
]

const landscapeScrollX = 600
async function loadLandscape() {
  if (landscapeData.value.length) return
  landscapeLoading.value = true
  try {
    const { data } = await api.get('/approvals/drug-approvals/competitive-landscape')
    landscapeData.value = data.landscape || []
    landscapeTargets.value = data.targets || []
  } catch { toast.error('加载格局数据失败') }
  finally { landscapeLoading.value = false }
}

// ── Label Detail ──
const showLabelDrawer = ref(false)
const labelData = ref<any>(null)
const labelLoading = ref(false)
const selectedApproval = ref<any>(null)
const drugGuidelines = ref<any[]>([])
const drugGuidelinesLoading = ref(false)

// ── 指南证据弹窗 ──
const showGuidelineEvModal = ref(false)
const selectedGuideline = ref<any>(null)
const guidelineEvidence = ref<any[]>([])
const guidelineEvLoading = ref(false)
const lineLabels: Record<string,string> = { '1L':'一线', '2L':'二线', '3L':'三线', adjuvant:'辅助', neoadjuvant:'新辅助', maintenance:'维持' }

async function viewGuidelineEvidence(g: any) {
  selectedGuideline.value = g
  showGuidelineEvModal.value = true
  guidelineEvLoading.value = true
  try {
    const { data } = await api.get(`/approvals/guidelines/${g.id}/evidence`)
    guidelineEvidence.value = data.items || []
  } catch { toast.error('加载证据失败') }
  finally { guidelineEvLoading.value = false }
}

async function loadLabel(approvalId: string) {
  labelLoading.value = true
  showLabelDrawer.value = true
  drugGuidelines.value = []
  try {
    const { data } = await api.get(`/approvals/drug-approvals/${approvalId}/label`)
    labelData.value = data
    selectedApproval.value = data.approval
  } catch { toast.error('加载标签详情失败') }
  finally { labelLoading.value = false }
  // Load related guidelines
  drugGuidelinesLoading.value = true
  try {
    const { data } = await api.get(`/approvals/drug-approvals/${approvalId}/guidelines`)
    drugGuidelines.value = data.guidelines || []
  } catch { /* silent */ }
  finally { drugGuidelinesLoading.value = false }
}

</script>

<template>
  <div style="max-width:1000px;margin:0 auto;padding:32px 24px">
    <div style="text-align:center;margin-bottom:32px">
      <h1 style="font-size:28px;margin-bottom:8px">💊 肿瘤新药审批追踪</h1>
      <p style="color:var(--text-secondary)">追踪 FDA / NMPA / EMA 肿瘤药物审批动态</p>
    </div>

    <NTabs v-model:value="activeTab" type="line">
      <NTabPane name="list" tab="📋 审批列表">
        <!-- Filter -->
        <div style="display:flex;gap:12px;margin-bottom:24px;justify-content:center;flex-wrap:wrap">
          <NButton :type="!agency ? 'primary' : 'default'" size="small" class="sky-btn" @click="agency=null;loadData()"><template #icon><NIcon size="14"><CheckmarkOutline /></NIcon></template>全部</NButton>
          <NButton :type="agency==='FDA' ? 'primary' : 'default'" size="small" class="sky-btn" @click="agency='FDA';loadData()">🇺🇸 FDA</NButton>
          <NButton :type="agency==='NMPA' ? 'primary' : 'default'" size="small" class="sky-btn" @click="agency='NMPA';loadData()">🇨🇳 NMPA</NButton>
          <NButton :type="agency==='EMA' ? 'primary' : 'default'" size="small" class="sky-btn" @click="agency='EMA';loadData()">🇪🇺 EMA</NButton>
        </div>

        <!-- Year summary -->
        <div v-if="yearlyData.length" style="display:flex;gap:12px;justify-content:center;margin-bottom:16px;flex-wrap:wrap">
          <NTag v-for="[year, count] in yearlyData" :key="year" size="small" :bordered="false">{{ year }}年 · {{ count }} 项</NTag>
        </div>

        <NSkeleton v-if="loading" text :repeat="4" />
        <NEmpty v-else-if="!approvals.length" description="暂无审批记录" style="padding:48px 0" />
        <n-grid v-else :cols="2" :x-gap="16" responsive="screen" :y-gap="16">
          <n-grid-item v-for="a in approvals" :key="a.id">
            <n-card size="small" style="cursor:pointer">
              <template #header>
                <div style="display:flex;justify-content:space-between;align-items:flex-start">
                  <div>
                    <strong style="font-size:15px">{{ a.drug_name }}</strong>
                    <NTag size="tiny" style="margin-left:6px" :bordered="false">{{ a.approval_agency }}</NTag>
                  </div>
                </div>
              </template>
              <div style="font-size:14px;color:var(--text-secondary);margin-bottom:6px">{{ a.generic_name }}</div>
              <div style="font-size:13px;color:var(--text-secondary);margin-bottom:6px;line-height:1.5">
                🎯 靶点：<strong>{{ a.target }}</strong>
                <NButton size="tiny" text style="margin-left:6px" @click="toggleSubscribe(a.target)">
                  {{ subscribedTargets.includes(a.target) ? '🔔 已订阅' : '🔕 订阅' }}
                </NButton>
                <NButton size="tiny" text style="margin-left:4px" @click="loadTimeline(a.target)">
                  时间线
                </NButton>
              </div>
              <div style="font-size:13px;color:var(--text-secondary);margin-bottom:6px;line-height:1.5">{{ a.indication }}</div>
              <div style="font-size:12px;color:var(--text-muted);display:flex;justify-content:space-between">
                <span>📅 {{ a.approval_date }}</span>
                <span v-if="a.approval_type">{{ a.approval_type === 'new_drug' ? '新药获批' : '适应症扩展' }}</span>
                <span>
                  <NButton size="tiny" text style="margin-right:6px" @click.stop="loadLabel(a.id)">📋 标签</NButton>
                  <span v-if="a.pivotal_trial_pmid" @click.stop="router.push(`/literature/${a.pivotal_trial_pmid}`)" style="cursor:pointer;color:#1a5276">📄 关键试验</span>
                </span>
              </div>
            </n-card>
          </n-grid-item>
        </n-grid>

        <div v-if="total > pageSize" style="display:flex;justify-content:center;margin-top:24px">
          <NPagination :page="page" :page-size="pageSize" :item-count="total" @update:page="p => { page=p; loadData() }" />
        </div>

        <NDivider />
        <div style="text-align:center">
          <NButton class="sky-btn" v-if="!auth.isAuthenticated" type="primary" ghost @click="router.push('/auth/register')">
            🔒 注册后按靶点订阅审批通知
          </NButton>
        </div>
      </NTabPane>

      <!-- Calendar -->
      <NTabPane name="calendar" tab="📆 日历视图">
        <!-- Navigation -->
        <div class="cal-nav">
          <NButton class="sky-btn" size="tiny" @click="prevMonth">‹ 上月</NButton>
          <div style="display:flex;align-items:center;gap:8px">
            <NButton class="sky-btn" size="tiny" ghost @click="showYearPicker = !showYearPicker">{{ calendarYear }} 年</NButton>
            <span class="cal-title">{{ calendarMonth }} 月</span>
          </div>
          <NButton class="sky-btn" size="tiny" @click="nextMonth">下月 ›</NButton>
          <NButton class="sky-btn" size="tiny" quaternary @click="goToToday" style="margin-left:4px">今天</NButton>
        </div>

        <!-- Year picker dropdown -->
        <div v-if="showYearPicker" class="year-picker">
          <span v-for="y in years" :key="y" class="year-opt" :class="{ active: y === calendarYear }" @click="selectYear(y)">{{ y }}</span>
        </div>

        <!-- Monthly stats -->
        <div v-if="monthApprovals.length" class="cal-stats">
          <span>本月 <strong>{{ monthStats.total }}</strong> 项审批</span>
          <span class="stat-divider">·</span>
          <span class="stat-new">{{ monthStats.newDrugs }} 新药</span>
          <span class="stat-divider">·</span>
          <span class="stat-expand">{{ monthStats.expanded }} 适应症扩展</span>
          <span v-if="monthStats.targets.length" class="stat-divider">·</span>
          <span v-if="monthStats.targets.length" style="font-size:12px;color:var(--text-muted)">
            涉及 {{ monthStats.targets.slice(0, 4).join(' / ') }}<span v-if="monthStats.targets.length > 4">…</span>
          </span>
        </div>
        <div v-else-if="!calLoading" class="cal-stats" style="color:var(--text-muted)">本月暂无审批记录</div>

        <NSkeleton v-if="calLoading" text :repeat="6" />
        <template v-else>
          <div class="cal-grid">
            <div v-for="wd in weekDays" :key="wd" class="cal-weekday">{{ wd }}</div>
            <template v-for="(cell, idx) in calendarDays" :key="idx">
              <div
                v-if="cell.day"
                class="cal-cell"
                :class="{
                  'cal-today': cell.dateStr === todayStr,
                  'cal-expanded': expandedCell === cell.dateStr,
                  'cal-has-data': approvalsByDate[cell.dateStr]?.length,
                }"
                @click="toggleCell(cell.dateStr)"
              >
                <div class="cal-day-num">{{ cell.day }}</div>
                <div v-if="approvalsByDate[cell.dateStr]?.length" class="cal-drugs">
                  <div
                    v-for="a in (approvalsByDate[cell.dateStr] || []).slice(0, 2)"
                    :key="a.id"
                    class="cal-drug-label"
                    :style="{ background: typeColor(a.approval_type) + '18', color: typeColor(a.approval_type) }"
                    :title="a.indication"
                  >
                    {{ a.drug_name.length > 8 ? a.drug_name.slice(0, 6) + '…' : a.drug_name }}
                  </div>
                  <div v-if="(approvalsByDate[cell.dateStr]?.length || 0) > 2" class="cal-more-count">
                    +{{ (approvalsByDate[cell.dateStr]?.length || 0) - 2 }}
                  </div>
                </div>
              </div>
              <div v-else class="cal-cell cal-other"></div>
            </template>
          </div>

          <!-- Inline expanded day details -->
          <div v-if="expandedCell && approvalsByDate[expandedCell]?.length" class="cal-day-detail">
            <div class="cal-day-header">
              <strong>📅 {{ formatDate(expandedCell) }}</strong>
              <span class="cal-day-count">{{ approvalsByDate[expandedCell]?.length || 0 }} 项审批</span>
              <NButton class="sky-btn" size="tiny" quaternary @click="expandedCell = ''">✕ 收起</NButton>
            </div>
            <div v-for="a in (approvalsByDate[expandedCell] || [])" :key="a.id" class="cal-day-item">
              <div class="cal-day-item-main">
                <span class="cal-day-icon">{{ typeIcon(a.approval_type) }}</span>
                <div>
                  <div class="cal-day-drug">{{ a.drug_name }}
                    <NTag size="tiny" :bordered="false" :color="{ color: typeColor(a.approval_type) + '18', textColor: typeColor(a.approval_type) }">{{ typeLabel(a.approval_type) }}</NTag>
                  </div>
                  <div class="cal-day-meta">{{ a.generic_name }}<span v-if="a.target"> · 🎯 {{ a.target }}</span></div>
                  <div class="cal-day-indication">{{ a.indication }}</div>
                </div>
              </div>
              <div v-if="a.pivotal_trial_pmid" class="cal-day-trial">
                <NButton size="tiny" text @click.stop="router.push(`/literature/${a.pivotal_trial_pmid}`)">📄 关键试验</NButton>
                <NButton size="tiny" text style="margin-left:6px" @click.stop="loadLabel(a.id)">📋 标签</NButton>
              </div>
              <div v-else class="cal-day-trial">
                <NButton size="tiny" text @click.stop="loadLabel(a.id)">📋 标签</NButton>
              </div>
            </div>
          </div>
        </template>
      </NTabPane>

      <!-- Timeline Swimlane -->
      <NTabPane name="timeline" tab="📅 审批时间线">
        <!-- Target selector -->
        <div style="display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-bottom:12px">
          <NTag v-for="t in HOT_TARGETS" :key="t"
            :bordered="false"
            :style="timelineTarget === t ? { background: '#1a5276', color: '#fff', cursor: 'pointer' } : { cursor: 'pointer' }"
            @click="loadTimeline(t)">{{ t }}</NTag>
          <div style="display:flex;gap:4px;align-items:center;margin-left:8px">
            <input v-model="customTargetInput"
              placeholder="输入靶点..."
              style="width:100px;padding:2px 8px;border:1px solid var(--border-color);border-radius:4px;font-size:12px;background:transparent;color:var(--text-primary);outline:none"
              @keyup.enter="searchCustomTarget" />
            <NButton size="tiny" class="sky-btn" @click="searchCustomTarget">查询</NButton>
          </div>
        </div>

        <!-- Stats -->
        <div v-if="tlStats.total" class="tl-stats">
          <span><strong>{{ tlStats.total }}</strong> 次审批 · </span>
          <span><strong>{{ tlStats.drugs }}</strong> 种药物 · </span>
          <span class="stat-new">{{ tlStats.newDrugs }} 新药</span>
          <span class="stat-divider">/</span>
          <span class="stat-expand">{{ tlStats.expanded }} 适应症</span>
          <span class="stat-divider">·</span>
          <span style="color:var(--text-muted)">{{ tlStats.years }}</span>
        </div>

        <!-- Loading -->
        <NSkeleton v-if="timelineLoading" text :repeat="6" />
        <div v-else-if="!timelineData.length" style="text-align:center;padding:40px;color:var(--text-muted)">
          该靶点暂无审批数据
        </div>

        <!-- Swimlane SVG -->
        <div v-else class="tl-svg-wrap">
          <svg :width="svgWidth" :height="svgHeight" class="tl-svg">
            <!-- Year grid lines -->
            <line v-for="y in yearTicks" :key="'grid-'+y"
              :x1="tlX(String(y)+'-01-01', svgWidth)" :x2="tlX(String(y)+'-01-01', svgWidth)"
              y1="0" :y2="svgHeight - 30"
              stroke="var(--border-color)" stroke-width="1" stroke-dasharray="4,4" />

            <!-- Year labels -->
            <text v-for="y in yearTicks" :key="'label-'+y"
              :x="tlX(String(y)+'-01-01', svgWidth)" y="22"
              text-anchor="middle" fill="var(--text-muted)" font-size="11" font-weight="600">{{ y }}</text>

            <!-- Per-drug lanes -->
            <template v-for="(lane, li) in swimlaneDrugs" :key="lane.drug">
              <line
                x1="140" :x2="svgWidth - 20"
                :y1="60 + li * 80" :y2="60 + li * 80"
                stroke="var(--border-color)" stroke-width="1" stroke-opacity="0.3" />

              <!-- Drug name -->
              <text x="8" :y="60 + li * 80 + 4" fill="var(--text-primary)" font-size="13" font-weight="600"
                text-anchor="start" dominant-baseline="middle">{{ lane.drug }}</text>

              <!-- Connector line between dots -->
              <polyline
                :points="lane.items.map(a => `${tlX(a.date, svgWidth)},${60 + li * 80}`).join(' ')"
                fill="none" stroke="var(--border-color)" stroke-width="1.5" stroke-opacity="0.5" />

              <!-- Approval dots -->
              <template v-for="item in lane.items" :key="item.date + item.target">
                <circle
                  :cx="tlX(item.date, svgWidth)" :cy="60 + li * 80" :r="item.approval_type === 'new_drug' ? 8 : 6"
                  :fill="item.approval_type === 'new_drug' ? '#18a058' : 'none'"
                  :stroke="item.approval_type === 'new_drug' ? '#18a058' : '#2080f0'"
                  :stroke-width="item.approval_type === 'new_drug' ? 0 : 2"
                  style="cursor:pointer;transition:r 0.15s"
                  @mouseenter="showTlTooltip = true; tlTooltip = { x: tlX(item.date, svgWidth), y: 60 + li * 80, item }"
                  @mouseleave="showTlTooltip = false"
                />
                <!-- Date label -->
                <text :x="tlX(item.date, svgWidth)" :y="60 + li * 80 + 16"
                  text-anchor="middle" fill="var(--text-muted)" font-size="9">{{ item.date?.slice(0,10) }}</text>
              </template>

              <!-- Interval annotations -->
              <template v-for="seg in intervals(lane.items)" :key="seg.to + seg.from">
                <text
                  :x="(tlX(seg.to, svgWidth) + tlX(seg.from, svgWidth)) / 2"
                  :y="60 + li * 80 - 14"
                  text-anchor="middle" fill="var(--text-muted)" font-size="9" font-style="italic">
                  间隔 {{ fmtInterval(seg.months) }}
                </text>
              </template>
            </template>
          </svg>

          <!-- Tooltip -->
          <div v-if="showTlTooltip && tlTooltip.item" class="tl-tooltip"
            :style="{ left: Math.min(tlTooltip.x, svgWidth - 260) + 'px', top: (tlTooltip.y - 100) + 'px' }">
            <div class="tl-tt-drug">{{ tlTooltip.item.drug_name }}</div>
            <div class="tl-tt-meta">{{ tlTooltip.item.generic_name }}
              <NTag size="tiny" :bordered="false" :color="{ color: (tlTooltip.item.approval_type === 'new_drug' ? '#18a058' : '#2080f0') + '18', textColor: tlTooltip.item.approval_type === 'new_drug' ? '#18a058' : '#2080f0' }">{{ tlTooltip.item.approval_type === 'new_drug' ? '新药' : '适应症' }}</NTag>
            </div>
            <div class="tl-tt-indication">{{ tlTooltip.item.indication }}</div>
            <div class="tl-tt-date">{{ tlTooltip.item.date }}</div>
          </div>
        </div>

        <!-- Target details link -->
        <div v-if="timelineData.length" style="text-align:center;margin-top:12px;font-size:12px;color:var(--text-muted)">
          点击审批列表中的 🎯 靶点标签可直接跳转至此时间线
        </div>
      </NTabPane>

      <!-- Competitive Landscape -->
      <NTabPane name="landscape" tab="🗺️ 靶点格局">
        <NSkeleton v-if="landscapeLoading" text :repeat="6" />
        <template v-else>
          <!-- Target filter chips -->
          <div v-if="landscapeTargets.length" style="display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-bottom:16px">
            <NTag :bordered="false"
              :style="{ cursor:'pointer', background: !landscapeFilter ? '#1a5276' : undefined, color: !landscapeFilter ? '#fff' : undefined }"
              @click="landscapeFilter = null">全部</NTag>
            <NTag v-for="t in landscapeTargets.slice(0, 30)" :key="t"
              :bordered="false"
              :style="{ cursor:'pointer', background: landscapeFilter === t ? '#1a5276' : undefined, color: landscapeFilter === t ? '#fff' : undefined }"
              @click="landscapeFilter = t">{{ t }}</NTag>
            <span v-if="landscapeTargets.length > 30" style="font-size:12px;color:var(--text-muted);align-self:center">…{{ landscapeTargets.length - 30 }} 个</span>
          </div>

          <!-- Table and Chart -->
          <div style="display:flex;flex-direction:column;gap:16px">
            <!-- Overview table -->
            <NDataTable :columns="landscapeCols" :data="landscapeFilter ? landscapeData.filter((l:any) => l.target === landscapeFilter) : landscapeData" :bordered="false" size="small" :scroll-x="landscapeScrollX"
              :row-key="(r:any) => r.target" />

            <!-- Chart for selected target -->
            <div v-if="landscapeChartData" style="background:var(--bg-card);border-radius:8px;padding:16px;min-height:300px">
              <div style="font-size:14px;font-weight:700;margin-bottom:12px">药物覆盖癌种分布 — {{ landscapeFilter || (landscapeData[0]?.target || '') }}</div>
              <div style="height:280px">
                <Bar :data="landscapeChartData" :options="landscapeChartOptions" />
              </div>
            </div>

            <!-- Drug list for selected target -->
            <div style="background:var(--bg-card);border-radius:8px;padding:16px">
              <div style="font-size:14px;font-weight:700;margin-bottom:12px">
                {{ landscapeFilter || (landscapeData[0]?.target || '') }} — 药物列表
              </div>
              <div style="display:flex;flex-wrap:wrap;gap:8px">
                <NTag v-for="d in (landscapeData.find((l:any) => l.target === (landscapeFilter || landscapeData[0]?.target))?.drugs || [])" :key="d.generic_name" size="tiny" :bordered="false">
                  {{ d.drug_name }} ({{ d.first_year }})
                </NTag>
              </div>
            </div>
          </div>
        </template>
      </NTabPane>

      <!-- Subscribed targets -->
      <NTabPane v-if="auth.isAuthenticated" name="subs" :tab="'🔔 订阅管理' + (subscribedTargets.length ? ' (' + subscribedTargets.length + ')' : '')">
        <NSkeleton v-if="subLoading" text :repeat="4" />
        <template v-else>
          <!-- Subscribed target cards -->
          <div v-if="subscribedTargetsWithStats.length" class="sub-section">
            <div class="sub-section-title">已订阅靶点</div>
            <div class="sub-cards">
              <div v-for="st in subscribedTargetsWithStats" :key="st.target" class="sub-card">
                <div class="sub-card-top">
                  <span class="sub-card-target">🎯 {{ st.target }}</span>
                  <div class="sub-card-actions">
                    <NButton size="tiny" quaternary class="sky-btn" @click="loadTimeline(st.target)">时间线</NButton>
                    <NButton size="tiny" quaternary style="color:var(--text-muted)" @click="toggleSubscribe(st.target)">取消订阅</NButton>
                  </div>
                </div>
                <div class="sub-card-stats">
                  <div class="sub-stat">
                    <span class="sub-stat-val">{{ st.approval_count || '-' }}</span>
                    <span class="sub-stat-lbl">审批次数</span>
                  </div>
                  <div class="sub-stat">
                    <span class="sub-stat-val">{{ st.drug_count || '-' }}</span>
                    <span class="sub-stat-lbl">获批药物</span>
                  </div>
                  <div class="sub-stat">
                    <span class="sub-stat-val">{{ st.latest_date || '-' }}</span>
                    <span class="sub-stat-lbl">最近审批</span>
                  </div>
                </div>
                <div v-if="st.latest_drug" class="sub-card-latest">
                  🆕 <strong>{{ st.latest_drug }}</strong>
                  <span style="color:var(--text-muted)">{{ st.latest_date }}</span>
                </div>
              </div>
            </div>
          </div>
          <div v-else class="sub-empty">
            <div>尚未订阅任何靶点</div>
            <div class="sub-empty-hint">从下方发现热门靶点开始订阅</div>
          </div>

          <!-- Discover more -->
          <div v-if="discoverTargets.length" class="sub-section">
            <div class="sub-section-title">发现更多靶点</div>
            <div class="discover-grid">
              <div v-for="dt in discoverTargets" :key="dt.target" class="discover-item" @click="toggleSubscribe(dt.target)">
                <div class="discover-item-top">
                  <strong>{{ dt.target }}</strong>
                  <span v-if="!subscribedTargets.includes(dt.target)" class="discover-plus">+ 订阅</span>
                </div>
                <div class="discover-item-meta">
                  <span>{{ dt.drug_count || '-' }} 种药物</span>
                  <span class="stat-divider">·</span>
                  <span>{{ dt.approval_count || '-' }} 次审批</span>
                </div>
              </div>
            </div>
          </div>
        </template>
      </NTabPane>
    </NTabs>
  </div>

  <!-- Label Detail Drawer -->
  <NDrawer v-model:show="showLabelDrawer" :width="600" placement="right">
    <NDrawerContent title="📋 FDA 标签详情" closable @close="showLabelDrawer = false">
      <NSkeleton v-if="labelLoading" text :repeat="8" />
      <template v-else-if="labelData">
        <div v-if="selectedApproval" style="margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border-color)">
          <div style="font-size:16px;font-weight:700">{{ selectedApproval.drug_name }}</div>
          <div style="font-size:13px;color:var(--text-secondary)">{{ selectedApproval.generic_name }}
            <NTag size="tiny" style="margin-left:6px" :bordered="false">{{ selectedApproval.target }}</NTag>
          </div>
        </div>

        <template v-if="labelData.labels?.length">
          <div v-for="(l, li) in labelData.labels" :key="l.set_id" style="margin-bottom:20px">
            <NTag size="tiny" style="margin-bottom:8px" :bordered="false">
              标签 v{{ labelData.labels.length - li }} · {{ l.effective_time?.slice(0,4) || '?' }}
            </NTag>

            <div v-if="l.indications_and_usage" class="label-section">
              <div class="label-sec-title">适应症及用法</div>
              <div class="label-sec-body" style="white-space:pre-wrap;max-height:300px;overflow-y:auto">{{ l.indications_and_usage }}</div>
            </div>

            <div v-if="l.mechanism_of_action" class="label-section">
              <div class="label-sec-title">作用机制</div>
              <div class="label-sec-body" style="white-space:pre-wrap;max-height:200px;overflow-y:auto">{{ l.mechanism_of_action }}</div>
            </div>

            <div v-if="l.clinical_studies" class="label-section">
              <div class="label-sec-title">关键临床研究</div>
              <div class="label-sec-body" style="white-space:pre-wrap;max-height:400px;overflow-y:auto">{{ l.clinical_studies }}</div>
              <div v-if="l.nct_numbers?.length" style="margin-top:6px">
                <span style="font-size:11px;color:var(--text-muted)">临床试验编号：</span>
                <NTag v-for="nct in l.nct_numbers.slice(0,10)" :key="nct" size="tiny" style="margin:2px" :bordered="false">{{ nct }}</NTag>
                <span v-if="l.nct_numbers.length > 10" style="font-size:11px;color:var(--text-muted)">…等{{ l.nct_numbers.length }}项</span>
              </div>
            </div>

            <div v-if="l.warnings" class="label-section">
              <div class="label-sec-title" style="color:#d03050">⚠️ 警告及注意事项</div>
              <div class="label-sec-body" style="white-space:pre-wrap;max-height:200px;overflow-y:auto;color:var(--text-secondary)">{{ l.warnings }}</div>
            </div>
          </div>

          <!-- 关键临床试验 -->
          <div v-if="labelData.clinical_trials?.length" class="label-section" style="margin-top:20px">
            <div class="label-sec-title">📄 关键临床试验文献</div>
            <div style="display:flex;flex-direction:column;gap:8px">
              <div v-for="t in labelData.clinical_trials" :key="t.pmid"
                style="padding:8px 10px;background:var(--bg-hover);border-radius:6px;cursor:pointer"
                @click="router.push(`/literature/${t.pmid}`)">
                <div style="font-size:13px;font-weight:600;color:var(--text-primary);margin-bottom:4px;line-height:1.4">
                  {{ t.title?.slice(0, 120) }}<span v-if="(t.title?.length || 0) > 120">…</span>
                </div>
                <div style="display:flex;gap:8px;font-size:11px;color:var(--text-muted);align-items:center">
                  <span v-if="t.journal">{{ t.journal }}</span>
                  <span v-if="t.first_author">· {{ t.first_author }}</span>
                  <span v-if="t.pub_date">· {{ t.pub_date }}</span>
                  <NTag v-if="t.cited_by_count" size="tiny" :bordered="false" style="margin-left:auto">
                    {{ t.cited_by_count }} 引用
                  </NTag>
                </div>
              </div>
            </div>
          </div>
          <NEmpty v-else-if="labelData.labels?.length && !labelData.clinical_trials?.length"
            description="暂无关联临床试验文献" style="padding:8px 0" />

          <div v-if="labelData.labels.length > 1" style="margin-top:12px;padding:8px 12px;background:var(--bg-hover);border-radius:6px;font-size:12px;color:var(--text-muted)">
            该药品有 {{ labelData.labels.length }} 个标签版本，显示全部
          </div>

          <!-- 关联指南 -->
          <div class="label-section" style="margin-top:20px">
            <div class="label-sec-title">📋 指南推荐</div>
            <div style="font-size:12px;color:var(--text-muted);margin-bottom:8px">
              {{ labelData?.approval?.indication ? ('适应症：' + labelData.approval.indication.slice(0, 60) + (labelData.approval.indication.length > 60 ? '…' : '')) : '' }}
            </div>
            <NSkeleton v-if="drugGuidelinesLoading" text :repeat="2" />
            <div v-else-if="!drugGuidelines.length" style="font-size:13px;color:var(--text-muted);padding:8px 0">暂无关联指南</div>
            <div v-for="g in drugGuidelines" :key="g.id"
              style="padding:8px 10px;background:var(--bg-hover);border-radius:6px;margin-bottom:6px;cursor:pointer"
              @click="viewGuidelineEvidence(g)">
              <div style="display:flex;gap:6px;align-items:center;margin-bottom:4px">
                <NTag size="tiny" :bordered="false" :color="{
                  color: ({ NCCN:'#2080f0',CSCO:'#d03050',ESMO:'#18a058',NHC:'#f0a020' } as Record<string,string>)[g.source] || '#999'
                }">{{ g.source }}</NTag>
                <strong style="font-size:13px">{{ g.version }}</strong>
                <span style="font-size:11px;color:var(--text-muted);margin-left:auto">{{ g.publish_date }}</span>
              </div>
              <div style="font-size:12px;color:var(--text-secondary);line-height:1.4">
                {{ g.change_summary_zh?.slice(0, 80) }}{{ g.change_summary_zh?.length > 80 ? '…' : '' }}
              </div>
              <div style="font-size:11px;color:var(--text-muted);margin-top:4px">{{ g.evidence_count }} 条证据</div>
            </div>
          </div>
        </template>
        <NEmpty v-else description="暂无 FDA 标签数据" />
      </template>
    </NDrawerContent>
  </NDrawer>

  <!-- 指南证据弹窗 -->
  <NModal v-model:show="showGuidelineEvModal" title="指南证据" closable>
    <NCard v-if="selectedGuideline" style="width:min(600px,calc(100vw - 48px));max-height:70vh;overflow-y:auto">
      <h4 style="margin-top:0;margin-bottom:8px">
        <NTag size="small" :bordered="false" :color="{
          color: ({ NCCN:'#2080f0',CSCO:'#d03050',ESMO:'#18a058',NHC:'#f0a020' } as Record<string,string>)[selectedGuideline.source] || '#999'
        }">{{ selectedGuideline.source }}</NTag>
        {{ selectedGuideline.version }} · {{ selectedGuideline.publish_date }}
      </h4>
      <div v-if="selectedGuideline.change_summary_zh" style="font-size:13px;color:var(--text-secondary);margin-bottom:12px;line-height:1.5">
        {{ selectedGuideline.change_summary_zh }}
      </div>
      <NSkeleton v-if="guidelineEvLoading" text :repeat="3" />
      <div v-else-if="!guidelineEvidence.length" style="color:var(--text-muted);text-align:center;padding:16px">暂无证据文献</div>
      <div v-for="ev in guidelineEvidence" :key="ev.pmid" style="padding:8px 0;border-bottom:1px solid var(--border-color);font-size:14px">
        <div style="display:flex;gap:6px;align-items:flex-start;margin-bottom:4px">
          <NTag size="tiny" type="success">{{ ev.level||'—' }}</NTag>
          <NTag size="tiny" v-if="ev.treatment_line">{{ lineLabels[ev.treatment_line]||ev.treatment_line }}</NTag>
        </div>
        <p style="margin:4px 0;line-height:1.5"><strong>{{ ev.recommendation }}</strong></p>
        <p style="margin:4px 0;font-size:13px;color:var(--text-secondary)">
          📄 <span style="color:#1a5276;cursor:pointer" @click="router.push(`/literature/${ev.pmid}`)">{{ ev.title }}</span>
          <span style="color:var(--text-muted);margin-left:6px">{{ ev.journal }}</span>
        </p>
      </div>
    </NCard>
  </NModal>
</template>

<style scoped>
.tl-svg-wrap { position: relative; overflow-x: auto; margin: 0 -12px; padding: 0 12px; }
.tl-svg { display: block; min-width: 500px; }
.tl-stats { text-align: center; margin-bottom: 16px; font-size: 13px; color: var(--text-secondary); }
/* ── Tweening ── */
.tl-tooltip {
  position: absolute;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 10px 14px;
  pointer-events: none;
  z-index: 100;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  max-width: 280px;
}
.tl-tt-drug { font-size: 14px; font-weight: 700; color: var(--text-primary); margin-bottom: 4px; display: flex; align-items: center; gap: 6px; }
.tl-tt-meta { font-size: 12px; color: var(--text-secondary); margin-bottom: 4px; }
.tl-tt-indication { font-size: 12px; color: var(--text-secondary); line-height: 1.4; margin-bottom: 4px; }
.tl-tt-date { font-size: 11px; color: var(--text-muted); }

.cal-nav { display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.cal-title { font-size: 18px; font-weight: 700; color: #1a5276; min-width: 48px; text-align: center; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; max-width: 700px; margin: 0 auto; }
.cal-weekday { text-align: center; font-size: 12px; font-weight: 600; color: var(--text-muted); padding: 6px 0; }
.cal-cell { min-height: 80px; border: 1px solid var(--border-color); border-radius: 6px; padding: 4px 6px; cursor: pointer; transition: all 0.15s; }
.cal-cell:hover { background: var(--bg-hover); }
.cal-other { background: var(--bg-page); cursor: default; }
.cal-other:hover { background: var(--bg-page); }
.cal-today { border-color: #1a5276; border-width: 2px; background: #1a527608; }
.cal-expanded { border-color: #1a5276; background: #1a527610; box-shadow: 0 0 0 1px #1a527640; }
.cal-has-data { background: #18a05806; }
.cal-day-num { font-size: 13px; font-weight: 600; color: var(--text-primary); margin-bottom: 4px; }
.cal-today .cal-day-num { color: #1a5276; }
.cal-drugs { display: flex; flex-direction: column; gap: 2px; }
.cal-drug-label { font-size: 10px; font-weight: 600; padding: 1px 4px; border-radius: 3px; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-more-count { font-size: 10px; color: var(--text-muted); text-align: center; }

.year-picker { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-bottom: 12px; padding: 8px; background: var(--bg-hover); border-radius: 8px; max-width: 500px; margin-left: auto; margin-right: auto; }
.year-opt { padding: 4px 12px; border-radius: 4px; font-size: 13px; cursor: pointer; transition: background 0.15s; color: var(--text-secondary); }
.year-opt:hover { background: var(--bg-card); }
.year-opt.active { background: #1a5276; color: #fff; }

.cal-stats { text-align: center; margin-bottom: 16px; font-size: 13px; color: var(--text-secondary); }
.stat-divider { margin: 0 6px; color: var(--text-muted); }
.stat-new { color: #18a058; font-weight: 600; }
.stat-expand { color: #2080f0; font-weight: 600; }

.cal-day-detail { max-width: 700px; margin: 12px auto 0; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; padding: 16px; }
.cal-day-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border-color); }
.cal-day-count { font-size: 12px; color: var(--text-muted); margin-right: auto; }
.cal-day-item { padding: 8px 0; border-bottom: 1px solid var(--border-color); }
.cal-day-item:last-child { border-bottom: none; }
.cal-day-item-main { display: flex; gap: 10px; align-items: flex-start; }
.cal-day-icon { font-size: 16px; line-height: 1.6; }
.cal-day-drug { font-size: 14px; font-weight: 600; margin-bottom: 2px; display: flex; align-items: center; gap: 6px; }
.cal-day-meta { font-size: 12px; color: var(--text-secondary); margin-bottom: 4px; }
.cal-day-indication { font-size: 13px; color: var(--text-secondary); line-height: 1.4; }
.cal-day-trial { margin-top: 4px; margin-left: 26px; }

/* ── Subscription ── */
.sub-section { margin-bottom: 28px; }
.sub-section-title { font-size: 14px; font-weight: 700; color: var(--text-primary); margin-bottom: 12px; padding-bottom: 6px; border-bottom: 1px solid var(--border-color); }
.sub-empty { text-align: center; padding: 40px; color: var(--text-muted); font-size: 14px; }
.sub-empty-hint { font-size: 12px; margin-top: 6px; color: var(--text-muted); opacity: 0.7; }
.sub-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.sub-card { background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 10px; padding: 16px; transition: box-shadow 0.15s; }
.sub-card:hover { box-shadow: 0 2px 12px rgba(0,0,0,0.06); }
.sub-card-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.sub-card-target { font-size: 16px; font-weight: 700; color: #1a5276; }
.sub-card-actions { display: flex; gap: 4px; }
.sub-card-stats { display: flex; gap: 16px; margin-bottom: 10px; }
.sub-stat { display: flex; flex-direction: column; align-items: center; min-width: 60px; }
.sub-stat-val { font-size: 18px; font-weight: 700; color: var(--text-primary); line-height: 1.2; }
.sub-stat-lbl { font-size: 11px; color: var(--text-muted); }
.sub-card-latest { font-size: 12px; color: var(--text-secondary); padding-top: 8px; border-top: 1px solid var(--border-color); display: flex; justify-content: space-between; }
.discover-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.discover-item { display: flex; flex-direction: column; gap: 2px; padding: 10px 14px; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; cursor: pointer; transition: all 0.15s; min-width: 150px; }
.discover-item:hover { border-color: #1a5276; box-shadow: 0 2px 8px rgba(26,82,118,0.1); }
.discover-item-top { display: flex; justify-content: space-between; align-items: center; }
.discover-plus { font-size: 11px; color: #18a058; font-weight: 600; }
.discover-item-meta { font-size: 11px; color: var(--text-muted); }

/* ── Label Drawer ── */
.label-section { margin-bottom: 14px; }
.label-sec-title { font-size: 13px; font-weight: 700; color: var(--text-primary); margin-bottom: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--border-color); }
.label-sec-body { font-size: 13px; color: var(--text-secondary); line-height: 1.7; background: var(--bg-hover); border-radius: 6px; padding: 10px 12px; }
</style>
