<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { NButton, NCard, NCheckbox, NIcon, NRadio, NRadioGroup, NResult, NSpin, NSwitch, NTag, NSkeleton } from 'naive-ui'
import { api } from '../../api/client'
import { SaveOutline, CheckmarkCircleOutline } from '@vicons/ionicons5'
import { useToast } from '../../composables/useToast'

const router = useRouter()
const toast = useToast()
const tags = ref<any[]>([])
const categories = ref<any[]>([])
const loading = ref(true)
const saving = ref(false)
const matchMode = ref('standard')
const selectedIds = ref<string[]>([])
const feedsGenerated = ref(0)
const saveError = ref('')
const saveSuccess = ref(false)

// ── 预估 ──
const estimate = ref<{ total_articles: number; daily_estimate: number; by_priority: Record<string, number> } | null>(null)
const estimateLoading = ref(false)
let _estimateTimer: ReturnType<typeof setTimeout> | null = null

function fetchEstimate() {
  if (_estimateTimer) clearTimeout(_estimateTimer)
  if (!selectedIds.value.length) { estimate.value = null; return }
  _estimateTimer = setTimeout(async () => {
    estimateLoading.value = true
    try {
      const { data } = await api.get('/subscriptions/estimate', {
        params: { tag_ids: selectedIds.value.join(','), match_mode: matchMode.value }
      })
      estimate.value = data
    } catch { /* 静默 */ }
    finally { estimateLoading.value = false }
  }, 300)
}

watch(matchMode, fetchEstimate)
watch(selectedIds, fetchEstimate, { deep: false })

const MODE_DESC: Record<string, { title: string; desc: string }> = {
  standard: { title: '标准（推荐）', desc: '主标签命中优先推送，量适中·质量均衡' },
  loose: { title: '宽松', desc: '任一标签命中推送，量大全面·覆盖广' },
  strict: { title: '严格', desc: '全部标签同时命中才推送，量少精准·无噪声' },
}

// ── 个人偏好 ──
const journalTiers = ref<string[]>([])
const therapyTypes = ref<string[]>([])
const litTypes = ref<string[]>([])
const includeChildren = ref(true)

const THERAPY_OPTIONS = [
  { key: 'targeted_therapy', label: '靶向治疗' },
  { key: 'immunotherapy', label: '免疫治疗' },
  { key: 'chemotherapy', label: '化疗' },
  { key: 'radiotherapy', label: '放疗' },
  { key: 'surgery', label: '外科' },
  { key: 'hormone', label: '内分泌治疗' },
]

const LIT_TYPE_OPTIONS = [
  { key: 'rct', label: 'RCT' },
  { key: 'meta_analysis', label: 'Meta分析' },
  { key: 'guideline', label: '指南' },
  { key: 'review', label: '综述' },
]

const TIER_OPTIONS = [
  { key: 'tier1', label: 'Tier 1', color: '#d03050' },
  { key: 'tier2', label: 'Tier 2', color: '#f0a020' },
  { key: 'tier3', label: 'Tier 3', color: '#2080f0' },
  { key: 'tier4', label: 'Tier 4', color: '#999' },
]

// 按癌种分组
const cancerTags = computed(() => {
  const flat = tags.value.filter((t: any) => t.tag_category === 'cancer' && t.level === 2 && t.is_selectable !== false)
  const children = tags.value.filter((t: any) => t.level === 3)
  return flat.map((t: any) => ({
    ...t,
    children: children.filter((c: any) => c.parent_id === t.id),
  }))
})

// 其他类别
const otherCategories = computed(() => {
  return (categories.value || []).filter((c: any) => c.key !== 'cancer')
})

const tagsByCategory = computed(() => {
  const result: Record<string, any[]> = {}
  for (const t of tags.value) {
    if (t.level === 1) continue
    const cat = t.tag_category
    if (!result[cat]) result[cat] = []
    result[cat].push(t)
  }
  return result
})

