﻿<template>
  <div class="chart-analysis-container">
    <!-- 仪表盘：整体健康度 -->
    <div class="gauges-row">
      <!-- 月度仪表盘 -->
      <div class="chart-card gauge-card">
        <div class="chart-header">
          <div class="chart-title">
            月度健康度
          </div>
          <div class="chart-subtitle">
            本月预算
          </div>
        </div>
        <div
          ref="monthGaugeRef"
          class="chart-body gauge-chart"
        />
        <div class="gauge-footer compact">
          <div class="gauge-item">
            <span class="label">已用</span>
            <span class="value expense">¥{{ formatMoney(overallStats.month.current) }}</span>
          </div>
          <div class="gauge-item">
            <span class="label">预算</span>
            <span class="value">¥{{ formatMoney(overallStats.month.limit) }}</span>
          </div>
        </div>
      </div>

      <!-- 年度仪表盘 -->
      <div class="chart-card gauge-card">
        <div class="chart-header">
          <div class="chart-title">
            年度健康度
          </div>
          <div class="chart-subtitle">
            本年预算
          </div>
        </div>
        <div
          ref="yearGaugeRef"
          class="chart-body gauge-chart"
        />
        <div class="gauge-footer compact">
          <div class="gauge-item">
            <span class="label">已用</span>
            <span class="value expense">¥{{ formatMoney(overallStats.year.current) }}</span>
          </div>
          <div class="gauge-item">
            <span class="label">预算</span>
            <span class="value">¥{{ formatMoney(overallStats.year.limit) }}</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 月度预算进度 -->
    <div
      v-if="budgets.length > 0"
      class="chart-card"
    >
      <div class="chart-header">
        <div class="chart-title">
          预算进度（月度）
        </div>
        <div class="chart-subtitle">
          本月各预算执行情况
        </div>
      </div>
      <div
        ref="monthBarChartRef"
        class="chart-body bar-chart"
        :style="{ height: calculateChartHeight() + 'px' }"
      />
    </div>

    <!-- 年度预算进度 -->
    <div
      v-if="budgets.length > 0"
      class="chart-card"
      style="margin-top: 12px"
    >
      <div class="chart-header">
        <div class="chart-title">
          预算进度（年度）
        </div>
        <div class="chart-subtitle">
          本年各预算执行情况
        </div>
      </div>
      <div
        ref="yearBarChartRef"
        class="chart-body bar-chart"
        :style="{ height: calculateChartHeight() + 'px' }"
      />
    </div>

    <!-- 空状态占位 -->
    <div
      v-else
      class="chart-card empty-card"
    >
      <van-empty
        description="暂无预算数据"
        image="search"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import { BudgetCategory } from '@/constants/enums'
import { getCssVar } from '@/utils/theme'

const props = defineProps({
  overallStats: {
    type: Object,
    required: true
  },
  budgets: {
    type: Array,
    default: () => []
  },
  activeTab: {
    type: [Number, String],
    default: BudgetCategory.Expense
  }
})

const monthGaugeRef = ref(null)
const yearGaugeRef = ref(null)
const monthBarChartRef = ref(null)
const yearBarChartRef = ref(null)
let monthGaugeChart = null
let yearGaugeChart = null
let monthBarChart = null
let yearBarChart = null

const formatMoney = (val) => {
  if (val >= 10000) {
    return (val / 10000).toFixed(1) + 'w'
  }
  return parseFloat(val || 0).toLocaleString(undefined, {
    minimumFractionDigits: 0,
    maximumFractionDigits: 0
  })
}

const initGaugeChart = (chartInstance, dom, data, isExpense) => {
  if (!dom) { return null }

  const chart = echarts.init(dom)
  updateSingleGauge(chart, data, isExpense)
  return chart
}

