<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { NCard, NButton, NTag, NSpin, NEmpty, NSkeleton, NPagination, NGi, NGrid } from 'naive-ui'
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Tooltip, Legend } from 'chart.js'
import { api } from '../../api/client'
import { useToast } from '../../composables/useToast'

ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend)

const route = useRoute()
const router = useRouter()
const toast = useToast()
const issn = computed(() => route.params.issn as string)

const loading = ref(true)
const journal = ref<any>(null)
const articles = ref<any[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = 20
const articleLoading = ref(false)
const yearFilter = ref<number | null>(null)
const availableYears = ref<number[]>([])
const savedPmids = ref<Set<number>>(new Set())

const tierColors: Record<string, string> = {
  '1': '#d03050', '2': '#f0a020', '3': '#18a058', '4': '#999',
}
const tierLabels: Record<string, string> = {
  '1': '四大综合', '2': '肿瘤顶刊', '3': '专科顶刊', '4': '其他',
}

const trendChart = computed(() => {
  if (!journal.value?.yearly_trend?.length) return null
  const data = [...journal.value.yearly_trend].reverse()
  return {
    labels: data.map((d: any) => d.year),
    datasets: [{
      label: '年发文量',
      data: data.map((d: any) => d.count),
      backgroundColor: '#1a5276',
      borderRadius: 2,
    }],
  }
})

const trendOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: { legend: { display: false } },
  scales: {
    x: { ticks: { font: { size: 10 } }, grid: { display: false } },
    y: { beginAtZero: true, ticks: { stepSize: 1, font: { size: 10 } }, grid: { color: 'rgba(0,0,0,0.05)' } },
  },
}

async function fetchJournal() {
  loading.value = true
  try {
    const { data } = await api.get(`/journals/${issn.value}`)
    journal.value = data
  } catch (e: any) { toast.apiError(e, '加载期刊失败') }
  finally { loading.value = false }
}

async function fetchArticles(p: number = 1) {
  articleLoading.value = true
  try {
    const params: Record<string, any> = { page: p, page_size: pageSize }
    if (yearFilter.value) params.year = yearFilter.value
    const { data } = await api.get(`/journals/${issn.value}/articles`, { params })
    articles.value = data.items || []
    total.value = data.total || 0
    page.value = data.page || 1
    availableYears.value = data.available_years || []
    savedPmids.value = new Set(data.is_saved || [])
  } catch (e: any) { toast.apiError(e, '加载文章失败') }
  finally { articleLoading.value = false }
}

async function toggleFollow() {
  if (!journal.value) return
  try {
    if (journal.value.is_following) {
      await api.delete(`/journals/${issn.value}/follow`)
      journal.value.is_following = false
      toast.success('已取消关注')
    } else {
      await api.post(`/journals/${issn.value}/follow`)
      journal.value.is_following = true
      toast.success('已关注，新文献将推送到 Feed')
    }
  } catch (e: any) { toast.apiError(e, '操作失败') }
}

function goArticle(pmid: number) {
  router.push(`/app/literature/${pmid}`)
}

function handleYearChange(y: number | null) {
  yearFilter.value = y
  fetchArticles(1)
}

onMounted(async () => {
  await Promise.all([fetchJournal(), fetchArticles()])
})
</script>