// 加载已有订阅
onMounted(async () => {
  try {
    const [tagsRes, myTagsRes, prefsRes] = await Promise.all([
      api.get('/public/tags'),
      api.get('/subscriptions/my-tags'),
      api.get('/subscriptions/preferences'),
    ])
    tags.value = tagsRes.data.tags || []
    categories.value = tagsRes.data.categories || []
    selectedIds.value = (myTagsRes.data || []).map((t: any) => t.tag_id)

    const p = prefsRes.data
    journalTiers.value = p.journal_tiers || []
    therapyTypes.value = p.therapy_types || []
    litTypes.value = p.lit_types || []
    matchMode.value = p.match_mode || 'standard'
    if (selectedIds.value.length) fetchEstimate()
  } catch (e) { toast.apiError(e, '加载失败') }
  finally { loading.value = false }
})

async function saveAndGo() {
  if (!selectedIds.value.length) return
  saving.value = true; saveError.value = ''; saveSuccess.value = false
  try {
    await api.post('/subscriptions/preferences', {
      journal_tiers: journalTiers.value,
      therapy_types: therapyTypes.value,
      lit_types: litTypes.value,
      match_mode: matchMode.value,
    })
    const { data } = await api.post('/subscriptions/batch-subscribe', {
      tag_ids: selectedIds.value,
      match_mode: matchMode.value,
      include_children: includeChildren.value,
    })
    feedsGenerated.value = data.feeds_generated || 0
    saveSuccess.value = true
    setTimeout(() => router.push('/app/feed'), 1200)
  } catch (e: any) {
    saveError.value = e.response?.data?.detail || '保存失败，请重试'
  } finally { saving.value = false }
}

function skipForNow() { router.push('/app/feed') }

function toggleTag(id: string, v: boolean) {
  if (v) selectedIds.value.push(id)
  else selectedIds.value = selectedIds.value.filter(x => x !== id)
}

function toggleCancerTag(cancerTag: any, selected: boolean) {
  toggleTag(cancerTag.id, selected)
  if (includeChildren.value && cancerTag.children) {
    for (const child of cancerTag.children) {
      if (selected) {
        if (!selectedIds.value.includes(child.id)) selectedIds.value.push(child.id)
      } else {
        selectedIds.value = selectedIds.value.filter((x: string) => x !== child.id)
      }
    }
  }
}

function isCancerSelected(cancerTag: any): boolean {
  return selectedIds.value.includes(cancerTag.id)
}

const expandedTags = ref<Set<string>>(new Set())

function toggleExpand(id: string) {
  const s = expandedTags.value
  if (s.has(id)) s.delete(id)
  else s.add(id)
}

function expandAll() {
  expandedTags.value = new Set(cancerTags.value.map((t: any) => t.id))
}

function collapseAll() {
  expandedTags.value = new Set()
}
</script>