const updateSingleGauge = (chart, data, isExpense) => {
  if (!chart) { return }

  const rate = parseFloat(data.rate || 0)
  // 颜色逻辑
  let color = getCssVar('--chart-success') // 绿色
  if (isExpense) {
    if (rate >= 100) { color = getCssVar('--chart-danger') } // 红色
    else if (rate >= 80) { color = getCssVar('--chart-warning') } // 橙色
  } else {
    if (rate >= 100) { color = getCssVar('--chart-success') } // 绿色
    else if (rate >= 80) { color = getCssVar('--chart-warning') } // 橙色
    else { color = getCssVar('--chart-danger') } // 红色
  }

  const option = {
    series: [
      {
        type: 'gauge',
        startAngle: 180,
        endAngle: 0,
        min: 0,
        max: Math.max(100, rate * 1.2),
        splitNumber: 5,
        radius: '110%', // 放大一点以适应小卡片
        center: ['50%', '75%'],
        itemStyle: {
          color: color,
          shadowColor: getCssVar('--chart-shadow'),
          shadowBlur: 10,
          shadowOffsetX: 2,
          shadowOffsetY: 2
        },
        progress: {
          show: true,
          roundCap: true,
          width: 12 // 变细一点
        },
        pointer: { show: false },
        axisLine: {
          roundCap: true,
          lineStyle: {
            width: 12,
            color: [[1, getCssVar('--chart-axis')]]
          }
        },
        axisTick: { show: false },
        splitLine: { show: false },
        axisLabel: { show: false },
        detail: {
          valueAnimation: true,
          fontSize: 24, // 字体调小
          offsetCenter: [0, -5],
          color: 'var(--van-text-color)',
          formatter: '{value}%',
          fontWeight: 'bold',
          fontFamily: 'DIN Alternate, system-ui'
        },
        data: [{ value: rate }]
      }
    ]
  }

  chart.setOption(option)
}

const updateCharts = () => {
  const isExpense = props.activeTab === BudgetCategory.Expense
  updateSingleGauge(monthGaugeChart, props.overallStats.month, isExpense)
  updateSingleGauge(yearGaugeChart, props.overallStats.year, isExpense)

  // 确保 barChart 已初始化，如果还未初始化则先初始化
  if (props.budgets.length > 0) {
    if (!monthBarChart && monthBarChartRef.value) {
      monthBarChart = echarts.init(monthBarChartRef.value)
    }
    if (!yearBarChart && yearBarChartRef.value) {
      yearBarChart = echarts.init(yearBarChartRef.value)
    }
    updateBarChart()
  }
}

const updateBarChart = () => {
  if (!monthBarChart || !yearBarChart) { return }

  const sortedBudgets = [...props.budgets].sort((a, b) => b.current - a.current).slice(0, 10)
  const categories = sortedBudgets.map(b => b.name)
  // 月度数据
  const monthLimits = sortedBudgets.map(b => b.monthLimit || b.limit)
  const monthCurrents = sortedBudgets.map(b => b.monthCurrent || b.current)
  // 年度数据
  const yearLimits = sortedBudgets.map(b => b.yearLimit || b.limit)
  const yearCurrents = sortedBudgets.map(b => b.yearCurrent || b.current)

  const getColors = (data, limits) => {
    return data.map((current, idx) => {
      const limit = limits[idx]
      const rate = limit > 0 ? (current / limit) : 0
      if (props.activeTab === BudgetCategory.Expense) {
        if (rate >= 1) { return getCssVar('--chart-danger') }
        if (rate >= 0.8) { return getCssVar('--chart-warning') }
        return getCssVar('--chart-primary')
      } else {
        if (rate >= 1) { return getCssVar('--chart-success') }
        return getCssVar('--chart-primary')
      }
    })
  }

  const monthColors = getColors(monthCurrents, monthLimits)
  const yearColors = getColors(yearCurrents, yearLimits)

  // 获取当前主题下的颜色值
  const textColor = getCssVar('--van-text-color')
  const textColor2 = getCssVar('--van-text-color-2')
  const bgColor3 = getCssVar('--van-background-3')
  const splitLineColor = getCssVar('--chart-split')
  const axisLabelColor = getCssVar('--chart-text-muted')

  const createOption = (limits, currents, colors) => {
    return {
      grid: {
        left: '3%',
        right: '8%',
        bottom: '3%',
        top: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'value',
        splitLine: {
          lineStyle: {
            type: 'dashed',
            color: splitLineColor
          }
        },
        axisLabel: {
          color: axisLabelColor,
          formatter: (value) => {
            if (value >= 10000) { return (value / 10000).toFixed(0) + 'w' }
            return value
          }
        }
      },
      yAxis: {
        type: 'category',
        data: categories,
        axisLine: { show: false },
        axisTick: { show: false },
        axisLabel: {
          color: textColor,
          width: 50,
          overflow: 'truncate',
          interval: 0
        }
      },
      series: [
        {
          name: '预算',
          type: 'bar',
          data: limits,
          barWidth: 10,
          itemStyle: {
            color: bgColor3,
            borderRadius: 5
          },
          z: 1,
          label: {
            show: true,
            position: 'right',
            formatter: (params) => {
              const val = params.value
              return val >= 10000 ? (val / 10000).toFixed(1) + 'w' : val
            },
            color: textColor2,
            fontSize: 10
          }
        },
        {
          name: '实际',
          type: 'bar',
          data: currents,
          barGap: '-100%',
          barWidth: 10,
          itemStyle: {
            color: (params) => colors[params.dataIndex],
            borderRadius: 5
          },
          z: 2
        }
      ]
    }
  }

  monthBarChart.setOption(createOption(monthLimits, monthCurrents, monthColors))
  yearBarChart.setOption(createOption(yearLimits, yearCurrents, yearColors))
}

