<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import * as echarts from 'echarts'
import { buildInsightMockData } from './insightMockData'
import { hudThemeRef } from '../../composables/useHudTheme'

const mock = buildInsightMockData()

const lineRef = ref(null)
const barRef = ref(null)
const pieRef = ref(null)
const areaRef = ref(null)
let charts = []
let ro

function getPalette() {
  const dark = hudThemeRef.value === 'dark'
  if (dark) {
    return {
      primary: '#818cf8',
      secondary: '#6366f1',
      warn: '#fbbf24',
      grid: '#334155',
      text: '#94a3b8',
      pieStroke: '#1e293b',
      areaTop: 'rgba(129, 140, 248, 0.38)',
      areaBottom: 'rgba(129, 140, 248, 0.02)',
    }
  }
  return {
    primary: '#4f46e5',
    secondary: '#6366f1',
    warn: '#d97706',
    grid: '#e2e8f0',
    text: '#475569',
    pieStroke: '#fff',
    areaTop: 'rgba(79, 70, 229, 0.35)',
    areaBottom: 'rgba(79, 70, 229, 0.02)',
  }
}

function baseChart(dom, option) {
  const c = echarts.init(dom, null, { renderer: 'canvas' })
  c.setOption(option)
  return c
}

function disposeCharts() {
  charts.forEach((c) => c && c.dispose())
  charts = []
}

function initAll() {
  if (!lineRef.value || !barRef.value || !pieRef.value || !areaRef.value) return

  disposeCharts()

  const palette = getPalette()

  const line = baseChart(lineRef.value, {
    animationDuration: 900,
    animationEasing: 'cubicOut',
    color: [palette.primary],
    grid: { left: 48, right: 16, top: 28, bottom: 32 },
    tooltip: { trigger: 'axis' },
    xAxis: {
      type: 'category',
      data: mock.trendLine.categories,
      axisLine: { lineStyle: { color: palette.grid } },
      axisLabel: { color: palette.text },
    },
    yAxis: {
      type: 'value',
      splitLine: { lineStyle: { color: palette.grid } },
      axisLabel: { color: palette.text },
    },
    series: [
      {
        name: '检测任务',
        type: 'line',
        smooth: true,
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: palette.areaTop },
            { offset: 1, color: palette.areaBottom },
          ]),
        },
        data: mock.trendLine.series,
      },
    ],
  })

  const bar = baseChart(barRef.value, {
    animationDuration: 800,
    color: [palette.secondary],
    grid: { left: 48, right: 16, top: 28, bottom: 32 },
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: mock.barMedia.categories, axisLabel: { color: palette.text } },
    yAxis: {
      type: 'value',
      splitLine: { lineStyle: { color: palette.grid } },
      axisLabel: { color: palette.text },
    },
    series: [
      {
        name: '数量',
        type: 'bar',
        barMaxWidth: 36,
        itemStyle: { borderRadius: [6, 6, 0, 0] },
        data: mock.barMedia.values,
      },
    ],
  })

  const pie = baseChart(pieRef.value, {
    animationDuration: 900,
    color: [palette.primary, palette.secondary, palette.warn, '#22d3ee', '#94a3b8'],
    tooltip: { trigger: 'item' },
    series: [
      {
        name: '占比',
        type: 'pie',
        radius: ['42%', '68%'],
        itemStyle: { borderRadius: 6, borderColor: palette.pieStroke, borderWidth: 2 },
        label: { color: palette.text },
        data: mock.pieDefect.names.map((n, i) => ({ name: n, value: mock.pieDefect.values[i] })),
      },
    ],
  })

  const area = baseChart(areaRef.value, {
    animationDuration: 900,
    color: [palette.primary, palette.warn],
    legend: { textStyle: { color: palette.text } },
    grid: { left: 48, right: 16, top: 36, bottom: 28 },
    tooltip: { trigger: 'axis' },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: mock.areaCompletion.months,
      axisLabel: { color: palette.text },
    },
    yAxis: {
      type: 'value',
      splitLine: { lineStyle: { color: palette.grid } },
      axisLabel: { color: palette.text },
    },
    series: [
      { name: '已完成', type: 'line', stack: 't', smooth: true, areaStyle: { opacity: 0.22 }, data: mock.areaCompletion.completed },
      { name: '待处理', type: 'line', stack: 't', smooth: true, areaStyle: { opacity: 0.18 }, data: mock.areaCompletion.pending },
    ],
  })

  charts = [line, bar, pie, area]
}

