<script lang="ts" setup>
import type { EchartsUIType } from '@vben/plugins/echarts'

import { onMounted, ref, watch } from 'vue'

import { EchartsUI, useEcharts } from '@vben/plugins/echarts'

const props = defineProps<{
  excellent: number
  good: number
  pass: number
  unqualified: number
  excellentRate: number
  goodRate: number
  passRate: number
  unqualifiedRate: number
}>()

const chartMode = ref<'bar' | 'pie'>('bar')

const chartRef = ref<EchartsUIType>()
const { renderEcharts } = useEcharts(chartRef)

const categories = ['优秀', '良好', '合格', '其他/不及格']
const colors = ['#1E40AF', '#3B82F6', '#93C5FD', '#EF4444']

function getCounts() {
  return [
    Number(props.excellent),
    Number(props.good),
    Number(props.pass),
    Number(props.unqualified),
  ]
}

function getRates() {
  return [
    +(Number(props.excellentRate) * 100).toFixed(2),
    +(Number(props.goodRate) * 100).toFixed(2),
    +(Number(props.passRate) * 100).toFixed(2),
    +(Number(props.unqualifiedRate) * 100).toFixed(2),
  ]
}

function renderBar() {
  const counts = getCounts()
  const rates = getRates()
  renderEcharts({
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: (params: any) => {
        const i = params[0].dataIndex
        return `<b>${categories[i]}</b><br/>数量: ${counts[i]}<br/>占比: ${rates[i]}%`
      },
      backgroundColor: '#fff',
      borderColor: '#E2E8F0',
      textStyle: { color: '#0F172A' },
    },
    grid: {
      left: '4%',
      right: '4%',
      bottom: '10%',
      top: '12%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: categories,
      axisLabel: { color: '#475569', fontSize: 13, fontWeight: 500 },
      axisLine: { lineStyle: { color: '#E2E8F0' } },
      axisTick: { show: false },
    },
    yAxis: {
      type: 'value',
      name: '数量',
      nameTextStyle: { color: '#94A3B8', fontSize: 12 },
      axisLabel: { color: '#94A3B8' },
      splitLine: { lineStyle: { color: '#F1F5F9', type: 'dashed' } },
      axisLine: { show: false },
      axisTick: { show: false },
    },
    series: [
      {
        type: 'bar',
        barWidth: '38%',
        label: {
          show: true,
          position: 'top',
          color: '#475569',
          fontWeight: 600,
          fontSize: 13,
        },
        data: counts.map((v, i) => ({
          value: v,
          itemStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                { offset: 0, color: colors[i]! },
                { offset: 1, color: `${colors[i]}4D` },
              ],
            },
            borderRadius: [6, 6, 0, 0],
          },
        })),
        animationDuration: 800,
        animationEasing: 'cubicOut',
      },
    ],
  })
}

function renderPie() {
  const rates = getRates()
  renderEcharts({
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {d}%',
      backgroundColor: '#fff',
      borderColor: '#E2E8F0',
      textStyle: { color: '#0F172A' },
    },
    legend: {
      bottom: '2%',
      itemWidth: 12,
      itemHeight: 12,
      itemGap: 20,
      textStyle: { color: '#475569', fontSize: 13 },
    },
    series: [
      {
        type: 'pie',
        radius: ['40%', '65%'],
        center: ['50%', '45%'],
        avoidLabelOverlap: true,
        label: {
          show: true,
          formatter: '{b}\n{d}%',
          fontSize: 12,
          color: '#475569',
        },
        labelLine: { length: 12, length2: 8 },
        itemStyle: { borderRadius: 6, borderColor: '#fff', borderWidth: 2 },
        data: categories.map((name, i) => ({
          name,
          value: rates[i],
          itemStyle: { color: colors[i] },
        })),
        animationDuration: 800,
        animationEasing: 'cubicOut',
      },
    ],
  })
}

function render() {
  if (chartMode.value === 'pie') {
    renderPie()
  } else {
    renderBar()
  }
}

function toggleMode() {
  chartMode.value = chartMode.value === 'bar' ? 'pie' : 'bar'
}

onMounted(render)
watch(chartMode, render)
watch(
  () => [
    props.excellent,
    props.good,
    props.pass,
    props.unqualified,
    props.excellentRate,
    props.goodRate,
    props.passRate,
    props.unqualifiedRate,
  ],
  render,
)
</script>

<template>
  <div class="relative">
    <div class="absolute right-0 top-[-32px] z-10 flex gap-1">
      <button
        class="rounded px-2 py-0.5 text-xs transition-colors"
        :class="
          chartMode === 'bar'
            ? 'bg-blue-500 text-white'
            : 'bg-gray-100 text-gray-500 hover:bg-gray-200'
        "
        @click="chartMode !== 'bar' && toggleMode()"
      >
        数量
      </button>
      <button
        class="rounded px-2 py-0.5 text-xs transition-colors"
        :class="
          chartMode === 'pie'
            ? 'bg-blue-500 text-white'
            : 'bg-gray-100 text-gray-500 hover:bg-gray-200'
        "
        @click="chartMode !== 'pie' && toggleMode()"
      >
        占比
      </button>
    </div>
    <EchartsUI ref="chartRef" class="h-[280px] w-full" />
  </div>
</template>
