<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { NCard, NGrid, NGi, NButton, NSpin, NEmpty, NProgress, NTag, NSkeleton } from 'naive-ui'
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 { useToast } from '../../composables/useToast'
import { useAuthStore } from '../../stores/auth'

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

const router = useRouter()
const toast = useToast()
const auth = useAuthStore()
const loading = ref(true)
const generating = ref(false)
const calLoading = ref(false)
const trendLoading = ref(false)
const activityLoading = ref(false)

// ── Data ──
interface ProfileData {
  stats: {
    saved: number; rated: number; notes: number; subscriptions: number
    total_feed: number; read: number; active_days_7d: number; read_rate: number
  }
  top_journals: Array<{ journal: string; count: number }>
  top_tags: Array<{ name: string; count: number }>
  reading_status_dist: Record<string, number>
}
const profile = ref<ProfileData | null>(null)

const calendarData = ref<Array<{ date: string; count: number }>>([])
const trendData = ref<Array<{ date: string; count: number }>>([])
const recentActivity = ref<Array<{ pmid: number; title: string; journal: string; pub_date: string | null; read_at: string | null; priority: string }>>([])

// ── Computed ──
const maxTagCount = computed(() => {
  if (!profile.value?.top_tags.length) return 1
  return Math.max(...profile.value.top_tags.map(t => t.count), 1)
})
const tagColors = ['#1a5276', '#2e86c1', '#3498db', '#5dade2', '#85c1e9', '#aed6f1', '#d4e6f1', '#f0b27a', '#e59866', '#dc7633', '#d35400', '#a04000', '#6c3483', '#7d3c98', '#8e44ad']

// 阅读状态分布
const readingDistTotal = computed(() => {
  const d = profile.value?.reading_status_dist || {}
  return (d.unread || 0) + (d.reading || 0) + (d.completed || 0) || 1
})
const readingDistPct = (key: string) => {
  const d = profile.value?.reading_status_dist || {}
  return Math.round(((d[key] || 0) / readingDistTotal.value) * 100)
}

// 热力图 - 构建 53×7 grid
const heatmapWeeks = computed(() => {
  const map = new Map<string, number>()
  for (const d of calendarData.value) map.set(d.date, d.count)
  const max = Math.max(1, ...calendarData.value.map(d => d.count), 1)

  const weeks: Array<Array<{ date: string; count: number; level: number }>> = []
  // 从 365 天前开始，到昨天
  const start = new Date()
  start.setDate(start.getDate() - 364)
  // 对齐到周日
  start.setDate(start.getDate() - start.getDay())

  const end = new Date()
  end.setDate(end.getDate() - 1)

  const cur = new Date(start)
  while (cur <= end) {
    const week: Array<{ date: string; count: number; level: number }> = []
    for (let d = 0; d < 7; d++) {
      const dateStr = cur.toISOString().slice(0, 10)
      const cnt = map.get(dateStr) || 0
      let level = 0
      if (cnt > 0) level = max > 1 ? Math.min(4, Math.ceil((cnt / max) * 4)) : 1
      week.push({ date: dateStr, count: cnt, level })
      cur.setDate(cur.getDate() + 1)
    }
    weeks.push(week)
  }
  return weeks
})

// 趋势图
const trendChart = computed(() => ({
  labels: trendData.value.map(d => d.date.slice(5)),
  datasets: [
    {
      label: '阅读量',
      data: trendData.value.map(d => d.count),
      backgroundColor: 'rgba(26, 82, 118, 0.5)',
      borderColor: '#1a5276',
      borderWidth: 1,
      borderRadius: 2,
    },
  ],
}))

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

// 期刊 Chart.js 数据（复用 StatsView 的柱状图）
const journalChart = computed(() => ({
  labels: (profile.value?.top_journals || []).map(j => (j.journal || '').slice(0, 25)),
  datasets: [{
    label: '收藏篇数',
    data: (profile.value?.top_journals || []).map(j => j.count),
    backgroundColor: ['#2080f0', '#18a058', '#d03050', '#f0a020', '#7c4dff'],
    borderRadius: 4,
  }],
}))

const journalChartOptions = {
  responsive: true,
  maintainAspectRatio: false,
  indexAxis: 'y' as const,
  plugins: { legend: { display: false } },
  scales: {
    x: { beginAtZero: true, ticks: { stepSize: 1, font: { size: 10 } } },
    y: { ticks: { font: { size: 10 } }, grid: { display: false } },
  },
}

// ── Fetch ──
async function fetchProfile() {
  loading.value = true
  try {
    const { data } = await api.get('/settings/profile')
    profile.value = data
  } catch (e) { toast.apiError(e, '加载学术画像失败') }
  finally { loading.value = false }
}

