<script setup lang="ts">
/**
 * 数据分析：日期预设 + 真实 stats API + canvas 图表 + 地区 TOP 列表。
 */
import { computed, ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AppNavbar from '@/components/layout/AppNavbar.vue'
import AppFloatingTabbar from '@/components/layout/AppFloatingTabbar.vue'
import AppPageShell from '@/components/layout/AppPageShell.vue'
import AdminLineChart from '../../components/AdminLineChart.vue'
import AdminBarChart from '../../components/AdminBarChart.vue'
import { useAdminGuard } from '../../composables/useAdminGuard'
import { getDashboardStats, trendPointValue, type DashboardStats, type TrendPoint } from '@/api'

const { guardAdmin } = useAdminGuard()
const loading = ref(false)
const stats = ref<DashboardStats>({})
const preset = ref<'today' | '7d' | '30d'>('7d')

function formatDate(d: Date) {
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${day}`
}

function rangeOf(p: typeof preset.value) {
  const end = new Date()
  const start = new Date()
  if (p === 'today') { /* same day */ }
  else if (p === '7d') start.setDate(end.getDate() - 6)
  else start.setDate(end.getDate() - 29)
  return { startDate: formatDate(start), endDate: formatDate(end) }
}

const kpi = computed(() => [
  { label: '文章', value: stats.value.posts ?? 0 },
  { label: '作品', value: stats.value.works ?? 0 },
  { label: '咨询', value: stats.value.inquiryCount ?? 0 },
  {
    label: '区间 UV',
    value: (stats.value.uvTrend || []).reduce((s, i) => s + trendPointValue(i), 0),
  },
])

const cats = computed(() => {
  const set = new Set<string>()
  ;(stats.value.postsTrend || []).forEach(p => set.add(p.date))
  ;(stats.value.uvTrend || []).forEach(p => set.add(p.date))
  return Array.from(set).sort()
})

function mapByDate(list: TrendPoint[] | undefined, categories: string[]) {
  const map = new Map((list || []).map(i => [i.date, trendPointValue(i)]))
  return categories.map(d => map.get(d) ?? 0)
}

const lineSeries = computed(() => [
  { name: '发文', data: mapByDate(stats.value.postsTrend, cats.value) },
  { name: 'UV', data: mapByDate(stats.value.uvTrend, cats.value) },
])

const barCategories = computed(() =>
  (stats.value.topPosts || []).slice(0, 6).map(p => String(p.title || '').slice(0, 6) || '—'),
)
const barValues = computed(() =>
  (stats.value.topPosts || []).slice(0, 6).map(p => Number(p.count ?? p.readCount ?? 0)),
)

const regions = computed(() => {
  const list = stats.value.userRegions || []
  return [...list]
    .map(r => ({
      name: String(r.region || r.name || '未知'),
      value: Number(r.count ?? r.value ?? 0),
    }))
    .sort((a, b) => b.value - a.value)
    .slice(0, 8)
})

async function load() {
  if (!guardAdmin()) return
  loading.value = true
  try {
    stats.value = await getDashboardStats(rangeOf(preset.value))
  }
  catch {
    stats.value = {}
  }
  finally {
    loading.value = false
  }
}

function setPreset(p: typeof preset.value) {
  preset.value = p
  load()
}

onShow(load)
</script>

<template>
  <AppPageShell admin with-tab-pad>
    <AppNavbar title="数据分析" />
    <view class="page-pad">
      <view class="presets">
        <view class="chip" :class="{ on: preset === 'today' }" @click="setPreset('today')">今日</view>
        <view class="chip" :class="{ on: preset === '7d' }" @click="setPreset('7d')">近7天</view>
        <view class="chip" :class="{ on: preset === '30d' }" @click="setPreset('30d')">近30天</view>
      </view>
      <view class="grid">
        <view v-for="item in kpi" :key="item.label" class="admin-card card">
          <text class="font-mono-label text-art-muted">{{ item.label }}</text>
          <text class="value">{{ item.value }}</text>
        </view>
      </view>
      <view class="admin-card chart-card">
        <text class="chart-title">发文 / UV 趋势</text>
        <AdminLineChart v-if="cats.length" :categories="cats" :series="lineSeries" />
        <wd-empty v-else description="暂无趋势" />
      </view>
      <view class="admin-card chart-card">
        <text class="chart-title">热门文章</text>
        <AdminBarChart v-if="barCategories.length" :categories="barCategories" :values="barValues" />
        <wd-empty v-else description="暂无热门" />
      </view>
      <view class="admin-card chart-card">
        <text class="chart-title">访问地区 TOP</text>
        <view v-for="(r, i) in regions" :key="i" class="region">
          <text class="r-name">{{ i + 1 }}. {{ r.name }}</text>
          <text class="r-val text-art-accent">{{ r.value }}</text>
        </view>
        <wd-empty v-if="!regions.length" description="暂无地区数据" />
      </view>
      <wd-loading v-if="loading" />
    </view>
    <AppFloatingTabbar />
  </AppPageShell>
</template>

<style scoped lang="scss">
.page-pad { padding: 24rpx 32rpx 48rpx; }
.presets { display: flex; gap: 12rpx; margin-bottom: 20rpx; }
.chip {
  padding: 10rpx 22rpx; border-radius: 8rpx; font-size: 24rpx;
  background: rgba(255, 255, 255, 0.06); color: rgba(255, 255, 255, 0.65);
}
.chip.on { background: rgba(212, 179, 131, 0.25); color: rgb(var(--art-accent)); }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16rpx; margin-bottom: 20rpx; }
.card { padding: 24rpx; display: flex; flex-direction: column; gap: 8rpx; }
.value { font-size: 40rpx; color: rgb(var(--art-accent)); font-family: monospace; }
.chart-card { padding: 24rpx; margin-bottom: 20rpx; }
.chart-title { display: block; font-size: 28rpx; margin-bottom: 16rpx; color: rgb(var(--art-text)); }
.region {
  display: flex; justify-content: space-between; padding: 14rpx 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.r-name { color: rgb(var(--art-text)); font-size: 26rpx; }
.r-val { font-family: monospace; }
</style>