<template>
  <div class="journal-detail">
    <NSpin :show="loading">
      <NEmpty v-if="!loading && !journal" description="期刊未找到" />
      <template v-if="journal">
        <!-- 期刊头部 -->
        <NCard size="small" style="margin-bottom:16px">
          <div class="journal-header">
            <div class="header-main">
              <div class="journal-name-row">
                <h1 class="journal-name">{{ journal.name }}</h1>
                <NTag size="small" :color="{ color: tierColors[journal.tier] || '#999' }" style="margin-left:8px">
                  Tier {{ journal.tier }} · {{ tierLabels[journal.tier] || '' }}
                </NTag>
              </div>
              <div class="journal-meta">
                <span v-if="journal.issn">ISSN: {{ journal.issn }}</span>
                <span v-if="journal.eissn">EISSN: {{ journal.eissn }}</span>
                <span v-if="journal.publisher">{{ journal.publisher }}</span>
                <span v-if="journal.impact_factor">IF: {{ journal.impact_factor }}</span>
              </div>
            </div>
            <div class="header-actions">
              <NButton size="small" :type="journal.is_following ? 'default' : 'primary'"
                @click="toggleFollow" :class="{ 'sky-btn': !journal.is_following }">
                {{ journal.is_following ? '✅ 已关注' : '➕ 关注期刊' }}
              </NButton>
            </div>
          </div>

          <!-- 统计卡片 -->
          <NGrid :cols="3" :x-gap="12" style="margin-top:16px">
            <NGi>
              <div class="stat-item">
                <div class="stat-value">{{ journal.article_count }}</div>
                <div class="stat-label">收录文献</div>
              </div>
            </NGi>
            <NGi>
              <div class="stat-item">
                <div class="stat-value">{{ journal.my_saved }}</div>
                <div class="stat-label">我的收藏</div>
              </div>
            </NGi>
            <NGi>
              <div class="stat-item">
                <div class="stat-value">{{ journal.my_read }}</div>
                <div class="stat-label">我已阅读</div>
              </div>
            </NGi>
          </NGrid>
        </NCard>

        <!-- 年发文趋势 -->
        <NCard title="📈 年发文趋势" size="small" style="margin-bottom:16px">
          <div v-if="!trendChart" class="empty-hint">暂无数据</div>
          <div v-else style="height:200px">
            <Bar :data="trendChart" :options="trendOptions" />
          </div>
        </NCard>

        <!-- 文章列表 -->
        <NCard size="small">
          <div class="articles-header">
            <h3 style="margin:0">📄 文献列表</h3>
            <div class="year-filters">
              <span class="year-tag" :class="{ active: yearFilter === null }"
                @click="handleYearChange(null)">全部</span>
              <span v-for="y in availableYears.slice(0, 10)" :key="y"
                class="year-tag" :class="{ active: yearFilter === y }"
                @click="handleYearChange(y)">{{ y }}</span>
            </div>
          </div>

          <NSkeleton v-if="articleLoading" text :repeat="5" />
          <NEmpty v-else-if="!articles.length" description="暂无文献" style="padding:24px 0" />
          <div v-else>
            <div v-for="a in articles" :key="a.id" class="article-item" @click="goArticle(a.pmid)">
              <div class="article-title">{{ a.title }}</div>
              <div class="article-meta">
                <span>{{ a.first_author }} et al.</span>
                <span v-if="a.pub_date">· {{ a.pub_date?.slice(0, 10) }}</span>
                <span v-if="a.journal">· {{ a.journal }}</span>
                <span v-if="a.cited_by_count">· 被引 {{ a.cited_by_count }}</span>
                <NTag v-for="t in (a.tags || []).slice(0, 3)" :key="t.id" size="tiny" style="margin-left:4px">
                  {{ t.name_zh }}
                </NTag>
                <NTag v-if="savedPmids.has(a.pmid)" size="tiny" :color="{color: '#18a058'}" style="margin-left:4px">已收藏</NTag>
              </div>
            </div>
            <div v-if="total > pageSize" style="display:flex;justify-content:center;margin-top:16px">
              <NPagination :page="page" :page-size="pageSize" :item-count="total" @update:page="fetchArticles" />
            </div>
          </div>
        </NCard>
      </template>
    </NSpin>
  </div>
</template>

<style scoped>
.journal-detail { max-width: 1200px; margin: 0 auto; padding: 24px; }
.journal-header { display: flex; justify-content: space-between; align-items: flex-start; }
.header-main { flex: 1; }
.journal-name-row { display: flex; align-items: center; }
.journal-name { margin: 0; font-size: 22px; }
.journal-meta { display: flex; gap: 12px; margin-top: 6px; font-size: 12px; color: var(--text-secondary); flex-wrap: wrap; }
.header-actions { margin-left: 16px; flex-shrink: 0; }

.stat-item { text-align: center; padding: 12px 0; }
.stat-value { font-size: 28px; font-weight: 700; color: #1a5276; line-height: 1.2; }
.stat-label { font-size: 12px; color: var(--text-muted); margin-top: 4px; }

.empty-hint { color: var(--text-muted); font-size: 13px; padding: 30px 0; text-align: center; }

.articles-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; flex-wrap: wrap; gap: 8px; }
.year-filters { display: flex; gap: 4px; font-size: 12px; flex-wrap: wrap; }
.year-tag { cursor: pointer; padding: 2px 10px; border-radius: 10px; transition: all .15s; background: var(--bg-hover); color: var(--text-secondary); }
.year-tag.active { background: #1a5276; color: #fff; }

.article-item { padding: 10px 0; border-bottom: 1px solid var(--border-color); cursor: pointer; }
.article-item:last-child { border-bottom: none; }
.article-item:hover { background: var(--bg-hover); margin: 0 -12px; padding: 10px 12px; border-radius: 6px; }
.article-title { font-size: 14px; font-weight: 500; line-height: 1.4; }
.article-meta { font-size: 11px; color: var(--text-muted); margin-top: 4px; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
</style>