<template>
  <div style="max-width:1400px;margin:0 auto;padding:32px 24px">
    <div style="text-align:center;margin-bottom:32px">
      <h2 style="margin-bottom:8px">🎯 设置你的关注领域</h2>
      <p style="color:var(--text-secondary);font-size:14px">选择感兴趣的癌种、靶点和研究类型，立即匹配已有文献</p>
    </div>

    <div v-if="saveSuccess">
      <NResult status="success" title="保存成功！" :description="`已为你匹配 ${feedsGenerated} 篇相关文献`">
        <template #footer><NButton type="primary" @click="router.push('/app/feed')" class="sky-btn">
          <template #icon><NIcon size="14"><CheckmarkCircleOutline /></NIcon></template>
          去看文献速览 →
        </NButton></template>
      </NResult>
    </div>

    <NSpin v-else :show="loading">
      <div style="display:flex;gap:24px;flex-wrap:wrap">
        <div style="flex:2;min-width:420px">
          <!-- 癌种层级树 -->
          <NCard size="small" title="🏥 癌种部位" style="margin-bottom:16px">
            <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;font-size:12px">
              <span style="color:var(--text-muted)">点击 ▶ 展开查看靶点/治疗方式</span>
              <div style="display:flex;gap:6px">
                <NButton text size="tiny" @click="expandAll">展开全部</NButton>
                <NButton text size="tiny" @click="collapseAll">折叠全部</NButton>
              </div>
            </div>
            <div v-if="cancerTags.length">
              <div v-for="ctag in cancerTags" :key="ctag.id" style="margin:2px 0">
                <div style="display:flex;align-items:center;gap:4px;padding:4px 0;">
                  <span @click="toggleExpand(ctag.id)"
                        style="cursor:pointer;font-size:10px;color:var(--text-muted);width:14px;flex-shrink:0;text-align:center;user-select:none">
                    {{ expandedTags.has(ctag.id) ? '▼' : ctag.children?.length ? '▶' : '·' }}
                  </span>
                  <NCheckbox
                    :checked="isCancerSelected(ctag)"
                    @update:checked="(v:boolean) => toggleCancerTag(ctag, v)"
                  >
                    <span :class="{ 'cancer-tag-selected': isCancerSelected(ctag) }" style="font-weight:500">{{ ctag.name_zh || ctag.name_en }}</span>
                  </NCheckbox>
                  <span style="font-size:11px;color:var(--text-muted);white-space:nowrap">
                    {{ ctag.children?.length || 0 }}项
                    <template v-if="ctag.children?.length">
                      · 已选{{ ctag.children.filter((c:any) => selectedIds.includes(c.id)).length }}
                    </template>
                  </span>
                </div>
                <div v-if="expandedTags.has(ctag.id) && ctag.children?.length"
                     style="padding-left:28px;border-left:2px solid var(--border-color);margin-left:6px;margin-bottom:4px">
                  <div v-for="child in ctag.children" :key="child.id"
                       style="display:flex;align-items:center;padding:3px 0;margin:1px 0">
                    <NCheckbox
                      :checked="selectedIds.includes(child.id)"
                      @update:checked="(v:boolean) => toggleTag(child.id, v)"
                    >
                      <span :style="{ color: selectedIds.includes(child.id) ? '#1a5276' : 'var(--text-secondary)', fontSize: '13px' }">
                        {{ child.name_zh || child.name_en }}
                      </span>
                    </NCheckbox>
                  </div>
                </div>
              </div>
            </div>
            <div v-else style="color:var(--text-muted);font-size:13px;text-align:center;padding:8px">暂无癌种标签</div>
          </NCard>

          <!-- 其他标签类别 -->
          <div v-for="cat in otherCategories" :key="cat.key" style="margin-bottom:16px">
            <NCard size="small" :title="cat.label">
              <div v-for="tag in (tagsByCategory[cat.key] || []).filter(t => t.level===2 && t.is_selectable !== false)"
                   :key="tag.id" style="display:inline-flex;align-items:center;margin:4px 12px 4px 0">
                <NCheckbox :checked="selectedIds.includes(tag.id)"
                           @update:checked="(v:boolean) => toggleTag(tag.id, v)">
                  {{ tag.name_zh || tag.name_en }}
                </NCheckbox>
              </div>
            </NCard>
          </div>
        </div>

        <div style="flex:1;min-width:280px">
          <div style="position:sticky;top:24px">
            <!-- 匹配模式（每行显示预估） -->
            <NCard size="small" style="margin-bottom:16px">
              <div style="margin-bottom:12px;font-size:13px;font-weight:600">匹配模式</div>
              <NRadioGroup v-model:value="matchMode" size="small">
                <div v-for="(desc, key) in MODE_DESC" :key="key"
                     style="display:flex;align-items:flex-start;margin-bottom:10px">
                  <NRadio :value="key" style="flex:1">
                    <div>
                      <strong>{{ desc.title }}</strong>
                      <div style="font-size:12px;color:var(--text-muted);margin-top:2px">{{ desc.desc }}</div>
                    </div>
                  </NRadio>
                </div>
              </NRadioGroup>
            </NCard>

            <!-- 期刊等级筛选 -->
            <NCard size="small" style="margin-bottom:16px">
              <div style="margin-bottom:8px;font-size:13px;color:var(--text-secondary)">期刊等级偏好</div>
              <div style="display:flex;flex-wrap:wrap;gap:6px">
                <NTag v-for="tier in TIER_OPTIONS" :key="tier.key"
                  :color="{ color: tier.color }"
                  :bordered="false"
                  checkable
                  :checked="journalTiers.includes(tier.key)"
                  @click="journalTiers.includes(tier.key) ? journalTiers = journalTiers.filter(x=>x!==tier.key) : journalTiers.push(tier.key)"
                  style="cursor:pointer"
                >
                  {{ tier.label }}
                </NTag>
              </div>
            </NCard>

            <!-- 文献类型 -->
            <NCard size="small" style="margin-bottom:16px">
              <div style="margin-bottom:8px;font-size:13px;color:var(--text-secondary)">文献类型偏好</div>
              <div style="display:flex;flex-wrap:wrap;gap:6px">
                <NTag v-for="lt in LIT_TYPE_OPTIONS" :key="lt.key"
                  checkable
                  :checked="litTypes.includes(lt.key)"
                  @click="litTypes.includes(lt.key) ? litTypes = litTypes.filter(x=>x!==lt.key) : litTypes.push(lt.key)"
                  style="cursor:pointer"
                >
                  {{ lt.label }}
                </NTag>
              </div>
            </NCard>

            <!-- 治疗类型 -->
            <NCard size="small" style="margin-bottom:16px">
              <div style="margin-bottom:8px;font-size:13px;color:var(--text-secondary)">治疗方式偏好</div>
              <div style="display:flex;flex-wrap:wrap;gap:6px">
                <NTag v-for="th in THERAPY_OPTIONS" :key="th.key"
                  checkable
                  :checked="therapyTypes.includes(th.key)"
                  @click="therapyTypes.includes(th.key) ? therapyTypes = therapyTypes.filter(x=>x!==th.key) : therapyTypes.push(th.key)"
                  style="cursor:pointer"
                >
                  {{ th.label }}
                </NTag>
              </div>
            </NCard>

            <!-- 层级展开开关 -->
            <NCard size="small" style="margin-bottom:16px;font-size:13px">
              <div style="display:flex;justify-content:space-between;align-items:center">
                <span>自动展开子标签</span>
                <NSwitch v-model:value="includeChildren" size="small" />
              </div>
              <div style="color:var(--text-muted);font-size:12px;margin-top:6px">勾选癌种时自动订阅其下靶点/治疗方式</div>
            </NCard>

            <!-- 预估推送量（API 数据） -->
            <NCard size="small" style="margin-bottom:16px">
              <div style="border-bottom:1px solid var(--border-color);padding-bottom:12px;margin-bottom:8px">
                <template v-if="estimateLoading && !estimate">
                  <NSkeleton text :repeat="3" size="small" />
                </template>
                <template v-else-if="!selectedIds.length">
                  <div style="font-size:13px;color:var(--text-muted);text-align:center;padding:8px 0">请先选择关注标签</div>
                </template>
                <template v-else-if="estimate">
                  <div style="display:flex;justify-content:space-between;margin-bottom:8px">
                    <span style="font-size:13px;color:var(--text-secondary)">预计每日推送</span>
                    <strong>{{ estimate.daily_estimate }} 篇</strong>
                  </div>
                  <div style="display:flex;justify-content:space-between;margin-bottom:4px">
                    <span style="font-size:13px;color:var(--text-secondary)">🔴 必读</span>
                    <strong>{{ estimate.by_priority.must_read || 0 }} 篇</strong>
                  </div>
                  <div style="display:flex;justify-content:space-between;margin-bottom:4px">
                    <span style="font-size:13px;color:var(--text-secondary)">🟡 推荐</span>
                    <strong>{{ estimate.by_priority.recommended || 0 }} 篇</strong>
                  </div>
                  <div style="display:flex;justify-content:space-between">
                    <span style="font-size:12px;color:var(--text-muted)">文献库覆盖</span>
                    <span style="font-size:12px;color:var(--text-secondary)">{{ estimate.total_articles > 1000 ? (estimate.total_articles / 1000).toFixed(1) + 'k' : estimate.total_articles }} 篇</span>
                  </div>
                </template>
                <div v-else-if="estimateLoading" style="font-size:12px;color:var(--text-muted);text-align:center">计算中…</div>
              </div>
              <div v-if="saveError" style="color:#d03050;font-size:13px;margin-bottom:12px;text-align:center">{{ saveError }}</div>
              <NButton type="primary" block :loading="saving" @click="saveAndGo" :disabled="selectedIds.length === 0" class="sky-btn"><template #icon><NIcon size="14"><SaveOutline /></NIcon></template>
                {{ selectedIds.length ? `保存并开始 (已选${selectedIds.length}项)` : '请先选择关注标签' }}
              </NButton>
              <NButton text block size="small" style="margin-top:8px" @click="skipForNow">先跳过，以后再说</NButton>
            </NCard>
          </div>
        </div>
      </div>
    </NSpin>
  </div>
</template>

<style scoped>
.cancer-tag-selected { color: #1a5276; }
</style>