function resizeCharts() {
  charts.forEach((c) => c && c.resize())
}

watch(hudThemeRef, () => {
  nextTick(() => {
    disposeCharts()
    initAll()
    resizeCharts()
  })
})

onMounted(() => {
  nextTick(() => {
    initAll()
    ro = new ResizeObserver(() => resizeCharts())
    ;[lineRef, barRef, pieRef, areaRef].forEach((r) => {
      if (r.value) ro.observe(r.value)
    })
    window.addEventListener('resize', resizeCharts)
  })
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeCharts)
  if (ro) ro.disconnect()
  disposeCharts()
})
</script>

<template>
  <section class="insight">
    <div class="kpi-grid">
      <div class="kpi shell-card-elevated">
        <span class="label">近7日检测任务</span>
        <span class="val shell-kpi-num">{{ mock.kpi.detectionWeek }}</span>
        <span class="delta">环比 +{{ mock.kpi.detectionDelta }}%</span>
      </div>
      <div class="kpi shell-card-elevated">
        <span class="label">媒体资产</span>
        <span class="val shell-kpi-num">{{ mock.kpi.mediaAssets }}</span>
        <span class="delta muted">图像 / 视频统一管理</span>
      </div>
      <div class="kpi shell-card-elevated">
        <span class="label">模型版本</span>
        <span class="val shell-kpi-num">{{ mock.kpi.modelVersions }}</span>
        <span class="delta muted">可部署检测模型</span>
      </div>
      <div class="kpi shell-card-elevated">
        <span class="label">任务成功率</span>
        <span class="val shell-kpi-num">{{ mock.kpi.taskSuccessRate }}%</span>
        <span class="delta">流水线健康度</span>
      </div>
    </div>

    <div class="chart-grid">
      <div class="chart shell-card-elevated">
        <h3>周度检测趋势</h3>
        <div ref="lineRef" class="chart-dom" />
      </div>
      <div class="chart shell-card-elevated">
        <h3>媒介类型分布</h3>
        <div ref="barRef" class="chart-dom" />
      </div>
      <div class="chart shell-card-elevated">
        <h3>隐患类型占比</h3>
        <div ref="pieRef" class="chart-dom" />
      </div>
      <div class="chart shell-card-elevated">
        <h3>任务完成与积压</h3>
        <div ref="areaRef" class="chart-dom" />
      </div>
    </div>
  </section>
</template>

<style scoped>
.insight {
  margin-bottom: 8px;
}
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin: 18px 0 20px;
}
@media (max-width: 1200px) {
  .kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 640px) {
  .kpi-grid {
    grid-template-columns: 1fr;
  }
}
.kpi {
  padding: 16px 18px;
}
.kpi .label {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 8px;
}
.kpi .val {
  display: block;
  font-size: 1.65rem;
  color: var(--foreground);
}
.kpi .delta {
  display: block;
  margin-top: 8px;
  font-size: 0.78rem;
  color: var(--accent);
  font-weight: 500;
}
.kpi .delta.muted {
  color: var(--muted);
  font-weight: 400;
}
.chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 1100px) {
  .chart-grid {
    grid-template-columns: 1fr;
  }
}
.chart {
  padding: 14px 16px 8px;
}
.chart h3 {
  margin: 0 0 6px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--foreground);
}
.chart-dom {
  height: 260px;
  width: 100%;
}
@media (max-width: 1366px) {
  .chart-dom {
    height: 220px;
  }
}
</style>
