<template>
  <div class="analytics-overview">
    <a-card class="title-card">
      <template #title>运营概览</template>
      <template #extra>
        <a-space>
          <a-select v-model:value="timeRange" style="width: 120px" @change="fetchData">
            <a-select-option value="all">全部时间</a-select-option>
            <a-select-option value="month">本月</a-select-option>
            <a-select-option value="quarter">本季度</a-select-option>
            <a-select-option value="year">本年</a-select-option>
          </a-select>
          <a-select v-model:value="contestFilter" style="width: 200px" placeholder="全部活动" allow-clear
            @change="fetchData">
            <a-select-option v-for="c in contestOptions" :key="c.id" :value="c.id">{{ c.name }}</a-select-option>
          </a-select>
        </a-space>
      </template>
    </a-card>

    <a-spin :spinning="loading">
      <!-- 核心指标卡片 -->
      <div class="stats-row">
        <div v-for="item in statsItems" :key="item.key" class="stat-card">
          <div class="stat-icon" :style="{ background: item.bgColor }">
            <component :is="item.icon" :style="{ color: item.color }" />
          </div>
          <div class="stat-info">
            <span class="stat-count">{{ item.value }}</span>
            <span class="stat-label">{{ item.label }}</span>
          </div>
        </div>
      </div>

      <!-- 漏斗 + 趋势 -->
      <div class="grid-2">
        <!-- 报名转化漏斗 -->
        <div class="card-section">
          <h3 class="section-title">报名转化漏斗</h3>
          <div class="funnel-list">
            <div v-for="(item, idx) in funnelItems" :key="item.label" class="funnel-item">
              <div class="funnel-header">
                <span class="funnel-label">{{ item.label }}</span>
                <div class="funnel-values">
                  <span v-if="idx > 0" class="funnel-rate"
                    :style="{ background: item.rateBg, color: item.rateColor }">{{
                    item.rate }}</span>
                  <span class="funnel-count">{{ item.value }}</span>
                </div>
              </div>
              <div class="funnel-bar-bg">
                <div class="funnel-bar" :style="{ width: item.width + '%', background: item.gradient }"></div>
              </div>
            </div>
          </div>
        </div>

        <!-- 月度趋势 -->
        <div class="card-section">
          <h3 class="section-title">月度趋势</h3>
          <v-chart :option="trendOption" autoresize style="height: 280px" />
        </div>
      </div>

      <!-- 活动对比 -->
      <div class="card-section" style="margin-top: 16px">
        <h3 class="section-title">活动对比</h3>
        <a-table :columns="comparisonColumns" :data-source="data?.contestComparison || []" :pagination="false"
          row-key="contestId" size="small">
          <template #bodyCell="{ column, record }">
            <template
              v-if="column.key === 'passRate' || column.key === 'submitRate' || column.key === 'reviewRate' || column.key === 'awardRate'">
              <span class="rate-pill" :class="getRateClass(record[column.key])">{{ record[column.key] }}%</span>
            </template>
            <template v-else-if="column.key === 'avgScore'">
              <span v-if="record.avgScore" class="score-text">{{ record.avgScore }}</span>
              <span v-else class="text-muted">-</span>
            </template>
          </template>
        </a-table>
      </div>
    </a-spin>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import {
  TrophyOutlined, TeamOutlined, CheckCircleOutlined,
  FileTextOutlined, AuditOutlined, StarOutlined,
} from '@ant-design/icons-vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import { analyticsApi, type OverviewData } from '@/api/analytics'
import { contestsApi } from '@/api/contests'

use([CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent])

const loading = ref(true)
const data = ref<OverviewData | null>(null)
const timeRange = ref<string>('all')
const contestFilter = ref<number | undefined>(undefined)
const contestOptions = ref<{ id: number; name: string }[]>([])