const calculateChartHeight = () => {
  // 根据数据数量动态计算图表高度
  // 每个类别占用 60px，最少显示 200px，最多 400px
  const dataCount = Math.min(props.budgets.length, 10) // 最多显示10条
  const minHeight = 150
  const maxHeight = 400
  const heightPerItem = 60
  const calculatedHeight = Math.max(minHeight, dataCount * heightPerItem)
  return Math.min(calculatedHeight, maxHeight)
}

watch(() => props.overallStats, () => nextTick(updateCharts), { deep: true })
watch(() => props.budgets, () => {
  nextTick(() => {
    if (props.budgets.length > 0 && (!monthBarChart || !yearBarChart) && monthBarChartRef.value && yearBarChartRef.value) {
      // budgets 从空到有值，需要初始化图表
      monthBarChart = echarts.init(monthBarChartRef.value)
      yearBarChart = echarts.init(yearBarChartRef.value)
      updateBarChart()
    } else {
      updateCharts()
    }
  })
}, { deep: true })
watch(() => props.activeTab, () => nextTick(updateCharts))

const handleResize = () => {
  monthGaugeChart?.resize()
  yearGaugeChart?.resize()
  monthBarChart?.resize()
  yearBarChart?.resize()
}

onMounted(() => {
  nextTick(() => {
    const isExpense = props.activeTab === BudgetCategory.Expense
    monthGaugeChart = initGaugeChart(monthGaugeChart, monthGaugeRef.value, props.overallStats.month, isExpense)
    yearGaugeChart = initGaugeChart(yearGaugeChart, yearGaugeRef.value, props.overallStats.year, isExpense)
    // 只在有数据时初始化柱状图
    if (props.budgets.length > 0) {
      if (monthBarChartRef.value) {
        monthBarChart = echarts.init(monthBarChartRef.value)
      }
      if (yearBarChartRef.value) {
        yearBarChart = echarts.init(yearBarChartRef.value)
      }
      updateBarChart()
    }
    window.addEventListener('resize', handleResize)
  })
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  monthGaugeChart?.dispose()
  yearGaugeChart?.dispose()
  monthBarChart?.dispose()
  yearBarChart?.dispose()
})
</script>

<style scoped>
.chart-analysis-container {
  padding: 12px;
  padding-bottom: 80px;
}

.gauges-row {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}

.chart-card {
  background: var(--van-background-2);
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.gauge-card {
  flex: 1;
  min-width: 0;
  /* 防止 flex 子项溢出 */
  padding: 12px;
  /* 减小内边距 */
}

.chart-header {
  margin-bottom: 12px;
}

.chart-title {
  font-size: 14px;
  /* 调小标题 */
  font-weight: 600;
  color: var(--van-text-color);
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chart-subtitle {
  font-size: 10px;
  color: var(--van-text-color-2);
}

.chart-body {
  width: 100%;
}

.gauge-chart {
  height: 120px;
  /* 调小高度 */
}

.bar-chart {
  min-height: 200px;
  max-height: 400px;
}

.gauge-footer {
  display: flex;
  justify-content: space-around;
  /* 分散对齐 */
  align-items: center;
  margin-top: -20px;
  position: relative;
  z-index: 10;
}

.gauge-item {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gauge-item .label {
  font-size: 10px;
  color: var(--van-text-color-2);
  transform: scale(0.9);
  /* 视觉上更小 */
}

.gauge-item .value {
  font-size: 12px;
  font-weight: 600;
  font-family: DIN Alternate, system-ui;
  color: var(--van-text-color);
}

.gauge-item .value.expense {
  color: var(--van-primary-color);
}
</style>