<template>
  <div class="gauge-chart">
    <div class="gauge-body">
      <div ref="chartElement" class="gauge-canvas" role="img" :aria-label="ariaLabel"></div>
      <div class="gauge-center-value" aria-hidden="true">
        <strong>{{ normalizedRatio }}%</strong>
        <span>已执行</span>
      </div>
    </div>
    <div class="gauge-summary">
      <div>
        <span>预算总额</span>
        <strong>{{ total }}</strong>
      </div>
      <div>
        <span>已执行</span>
        <strong>{{ used }}</strong>
      </div>
      <div>
        <span>剩余可用</span>
        <strong>{{ left }}</strong>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, shallowRef } from 'vue'
import { GaugeChart as EChartsGaugeChart } from 'echarts/charts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'

import { useEcharts } from '../../composables/useEcharts.js'
import { useThemeColors } from '../../composables/useThemeColors.js'

use([EChartsGaugeChart, CanvasRenderer])

const props = defineProps({
  ratio: { type: [Number, String], required: true },
  total: { type: String, required: true },
  used: { type: String, required: true },
  left: { type: String, required: true }
})

const chartElement = shallowRef(null)
const themeColors = useThemeColors()
const normalizedRatio = computed(() => Math.max(0, Math.min(100, Math.round(Number(props.ratio) || 0))))
const ariaLabel = computed(() => `预算执行率${normalizedRatio.value}%，预算总额${props.total}，已执行${props.used}，剩余${props.left}`)

const chartOptions = computed(() => {
  const primary = themeColors.value.chartPrimary

  return {
    backgroundColor: 'transparent',
    animation: true,
    animationDuration: 1200,
    animationDurationUpdate: 1200,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear',
    series: [
      {
        type: 'gauge',
        startAngle: 205,
        endAngle: -25,
        min: 0,
        max: 100,
        radius: '104%',
        center: ['50%', '66%'],
        pointer: { show: false },
        progress: {
          show: true,
          roundCap: true,
          width: 14,
          itemStyle: {
            color: primary
          }
        },
        axisLine: {
          roundCap: true,
          lineStyle: {
            width: 14,
            color: [[1, '#e2e8f0']]
          }
        },
        axisTick: { show: false },
        splitLine: { show: false },
        axisLabel: { show: false },
        anchor: { show: false },
        detail: { show: false },
        title: { show: false },
        data: [{ value: normalizedRatio.value, name: '已执行' }]
      }
    ]
  }
})

useEcharts(chartElement, chartOptions)
</script>

<style scoped>
.gauge-chart {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: center;
}

.gauge-body {
  position: relative;
  height: 128px;
  width: 100%;
}

.gauge-canvas {
  width: 100%;
  height: 100%;
}

.gauge-center-value {
  position: absolute;
  left: 0;
  right: 0;
  top: 60%;
  display: grid;
  justify-items: center;
  gap: 4px;
  min-width: 0;
  transform: translateY(-50%);
  text-align: center;
  pointer-events: none;
}

.gauge-center-value strong {
  color: var(--theme-primary);
  font-size: 24px;
  font-weight: 850;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

.gauge-center-value span {
  color: #64748b;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.gauge-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  text-align: center;
  animation: gaugeSummaryIn 560ms ease both;
  animation-delay: 500ms;
}

.gauge-summary span {
  display: block;
  color: #64748b;
  font-size: 12px;
}

.gauge-summary strong {
  display: block;
  margin-top: 4px;
  color: #1e293b;
  font-size: 13px;
  font-weight: 500;
}

@keyframes gaugeSummaryIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .gauge-summary {
    animation: none;
  }
}
</style>