const statsItems = computed(() => {
  const s = data.value?.summary
  if (!s) return []
  return [
    { key: 'contests', label: '活动总数', value: s.totalContests, icon: TrophyOutlined, color: '#6366f1', bgColor: 'rgba(99,102,241,0.1)' },
    { key: 'reg', label: '累计报名', value: s.totalRegistrations, icon: TeamOutlined, color: '#3b82f6', bgColor: 'rgba(59,130,246,0.1)' },
    { key: 'passed', label: '报名通过', value: s.passedRegistrations, icon: CheckCircleOutlined, color: '#10b981', bgColor: 'rgba(16,185,129,0.1)' },
    { key: 'works', label: '作品总数', value: s.totalWorks, icon: FileTextOutlined, color: '#f59e0b', bgColor: 'rgba(245,158,11,0.1)' },
    { key: 'reviewed', label: '已完成评审', value: s.reviewedWorks, icon: AuditOutlined, color: '#14b8a6', bgColor: 'rgba(20,184,166,0.1)' },
    { key: 'awarded', label: '获奖作品', value: s.awardedWorks, icon: StarOutlined, color: '#ef4444', bgColor: 'rgba(239,68,68,0.1)' },
  ]
})

const funnelItems = computed(() => {
  const f = data.value?.funnel
  if (!f) return []
  const max = f.registered || 1
  const calcRate = (cur: number, prev: number) => prev > 0 ? (cur / prev * 100).toFixed(1) + '%' : '0%'
  return [
    { label: '报名', value: f.registered, width: 100, gradient: 'linear-gradient(90deg,#6366f1,#818cf8)', rate: '', rateBg: '', rateColor: '' },
    { label: '通过审核', value: f.passed, width: f.passed / max * 100, gradient: 'linear-gradient(90deg,#10b981,#34d399)', rate: calcRate(f.passed, f.registered), rateBg: '#ecfdf5', rateColor: '#10b981' },
    { label: '提交作品', value: f.submitted, width: f.submitted / max * 100, gradient: 'linear-gradient(90deg,#3b82f6,#60a5fa)', rate: calcRate(f.submitted, f.passed), rateBg: '#eff6ff', rateColor: '#3b82f6' },
    { label: '评审完成', value: f.reviewed, width: f.reviewed / max * 100, gradient: 'linear-gradient(90deg,#f59e0b,#fbbf24)', rate: calcRate(f.reviewed, f.submitted), rateBg: '#fffbeb', rateColor: '#f59e0b' },
    { label: '获奖', value: f.awarded, width: f.awarded / max * 100, gradient: 'linear-gradient(90deg,#ef4444,#f87171)', rate: calcRate(f.awarded, f.reviewed), rateBg: '#fef2f2', rateColor: '#ef4444' },
  ]
})

const trendOption = computed(() => {
  const trend = data.value?.monthlyTrend || []
  return {
    tooltip: { trigger: 'axis' },
    legend: { data: ['报名量', '作品量'], bottom: 0, textStyle: { fontSize: 12, color: '#9ca3af' } },
    grid: { left: 40, right: 16, top: 16, bottom: 40 },
    xAxis: { type: 'category', data: trend.map(t => t.month), axisLine: { lineStyle: { color: '#e5e7eb' } }, axisLabel: { color: '#9ca3af' }, axisTick: { show: false } },
    yAxis: { type: 'value', axisLine: { show: false }, axisTick: { show: false }, splitLine: { lineStyle: { color: '#f3f4f6', type: 'dashed' } }, axisLabel: { color: '#9ca3af' } },
    series: [
      { name: '报名量', type: 'line', data: trend.map(t => t.registrations), smooth: true, symbol: 'circle', symbolSize: 6, lineStyle: { width: 3, color: '#6366f1' }, itemStyle: { color: '#6366f1' }, areaStyle: { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: 'rgba(99,102,241,0.15)' }, { offset: 1, color: 'rgba(99,102,241,0)' }] } } },
      { name: '作品量', type: 'line', data: trend.map(t => t.works), smooth: true, symbol: 'circle', symbolSize: 6, lineStyle: { width: 3, color: '#f59e0b' }, itemStyle: { color: '#f59e0b' }, areaStyle: { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: 'rgba(245,158,11,0.12)' }, { offset: 1, color: 'rgba(245,158,11,0)' }] } } },
    ],
  }
})

