<template>
  <div class="analytics-review">
    <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 efficiencyItems" :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 class="stat-unit">{{ item.unit }}</span></span>
            <span class="stat-label">{{ item.label }}</span>
            <span v-if="item.hint" class="stat-hint">{{ item.hint }}</span>
          </div>
        </div>
      </div>

      <div class="grid-5-2">
        <!-- 评委工作量 -->
        <div class="card-section col-span-3">
          <h3 class="section-title">评委工作量</h3>
          <a-table :columns="judgeColumns" :data-source="data?.judgeWorkload || []" :pagination="false"
            row-key="judgeId" size="small">
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'judgeName'">
                <div class="judge-cell">
                  <div class="judge-avatar" :style="{ background: getAvatarColor(record.judgeName) }">{{
                    record.judgeName?.charAt(0) }}</div>
                  <span class="judge-name">{{ record.judgeName }}</span>
                </div>
              </template>
              <template v-else-if="column.key === 'completionRate'">
                <span class="rate-pill" :class="getRateClass(record.completionRate)">{{ record.completionRate }}%</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 v-else-if="column.key === 'scoreStddev'">
                <span :class="getStddevClass(record.scoreStddev)">{{ record.scoreStddev }}</span>
              </template>
            </template>
          </a-table>
        </div>

        <!-- 奖项分布 -->
        <div class="card-section col-span-2">
          <h3 class="section-title">奖项分布</h3>
          <div v-if="data?.awardDistribution?.length">
            <v-chart :option="awardOption" autoresize style="height: 260px" />
          </div>
          <a-empty v-else description="暂无奖项数据" style="padding: 60px 0" />
        </div>
      </div>
    </a-spin>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import {
  ClockCircleOutlined, ThunderboltOutlined, WarningOutlined, BarChartOutlined,
} from '@ant-design/icons-vue'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import { TooltipComponent, LegendComponent } from 'echarts/components'
import { analyticsApi, type ReviewData } from '@/api/analytics'
import { contestsApi } from '@/api/contests'

use([CanvasRenderer, PieChart, TooltipComponent, LegendComponent])

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

const avatarColors = ['#6366f1', '#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899']
const getAvatarColor = (name: string) => {
  const idx = name ? name.charCodeAt(0) % avatarColors.length : 0
  return `linear-gradient(135deg, ${avatarColors[idx]}, ${avatarColors[(idx + 1) % avatarColors.length]})`
}

const efficiencyItems = computed(() => {
  const e = data.value?.efficiency
  if (!e) return []
  return [
    { key: 'days', label: '平均评审周期', value: e.avgReviewDays, unit: '天', icon: ClockCircleOutlined, color: '#3b82f6', bgColor: 'rgba(59,130,246,0.1)', hint: '' },
    { key: 'daily', label: '日均评审量', value: e.dailyReviewCount, unit: '个/日', icon: ThunderboltOutlined, color: '#10b981', bgColor: 'rgba(16,185,129,0.1)', hint: '' },
    { key: 'pending', label: '待评审积压', value: e.pendingAssignments, unit: '个', icon: WarningOutlined, color: '#ef4444', bgColor: 'rgba(239,68,68,0.1)', hint: '' },
    { key: 'stddev', label: '评分一致性', value: e.avgScoreStddev, unit: '分', icon: BarChartOutlined, color: '#6366f1', bgColor: 'rgba(99,102,241,0.1)', hint: '标准差越小越好' },
  ]
})

const awardColors = ['#ef4444', '#f59e0b', '#3b82f6', '#10b981', '#8b5cf6', '#ec4899', '#14b8a6']
const awardOption = computed(() => {
  const dist = data.value?.awardDistribution || []
  return {
    tooltip: { trigger: 'item' },
    legend: { bottom: 0, textStyle: { fontSize: 12, color: '#9ca3af' } },
    series: [{
      type: 'pie', radius: ['45%', '72%'], center: ['50%', '45%'],
      label: { show: true, formatter: '{b}\n{d}%', fontSize: 12, color: '#6b7280' },
      labelLine: { length: 12, length2: 8 },
      itemStyle: { borderRadius: 6, borderColor: '#fff', borderWidth: 3 },
      data: dist.map((d, i) => ({
        value: d.count,
        name: d.awardName,
        itemStyle: { color: awardColors[i % awardColors.length] },
      })),
      emphasis: { itemStyle: { shadowBlur: 12, shadowColor: 'rgba(0,0,0,0.12)' } },
    }],
  }
})

const judgeColumns = [
  { title: '评委姓名', key: 'judgeName', width: 140 },
  { title: '关联活动', dataIndex: 'contestCount', key: 'contestCount', width: 80, align: 'center' as const },
  { title: '已分配', dataIndex: 'assignedCount', key: 'assignedCount', width: 70, align: 'center' as const },
  { title: '已评分', dataIndex: 'scoredCount', key: 'scoredCount', width: 70, align: 'center' as const },
  { title: '完成率', key: 'completionRate', width: 80, align: 'center' as const },
  { title: '平均分', key: 'avgScore', width: 80, align: 'center' as const },
  { title: '标准差', key: 'scoreStddev', width: 80, align: 'center' as const },
]

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

const getStddevClass = (stddev: number) => {
  if (stddev <= 3) return 'stddev-good'
  if (stddev <= 6) return 'stddev-ok'
  return 'stddev-bad'
}

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.getReview({
      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(4, 1fr);
  gap: 12px;
  margin-bottom: 16px;
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px;
  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: 44px;
    height: 44px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    flex-shrink: 0;
  }

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

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

    .stat-unit {
      font-size: 13px;
      font-weight: 400;
      color: #9ca3af;
      margin-left: 2px;
    }

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

    .stat-hint {
      font-size: 10px;
      color: #d1d5db;
    }
  }
}

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

.col-span-3 {
  grid-column: 1;
}

.col-span-2 {
  grid-column: 2;
}

.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;
  }
}

.judge-cell {
  display: flex;
  align-items: center;
  gap: 10px;
}

.judge-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
}

.judge-name {
  font-weight: 500;
  color: #1e1b4b;
}

.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;
}

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

.text-muted {
  color: #d1d5db;
}

.stddev-good {
  font-weight: 600;
  color: #10b981;
}

.stddev-ok {
  font-weight: 600;
  color: #f59e0b;
}

.stddev-bad {
  font-weight: 600;
  color: #ef4444;
}

: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>