async function fetchCalendar() {
  calLoading.value = true
  try {
    const { data } = await api.get('/settings/profile/calendar')
    calendarData.value = data.days || []
  } catch { /* silent */ }
  finally { calLoading.value = false }
}

async function fetchTrend() {
  trendLoading.value = true
  try {
    const { data } = await api.get('/settings/profile/reading-trend')
    trendData.value = data.trend || []
  } catch { /* silent */ }
  finally { trendLoading.value = false }
}

async function fetchRecentActivity() {
  activityLoading.value = true
  try {
    const { data } = await api.get('/settings/profile/recent-activity')
    recentActivity.value = data.items || []
  } catch { /* silent */ }
  finally { activityLoading.value = false }
}

async function generateWeeklyReport() {
  generating.value = true
  try {
    const response = await api.get('/settings/profile/weekly-report', { responseType: 'blob' })
    const blob = new Blob([response.data], { type: 'text/markdown' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url; a.download = `阅读周报_${new Date().toISOString().slice(0, 10)}.md`
    a.click(); URL.revokeObjectURL(url)
    toast.success('周报已下载')
  } catch (e) { toast.apiError(e, '生成周报失败') }
  finally { generating.value = false }
}

const HEATMAP_COLORS = ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39']

function heatmapColor(level: number): string {
  return (HEATMAP_COLORS[level] || HEATMAP_COLORS[0]) as string
}

onMounted(async () => {
  await Promise.all([fetchProfile(), fetchCalendar(), fetchTrend(), fetchRecentActivity()])
})
</script>

<template>
  <div class="profile-page">
    <NSpin :show="loading">
      <NEmpty v-if="!loading && !profile" description="加载失败" />

      <template v-if="profile">
        <!-- ════ Phase 1: 个人身份卡片 ════ -->
        <NCard size="small" style="margin-bottom:16px">
          <div class="identity-row">
            <div class="avatar-placeholder">
              {{ (auth.user?.display_name || 'U')[0] }}
            </div>
            <div class="identity-info">
              <div class="identity-name">{{ auth.user?.display_name || '用户' }}</div>
              <div class="identity-meta">
                <span v-if="auth.user?.title">{{ auth.user.title }}</span>
                <span v-if="(auth.currentTenant as any)?.hospital_name">{{ (auth.currentTenant as any)?.hospital_name }}</span>
                <span v-if="(auth.currentTenant as any)?.department_name">{{ (auth.currentTenant as any)?.department_name }}</span>
              </div>
              <div class="identity-email">{{ auth.user?.email }}</div>
            </div>
            <div style="margin-left:auto;display:flex;gap:8px;align-items:flex-start">
              <NButton size="tiny" @click="router.push('/app/settings')" class="sky-btn">编辑资料</NButton>
              <NButton size="tiny" :loading="generating" @click="generateWeeklyReport" class="sky-btn">📥 周报</NButton>
            </div>
          </div>
        </NCard>

        <!-- ════ Stats 卡片 ════ -->
        <NGrid :cols="4" :x-gap="12" :y-gap="12" style="margin-bottom:24px">
          <NGi><NCard size="small" title="📁 收藏文献"><div class="stat-value">{{ profile.stats.saved }}</div></NCard></NGi>
          <NGi><NCard size="small" title="⭐ 已评分"><div class="stat-value">{{ profile.stats.rated }}</div></NCard></NGi>
          <NGi><NCard size="small" title="📝 阅读笔记"><div class="stat-value">{{ profile.stats.notes }}</div></NCard></NGi>
          <NGi><NCard size="small" title="🔔 订阅标签"><div class="stat-value">{{ profile.stats.subscriptions }}</div></NCard></NGi>
          <NGi><NCard size="small" title="📚 推送总量"><div class="stat-value">{{ profile.stats.total_feed }}</div></NCard></NGi>
          <NGi><NCard size="small" title="👁️ 已读"><div class="stat-value">{{ profile.stats.read }}</div></NCard></NGi>
          <NGi><NCard size="small" title="📅 七日活跃"><div class="stat-value">{{ profile.stats.active_days_7d }} 天</div></NCard></NGi>
          <NGi>
            <NCard size="small" title="📈 阅读率">
              <div class="stat-value">{{ profile.stats.read_rate }}%</div>
              <NProgress type="line" :percentage="profile.stats.read_rate" :height="6" :border-radius="3"
                :color="profile.stats.read_rate > 60 ? '#18a058' : profile.stats.read_rate > 30 ? '#f0a020' : '#d03050'" />
            </NCard>
          </NGi>
        </NGrid>

        <!-- ════ 阅读状态分布 + 热力图 + 趋势 ════ -->
        <div class="profile-columns">
          <!-- 左：阅读状态分布 + 阅读进度 -->
          <div>
            <NCard title="📖 阅读进度" size="small" style="margin-bottom:16px">
              <div v-if="!profile.reading_status_dist" style="text-align:center;padding:12px;color:var(--text-muted);font-size:13px">
                收藏文献后可查看阅读进度
              </div>
              <div v-else class="reading-dist">
                <div class="dist-row">
                  <span class="dist-dot" style="background:#999"></span>
                  <span class="dist-label">未读</span>
                  <span class="dist-bar-bg">
                    <span class="dist-bar-fill" style="background:#999" :style="{ width: readingDistPct('unread') + '%' }"></span>
                  </span>
                  <span class="dist-num">{{ profile.reading_status_dist.unread || 0 }}</span>
                  <span class="dist-pct">{{ readingDistPct('unread') }}%</span>
                </div>
                <div class="dist-row">
                  <span class="dist-dot" style="background:#f0a020"></span>
                  <span class="dist-label">在读</span>
                  <span class="dist-bar-bg">
                    <span class="dist-bar-fill" style="background:#f0a020" :style="{ width: readingDistPct('reading') + '%' }"></span>
                  </span>
                  <span class="dist-num">{{ profile.reading_status_dist.reading || 0 }}</span>
                  <span class="dist-pct">{{ readingDistPct('reading') }}%</span>
                </div>
                <div class="dist-row">
                  <span class="dist-dot" style="background:#18a058"></span>
                  <span class="dist-label">已读</span>
                  <span class="dist-bar-bg">
                    <span class="dist-bar-fill" style="background:#18a058" :style="{ width: readingDistPct('completed') + '%' }"></span>
                  </span>
                  <span class="dist-num">{{ profile.reading_status_dist.completed || 0 }}</span>
                  <span class="dist-pct">{{ readingDistPct('completed') }}%</span>
                </div>
              </div>
            </NCard>

            <!-- 快速入口（从 StatsView 吸收） -->
            <NCard title="🎯 快速入口" size="small" style="margin-bottom:16px">
              <div style="display:flex;flex-direction:column;gap:8px">
                <NButton size="small" @click="router.push('/app/settings/interests')" class="sky-btn">设置关注领域</NButton>
                <NButton size="small" @click="router.push('/app/feed')" class="sky-btn">去看文献速览</NButton>
                <NButton size="small" @click="router.push('/app/library')" class="sky-btn">打开收藏夹</NButton>
              </div>
            </NCard>

            <!-- 期刊 Top 5 (Chart.js 柱状图) -->
            <NCard title="📰 最常阅读期刊 Top 5" size="small" style="margin-bottom:16px">
              <div v-if="!profile.top_journals.length" class="empty-hint">暂无数据</div>
              <div v-else style="height:200px">
                <Bar :data="journalChart" :options="journalChartOptions" />
              </div>
            </NCard>

            <!-- 标签云 -->
            <NCard title="🏷️ 标签云" size="small" style="margin-bottom:16px">
              <div v-if="!profile.top_tags.length" class="empty-hint">阅读更多文献后生成标签云</div>
              <div v-else class="tag-cloud">
                <NTag v-for="(t, i) in profile.top_tags" :key="i"
                  :color="{ color: tagColors[i % tagColors.length] + '22', textColor: tagColors[i % tagColors.length], borderColor: tagColors[i % tagColors.length] + '44' }"
                  :style="{ fontSize: (12 + t.count / maxTagCount * 8) + 'px' }">
                  {{ t.name }}
                  <span style="opacity:0.6;margin-left:4px">{{ t.count }}</span>
                </NTag>
              </div>
            </NCard>
          </div>

          <!-- 右：热力图 + 趋势 + 时间线 -->
          <div>
            <!-- 阅读热力图 -->
            <NCard title="🔥 阅读热力图" size="small" style="margin-bottom:16px">
              <NSkeleton v-if="calLoading" text :repeat="3" />
              <div v-else-if="!calendarData.length" class="empty-hint">还没有阅读记录</div>
              <template v-else>
                <div class="hm-wrapper">
                  <div class="hm-months">
                    <span v-for="m in ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']" :key="m" class="hm-month-label">{{ m }}</span>
                  </div>
                  <div class="hm-grid">
                    <div v-for="(week, wi) in heatmapWeeks" :key="wi" class="hm-week">
                      <div v-for="(day, di) in week" :key="di" class="hm-day"
                        :style="{ background: heatmapColor(day.level) }"
                        :title="day.date + ': ' + day.count + ' 篇阅读'">
                      </div>
                    </div>
                  </div>
                  <div class="hm-legend">
                    <span style="font-size:10px;color:var(--text-muted)">少</span>
                    <span v-for="i in 5" :key="i" class="hm-legend-dot" :style="{ background: heatmapColor(i - 1) }"></span>
                    <span style="font-size:10px;color:var(--text-muted)">多</span>
                  </div>
                </div>
              </template>
            </NCard>

            <!-- 阅读趋势 -->
            <NCard title="📈 阅读趋势（近30天）" size="small" style="margin-bottom:16px">
              <NSkeleton v-if="trendLoading" text :repeat="3" />
              <div v-else-if="!trendData.length" class="empty-hint">暂无数据</div>
              <div v-else style="height:180px">
                <Bar :data="trendChart" :options="trendChartOptions" />
              </div>
            </NCard>

            <!-- 最近阅读活动 -->
            <NCard title="🕐 最近阅读" size="small">
              <NSkeleton v-if="activityLoading" text :repeat="5" />
              <div v-else-if="!recentActivity.length" class="empty-hint">还没有阅读记录，去 Feed 看看吧</div>
              <div v-else class="activity-list">
                <div v-for="(a, i) in recentActivity" :key="i" class="activity-item" @click="router.push('/app/literature/' + a.pmid)">
                  <div class="activity-title">{{ a.title }}</div>
                  <div class="activity-meta">
                    <span>{{ a.journal }}</span>
                    <span v-if="a.read_at">· {{ a.read_at.slice(0, 10) }}</span>
                    <NTag v-if="a.priority === 'must_read'" size="tiny" :color="{ color: '#d03050' }" style="margin-left:4px">必读</NTag>
                    <NTag v-else-if="a.priority === 'recommended'" size="tiny" :color="{ color: '#f0a020' }" style="margin-left:4px">推荐</NTag>
                  </div>
                </div>
              </div>
            </NCard>
          </div>
        </div>
      </template>
    </NSpin>
  </div>
</template>

<style scoped>
.profile-page { max-width: 1400px; margin: 0 auto; padding: 24px; }
.stat-value { font-size: 28px; font-weight: 700; color: #1a5276; line-height: 1.2; margin-bottom: 4px; }

.profile-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

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

/* 身份卡片 */
.identity-row { display: flex; align-items: center; gap: 16px; }
.avatar-placeholder { width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, #1a5276, #3498db); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 700; flex-shrink: 0; }
.identity-info { flex: 1; }
.identity-name { font-size: 20px; font-weight: 700; }
.identity-meta { font-size: 13px; color: var(--text-secondary); margin-top: 2px; display: flex; gap: 8px; flex-wrap: wrap; }
.identity-email { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* 阅读状态分布 */
.reading-dist { display: flex; flex-direction: column; gap: 8px; }
.dist-row { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.dist-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.dist-label { width: 32px; flex-shrink: 0; color: var(--text-secondary); font-size: 12px; }
.dist-bar-bg { flex: 1; height: 8px; background: var(--border-color); border-radius: 4px; overflow: hidden; }
.dist-bar-fill { display: block; height: 100%; border-radius: 4px; transition: width 0.5s ease; }
.dist-num { width: 28px; text-align: right; font-weight: 600; font-size: 13px; }
.dist-pct { width: 40px; text-align: right; color: var(--text-muted); font-size: 11px; }

/* 热力图 */
.hm-wrapper { font-size: 0; }
.hm-months { display: flex; margin-bottom: 4px; margin-left: 32px; }
.hm-month-label { font-size: 9px; color: var(--text-muted); flex: 1; text-align: left; }
.hm-grid { display: flex; gap: 2px; }
.hm-week { display: flex; flex-direction: column; gap: 2px; }
.hm-day { width: 12px; height: 12px; border-radius: 2px; cursor: pointer; }
.hm-day:hover { outline: 2px solid var(--text-primary); }
.hm-legend { display: flex; align-items: center; gap: 3px; margin-top: 6px; justify-content: flex-end; }
.hm-legend-dot { width: 10px; height: 10px; border-radius: 2px; }

/* 标签云 */
.tag-cloud { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* 时间线 */
.activity-list { display: flex; flex-direction: column; gap: 0; }
.activity-item { padding: 10px 0; border-bottom: 1px solid var(--border-color); cursor: pointer; transition: background .15s; }
.activity-item:last-child { border-bottom: none; }
.activity-item:hover { background: var(--bg-hover); margin: 0 -12px; padding: 10px 12px; border-radius: 6px; }
.activity-title { font-size: 13px; font-weight: 500; line-height: 1.4; }
.activity-meta { font-size: 11px; color: var(--text-muted); margin-top: 4px; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

@media (max-width: 768px) {
  .profile-columns { grid-template-columns: 1fr; }
}
</style>