const comparisonColumns = [
  { title: '活动名称', dataIndex: 'contestName', key: 'contestName', width: 200 },
  { title: '报名数', dataIndex: 'registrations', key: 'registrations', width: 80, align: 'center' as const },
  { title: '通过率', key: 'passRate', width: 90, align: 'center' as const },
  { title: '提交率', key: 'submitRate', width: 90, align: 'center' as const },
  { title: '评审完成率', key: 'reviewRate', width: 100, align: 'center' as const },
  { title: '获奖率', key: 'awardRate', width: 90, align: 'center' as const },
  { title: '平均分', key: 'avgScore', width: 80, align: 'center' as const },
]

const getRateClass = (rate: number) => {
  if (rate >= 80) return 'rate-high'
  if (rate >= 50) return 'rate-mid'
  if (rate > 0) return 'rate-low'
  return 'rate-zero'
}

const fetchContestOptions = async () => {
  try {
    const res = await contestsApi.getList({ page: 1, pageSize: 100 })
    contestOptions.value = res.list.map(c => ({ id: c.id, name: c.contestName }))
  } catch { /* */ }
}

const fetchData = async () => {
  loading.value = true
  try {
    data.value = await analyticsApi.getOverview({
      contestId: contestFilter.value,
      timeRange: timeRange.value === 'all' ? undefined : timeRange.value,
    })
  } catch (error) { message.error('获取统计数据失败'); console.error(error) }
  finally { loading.value = false }
}

onMounted(() => { fetchContestOptions(); fetchData() })
</script>

<style scoped lang="scss">
$primary: #6366f1;

.title-card {
  margin-bottom: 16px;
  border: none;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);

  :deep(.ant-card-head) {
    border-bottom: none;

    .ant-card-head-title {
      font-size: 18px;
      font-weight: 600;
    }
  }

  :deep(.ant-card-body) {
    padding: 0;
  }
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  transition: all 0.2s;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba($primary, 0.12);
  }

  .stat-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    flex-shrink: 0;
  }

  .stat-info {
    display: flex;
    flex-direction: column;

    .stat-count {
      font-size: 22px;
      font-weight: 700;
      color: #1e1b4b;
      line-height: 1.2;
    }

    .stat-label {
      font-size: 12px;
      color: #9ca3af;
    }
  }
}

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

.card-section {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  padding: 24px;

  .section-title {
    font-size: 14px;
    font-weight: 600;
    color: #1e1b4b;
    margin: 0 0 16px;
  }
}

// 漏斗
.funnel-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.funnel-item {
  .funnel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
  }

  .funnel-label {
    font-size: 13px;
    font-weight: 500;
    color: #374151;
  }

  .funnel-values {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .funnel-count {
    font-size: 14px;
    font-weight: 700;
    color: #1e1b4b;
  }

  .funnel-rate {
    display: inline-flex;
    padding: 1px 8px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
  }

  .funnel-bar-bg {
    height: 28px;
    background: #f3f4f6;
    border-radius: 8px;
    overflow: hidden;
  }

  .funnel-bar {
    height: 100%;
    border-radius: 8px;
    transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
  }
}

// 转化率标签
.rate-pill {
  display: inline-flex;
  padding: 2px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
}

.rate-high {
  background: #ecfdf5;
  color: #10b981;
}

.rate-mid {
  background: #fffbeb;
  color: #f59e0b;
}

.rate-low {
  background: #fef2f2;
  color: #ef4444;
}

.rate-zero {
  background: #f3f4f6;
  color: #d1d5db;
}

.score-text {
  font-weight: 700;
  color: $primary;
}

.text-muted {
  color: #d1d5db;
}

:deep(.ant-table-wrapper) {
  background: transparent;

  .ant-table-thead>tr>th {
    background: #fafafa;
    font-weight: 600;
    font-size: 13px;
  }

  .ant-table-tbody>tr:hover>td {
    background: rgba($primary, 0.03);
  }
}
</style>
