﻿<template>
  <div class="chart-analysis-container">
    <!-- 仪表盘：整体健康度 -->
    <div class="gauges-row">
      <!-- 月度仪表盘 -->
      <div class="chart-card gauge-card">
        <div class="chart-header">
          <div class="chart-title">
            <!-- 月度健康度 -->
            {{ activeTab === BudgetCategory.Expense ? '使用情况' : '完成情况' }}
            (月度)
          </div>
        </div>
        <div
          ref="monthGaugeRef"
          class="chart-body gauge-chart"
        />
        <div class="gauge-footer compact">
          <div class="gauge-item">
            <span class="label">
              {{ activeTab === BudgetCategory.Expense ? '已用' : '已收' }}
            </span>
            <span class="value expense">¥{{ formatMoney(overallStats.month.current) }}</span>
          </div>
          <div class="gauge-item">
            <span class="label">
              {{ activeTab === BudgetCategory.Expense ? '预算' : '目标' }}
            </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">
            {{ activeTab === BudgetCategory.Expense ? '使用情况' : '完成情况' }}
            (年度)
          </div>
        </div>
        <div
          ref="yearGaugeRef"
          class="chart-body gauge-chart"
        />
        <div class="gauge-footer compact">
          <div class="gauge-item">
            <span class="label">
              {{ activeTab === BudgetCategory.Expense ? '已用' : '已收' }}
            </span>
            <span class="value expense">¥{{ formatMoney(overallStats.year.current) }}</span>
          </div>
          <div class="gauge-item">
            <span class="label">
              {{ activeTab === BudgetCategory.Expense ? '预算' : '目标' }}
            </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="burndownChartRef"
        class="chart-body burndown-chart"
      />
      <div class="expand-toggle-row">
        <div
          class="expand-toggle"
          @click="monthBarChartExpanded = !monthBarChartExpanded"
        >
          <span
            class="expand-icon"
            :class="{ expanded: monthBarChartExpanded }"
          >
            ▼
          </span>
          <span class="expand-text">{{ monthBarChartExpanded ? '收起详情' : '展开详情' }}</span>
        </div>
      </div>
      <div
        v-if="monthBarChartExpanded"
        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="yearBurndownChartRef"
        class="chart-body burndown-chart"
      />
      <div class="expand-toggle-row">
        <div
          class="expand-toggle"
          @click="yearBarChartExpanded = !yearBarChartExpanded"
        >
          <span
            class="expand-icon"
            :class="{ expanded: yearBarChartExpanded }"
          >
            ▼
          </span>
          <span class="expand-text">{{ yearBarChartExpanded ? '收起详情' : '展开详情' }}</span>
        </div>
      </div>
      <div
        v-if="yearBarChartExpanded"
        ref="yearBarChartRef"
        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">
          <span style="color: var(--van-danger-color)">红条超支</span> /
          <span style="color: var(--van-success-color)">绿条结余</span>
        </div>
      </div>
      <div
        ref="varianceChartRef"
        class="chart-body bar-chart"
        :style="{ height: calculateChartHeight() + 'px' }"
      />
    </div>

    <!-- 空状态占位 -->
    <div
      v-else-if="budgets.length === 0"
      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)
const burndownChartRef = ref(null)
const yearBurndownChartRef = ref(null)
const varianceChartRef = ref(null)
const monthBarChartExpanded = ref(false)
const yearBarChartExpanded = ref(false)
let monthGaugeChart = null
let yearGaugeChart = null
let monthBarChart = null
let yearBarChart = null
let burndownChart = null
let yearBurndownChart = null
let varianceChart = 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 && monthBarChartExpanded.value) {
      monthBarChart = echarts.init(monthBarChartRef.value)
    }
    if (!yearBarChart && yearBarChartRef.value && yearBarChartExpanded.value) {
      yearBarChart = echarts.init(yearBarChartRef.value)
    }
    if (monthBarChart || yearBarChart) {
      updateBarChart()
    }

    // 更新燃尽图/积累图
    if (!burndownChart && burndownChartRef.value) {
      burndownChart = echarts.init(burndownChartRef.value)
    }
    updateBurndownChart()

    if (!yearBurndownChart && yearBurndownChartRef.value) {
      yearBurndownChart = echarts.init(yearBurndownChartRef.value)
    }
    updateYearBurndownChart()

    if (!varianceChart && varianceChartRef.value) {
      varianceChart = echarts.init(varianceChartRef.value)
    }
    updateVarianceChart()
  }
}

const updateBarChart = () => {
  // 按预算类型分开：月度预算和年度预算
  // 1 = Month, 2 = Year
  const monthBudgets = props.budgets.filter(b => b.type === 1)
  const yearBudgets = props.budgets.filter(b => b.type === 2)

  // 为月度预算计算百分比
  const budgetsWithMonthPercentage = monthBudgets.map(b => {
    const limit = b.limit || 0
    const current = b.current || 0
    const percentage = limit > 0 ? (current / limit) * 100 : 0
    return { ...b, percentage }
  })

  // 为年度预算计算百分比
  const budgetsWithYearPercentage = yearBudgets.map(b => {
    const limit = b.limit || 0
    const current = b.current || 0
    const percentage = limit > 0 ? (current / limit) * 100 : 0
    return { ...b, percentage }
  })

  // 分别按百分比从高到低排序，取前10条
  const sortedMonthBudgets = budgetsWithMonthPercentage.sort((a, b) => b.percentage - a.percentage).slice(0, 10)
  const sortedYearBudgets = budgetsWithYearPercentage.sort((a, b) => b.percentage - a.percentage).slice(0, 10)

  const monthCategories = sortedMonthBudgets.map(b => b.name)
  const yearCategories = sortedYearBudgets.map(b => b.name)

  // 调试输出
  console.log('月度预算项数:', monthBudgets.length, '年度预算项数:', yearBudgets.length)
  console.log('月度排序后:', sortedMonthBudgets.map(b => ({ name: b.name, percentage: b.percentage })))
  console.log('年度排序后:', sortedYearBudgets.map(b => ({ name: b.name, percentage: b.percentage })))

  // 计算月度百分比数据
  const monthPercentages = sortedMonthBudgets.map(b => {
    const limit = b.limit || 0
    const current = b.current || 0
    if (!limit || limit <= 0) {return 0}
    return Math.round((current / limit) * 100)
  })

  // 计算年度百分比数据
  const yearPercentages = sortedYearBudgets.map(b => {
    const limit = b.limit || 0
    const current = b.current || 0
    if (!limit || limit <= 0) {return 0}
    return Math.round((current / limit) * 100)
  })

  const getColors = (percentages) => {
    return percentages.map(percentage => {
      if (props.activeTab === BudgetCategory.Expense) {
        // 支出：百分比越高越不好
        if (percentage >= 90) { return getCssVar('--chart-danger') } // 红色
        if (percentage >= 60) { return getCssVar('--chart-warning') } // 橙色
        return getCssVar('--chart-primary') // 蓝色
      } else {
        // 收入：百分比越高越好（越接近目标越好）
        if (percentage >= 90) { return getCssVar('--chart-success') } // 绿色
        if (percentage >= 60) { return getCssVar('--chart-primary') } // 蓝色
        return getCssVar('--chart-warning') // 橙色
      }
    })
  }

  const monthColors = getColors(monthPercentages)
  const yearColors = getColors(yearPercentages)

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

  const createOption = (categories, percentages, colors) => {
    return {
      grid: {
        left: '3%',
        right: '8%',
        bottom: '3%',
        top: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'value',
        max: 100,
        splitLine: {
          lineStyle: {
            type: 'dashed',
            color: splitLineColor
          }
        },
        axisLabel: {
          color: axisLabelColor,
          formatter: (value) => {
            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: percentages,
          barWidth: 10,
          itemStyle: {
            color: (params) => colors[params.dataIndex],
            borderRadius: 5
          },
          label: {
            show: true,
            position: 'right',
            formatter: (params) => {
              return params.value + '%'
            },
            color: textColor2,
            fontSize: 10
          },
          z: 2
        }
      ]
    }
  }

  if (monthBarChart) {
    monthBarChart.setOption(createOption(monthCategories, monthPercentages, monthColors))
  }
  if (yearBarChart) {
    yearBarChart.setOption(createOption(yearCategories, yearPercentages, yearColors))
  }
}

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

const updateBurndownChart = () => {
  if (!burndownChart) { return }

  // 获取当前月份的日期
  const today = new Date()
  const year = today.getFullYear()
  const month = today.getMonth()
  const daysInMonth = new Date(year, month + 1, 0).getDate()
  const currentDay = today.getDate()
  const isExpense = props.activeTab === BudgetCategory.Expense

  // 生成日期和理想燃尽线/积累线
  const dates = []
  const idealBurndown = []
  const actualBurndown = []

  const totalBudget = props.overallStats.month.limit || 0
  const currentExpense = props.overallStats.month.current || 0

  for (let i = 1; i <= daysInMonth; i++) {
    dates.push(`${i}日`)
    
    if (isExpense) {
      // 支出：燃尽图（向下走）
      // 理想燃尽：每天均匀消耗
      const idealRemaining = Math.max(0, totalBudget * (1 - i / daysInMonth))
      idealBurndown.push(Math.round(idealRemaining))

      // 实际燃尽：根据当前日期显示
      if (i <= currentDay && totalBudget > 0) {
        const actualRemaining = Math.max(0, totalBudget - (currentExpense * i / currentDay))
        actualBurndown.push(Math.round(actualRemaining))
      } else {
        actualBurndown.push(null)
      }
    } else {
      // 收入：积累图（向上走）
      // 理想积累：每天均匀积累
      const idealAccumulated = Math.min(totalBudget, totalBudget * (i / daysInMonth))
      idealBurndown.push(Math.round(idealAccumulated))

      // 实际积累：根据当前日期显示
      if (i <= currentDay && totalBudget > 0) {
        const actualAccumulated = Math.min(totalBudget, currentExpense * i / currentDay)
        actualBurndown.push(Math.round(actualAccumulated))
      } else {
        actualBurndown.push(null)
      }
    }
  }

  const textColor = getCssVar('--van-text-color')
  const textColor2 = getCssVar('--van-text-color-2')
  const splitLineColor = getCssVar('--chart-split')
  const axisLabelColor = getCssVar('--chart-text-muted')

  const idealSeriesName = isExpense ? '理想燃尽' : '理想积累'
  const actualSeriesName = isExpense ? '实际燃尽' : '实际积累'

  const option = {
    grid: {
      left: '3%',
      right: '8%',
      bottom: '3%',
      top: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: dates,
      axisLabel: {
        color: axisLabelColor,
        interval: Math.ceil(daysInMonth / 8) - 1,
        rotate: 45
      },
      splitLine: { show: false },
      axisLine: {
        lineStyle: {
          color: splitLineColor
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        color: axisLabelColor,
        formatter: (value) => {
          if (value >= 10000) { return (value / 10000).toFixed(0) + 'w' }
          return value
        }
      },
      splitLine: {
        lineStyle: {
          type: 'dashed',
          color: splitLineColor
        }
      }
    },
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        let result = params[0].name + '<br/>'
        params.forEach(param => {
          if (param.value !== null) {
            result += param.marker + param.seriesName + ': ¥' + (param.value >= 10000 ? (param.value / 10000).toFixed(1) + 'w' : param.value) + '<br/>'
          }
        })
        return result
      }
    },
    series: [
      {
        name: idealSeriesName,
        type: 'line',
        data: idealBurndown,
        smooth: false,
        lineStyle: {
          color: getCssVar('--chart-warning'),
          width: 2,
          type: 'dashed'
        },
        itemStyle: {
          color: getCssVar('--chart-warning')
        },
        z: 1
      },
      {
        name: actualSeriesName,
        type: 'line',
        data: actualBurndown,
        smooth: false,
        lineStyle: {
          color: getCssVar('--chart-primary'),
          width: 2
        },
        itemStyle: {
          color: getCssVar('--chart-primary')
        },
        z: 2
      }
    ]
  }

  burndownChart.setOption(option)
}

const updateYearBurndownChart = () => {
  if (!yearBurndownChart) { return }

  // 获取当前年份的日期
  const today = new Date()
  const year = today.getFullYear()
  const currentMonth = today.getMonth()
  const currentDay = today.getDate()
  const daysInCurrentMonth = new Date(year, currentMonth + 1, 0).getDate()
  const isExpense = props.activeTab === BudgetCategory.Expense

  // 生成月份和理想燃尽线/积累线
  const months = []
  const idealBurndown = []
  const actualBurndown = []

  const totalBudget = props.overallStats.year.limit || 0
  const currentExpense = props.overallStats.year.current || 0

  for (let i = 0; i < 12; i++) {
    months.push(`${i + 1}月`)

    // 计算当前时间进度（基于天数）
    let daysPassedInYear = 0
    let daysInYear = 0

    for (let j = 0; j < i; j++) {
      daysInYear += new Date(year, j + 1, 0).getDate()
    }

    if (i < currentMonth) {
      // 之前的月份都已完成
      daysPassedInYear = daysInYear + new Date(year, i + 1, 0).getDate()
    } else if (i === currentMonth) {
      // 当前月份
      daysPassedInYear = daysInYear + currentDay
      daysInYear += daysInCurrentMonth
    } else {
      // 未来的月份
      daysInYear += new Date(year, i + 1, 0).getDate()
    }

    // 全年总天数（365或366）
    const daysInYearTotal = new Date(year, 12, 0).getDate() === 29 ? 366 : 365
    const yearProgress = i === 11 ? 1 : daysPassedInYear / daysInYearTotal

    if (isExpense) {
      // 支出：燃尽图（向下走）
      // 理想燃尽：每月均匀消耗
      const idealRemaining = Math.max(0, totalBudget * (1 - (i + 1) / 12))
      idealBurndown.push(Math.round(idealRemaining))

      // 实际燃尽：根据当前日期显示
      if ((i < currentMonth || (i === currentMonth && currentDay > 0)) && totalBudget > 0) {
        const actualRemaining = Math.max(0, totalBudget - (currentExpense * yearProgress))
        actualBurndown.push(Math.round(actualRemaining))
      } else {
        actualBurndown.push(null)
      }
    } else {
      // 收入：积累图（向上走）
      // 理想积累：每月均匀积累
      const idealAccumulated = Math.min(totalBudget, totalBudget * ((i + 1) / 12))
      idealBurndown.push(Math.round(idealAccumulated))

      // 实际积累：根据当前日期显示
      if ((i < currentMonth || (i === currentMonth && currentDay > 0)) && totalBudget > 0) {
        const actualAccumulated = Math.min(totalBudget, currentExpense * yearProgress)
        actualBurndown.push(Math.round(actualAccumulated))
      } else {
        actualBurndown.push(null)
      }
    }
  }

  const textColor = getCssVar('--van-text-color')
  const textColor2 = getCssVar('--van-text-color-2')
  const splitLineColor = getCssVar('--chart-split')
  const axisLabelColor = getCssVar('--chart-text-muted')

  const idealSeriesName = isExpense ? '理想燃尽' : '理想积累'
  const actualSeriesName = isExpense ? '实际燃尽' : '实际积累'

  const option = {
    grid: {
      left: '3%',
      right: '8%',
      bottom: '3%',
      top: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: months,
      axisLabel: {
        color: axisLabelColor
      },
      splitLine: { show: false },
      axisLine: {
        lineStyle: {
          color: splitLineColor
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        color: axisLabelColor,
        formatter: (value) => {
          if (value >= 10000) { return (value / 10000).toFixed(0) + 'w' }
          return value
        }
      },
      splitLine: {
        lineStyle: {
          type: 'dashed',
          color: splitLineColor
        }
      }
    },
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        let result = params[0].name + '<br/>'
        params.forEach(param => {
          if (param.value !== null) {
            result += param.marker + param.seriesName + ': ¥' + (param.value >= 10000 ? (param.value / 10000).toFixed(1) + 'w' : param.value) + '<br/>'
          }
        })
        return result
      }
    },
    series: [
      {
        name: idealSeriesName,
        type: 'line',
        data: idealBurndown,
        smooth: false,
        lineStyle: {
          color: getCssVar('--chart-warning'),
          width: 2,
          type: 'dashed'
        },
        itemStyle: {
          color: getCssVar('--chart-warning')
        },
        z: 1
      },
      {
        name: actualSeriesName,
        type: 'line',
        data: actualBurndown,
        smooth: false,
        lineStyle: {
          color: getCssVar('--chart-primary'),
          width: 2
        },
        itemStyle: {
          color: getCssVar('--chart-primary')
        },
        z: 2
      }
    ]
  }

  yearBurndownChart.setOption(option)
}

const updateVarianceChart = () => {
  if (!varianceChart) { return }

  // 1. 准备数据：计算偏差 (Current - Limit)
  // 只关注本年和本月的预算，或者只展示本年？或者全部？
  // 按照设计，展示所有预算项的偏差
  // 为了避免混淆，我们可以合并月度和年度，或者只展示月度？
  // 用户的图表1和2是分开月度和年度的。
  // 偏差分析通常用于当前执行周期。如果混合了月度和年度，数值差异会很大（年度偏差可能几千，月度几百）。
  // 建议：优先展示月度预算的偏差，因为这是最高频关注点。或者提供选项？
  // 简单起见，这里展示“月度预算”的偏差。如果用户切到“收入”，则展示收入预算的偏差。

  // 过滤出月度预算
  const relevantBudgets = props.budgets // .filter(b => b.type === 1) // 1 = Month
  if (relevantBudgets.length === 0) {
    // 如果没有月度预算，尝试年度？不，保持一致性，只看月度。
    // 或者，我们可以把所有预算都放进去，但在名字上区分？
    // 让我们先只做月度，因为这是最直接的反馈。
  }

  // 计算偏差
  const data = relevantBudgets.map(b => {
    const limit = b.limit || 0
    const current = b.current || 0
    // 偏差 = 实际 - 预算
    // 对于支出：正数 = 超支 (Bad/Red), 负数 = 结余 (Good/Green)
    // 对于收入：正数 = 超额 (Good/Green?), 负数 = 差额 (Bad/Red?)
    // 但用户明确说：红条超支，绿条结余。这完全是支出视角。
    // 如果是收入 Tab，我们保持同样的逻辑：实际 > 目标 (Green), 实际 < 目标 (Red)
    // 为了适配用户的“红黑榜”视觉定义：
    // 右侧 (正值) -> 红色 (超支/Warning)
    // 左侧 (负值) -> 绿色 (结余/Safe)

    const diff = current - limit

    // 如果是收入，逻辑反转？
    // 收入：目标 10000，实际 12000。Diff +2000。这是好事。应该绿。
    // 收入：目标 10000，实际 8000。Diff -2000。这是坏事。应该红。
    // 所以收入时，我们把 Diff 取反？或者改变颜色映射？
    // 让我们先按“支出”逻辑写死，因为这是最常用的。

    return {
      name: b.name,
      value: diff,
      limit: limit,
      current: current
    }
  })

  // 排序：按偏差的绝对值降序排列
  data.sort((a, b) => Math.abs(b.value) - Math.abs(a.value))

  const categories = data.map(item => item.name)
  const values = data.map(item => item.value)

  const textColor = getCssVar('--van-text-color')
  const splitLineColor = getCssVar('--chart-split')
  const axisLabelColor = getCssVar('--chart-text-muted')

  const option = {
    grid: {
      left: '3%',
      right: '8%',
      bottom: '3%',
      top: '3%',
      containLabel: true
    },
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        const item = data[params[0].dataIndex]
        let html = `${item.name}<br/>`
        html += `预算: ¥${formatMoney(item.limit)}<br/>`
        html += `实际: ¥${formatMoney(item.current)}<br/>`
        const diffText = item.value > 0 ? `超支: ¥${formatMoney(item.value)}` : `结余: ¥${formatMoney(Math.abs(item.value))}`
        const color = item.value > 0 ? getCssVar('--van-danger-color') : getCssVar('--van-success-color')
        html += `<span style="color:${color};font-weight:bold">${diffText}</span>`
        return html
      }
    },
    xAxis: {
      type: 'value',
      position: 'top', // 坐标轴在上方，或者隐藏
      axisLine: { show: false },
      axisLabel: { show: false }, // 隐藏X轴标签，让图表更干净
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed',
          color: splitLineColor
        }
      }
    },
    yAxis: {
      type: 'category',
      axisTick: { show: false },
      axisLine: { show: false },
      data: categories,
      axisLabel: {
        color: textColor,
        width: 60,
        overflow: 'truncate'
      }
    },
    series: [
      {
        name: '偏差',
        type: 'bar',
        stack: 'Total',
        data: values,
        label: {
          show: true,
          position: 'right', // 默认右侧，正负值会自动调整吗？ECharts Bar label position logic:
          // For positive value: 'right', 'top', 'inside', etc.
          // We need dynamic position based on value sign.
          formatter: (params) => {
            const val = params.value
            return val > 0 ? `+${formatMoney(val)}` : formatMoney(val)
          },
          color: textColor
        },
        itemStyle: {
          borderRadius: 4,
          color: (params) => {
            const val = params.value
            if (props.activeTab === BudgetCategory.Expense) {
              // 支出：正数(超支)红，负数(结余)绿
              return val > 0 ? getCssVar('--van-danger-color') : getCssVar('--van-success-color')
            } else {
              // 收入：正数(超额)绿，负数(差额)红
              return val > 0 ? getCssVar('--van-success-color') : getCssVar('--van-danger-color')
            }
          }
        }
      }
    ]
  }

  // 针对 ECharts 的 label 位置优化：正数 label 在右，负数 label 在左
  // ECharts 5+ 支持 label position 为 function? 好像不支持。
  // 但我们可以通过 rich text 或 multiple series 来实现，或者简单地设为 'outside' (ECharts 没有 outside for bar?)
  // 对于 horizontal bar, positive value bar goes right, negative goes left.
  // label position 'right' means right of the bar end (for positive) and right of the bar end (for negative, which is inside towards 0).
  // ECharts default behavior:
  // If value > 0, bar extends right. Position 'right' is outside right.
  // If value < 0, bar extends left. Position 'right' is inside (near 0). Position 'left' is outside left.
  // Let's keep it simple first. Or use a callback if supported, or two series.
  // Actually, let's try just setting it based on logic if possible, but series config is static.
  // Better approach: use two series, one for positive, one for negative?
  // Or iterate data and set specific label position in data item.

  const seriesData = values.map((val, index) => {
    return {
      value: val,
      label: {
        position: val >= 0 ? 'right' : 'left'
      }
    }
  })

  option.series[0].data = seriesData

  varianceChart.setOption(option)
}

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()
    // 切换标签后延迟 resize，确保 DOM 已更新
    setTimeout(() => {
      burndownChart?.resize()
      yearBurndownChart?.resize()
      varianceChart?.resize()
    }, 100)
  })
})

// 监听展开/折叠状态
watch(() => monthBarChartExpanded.value, (expanded) => {
  if (expanded) {
    nextTick(() => {
      if (monthBarChartRef.value) {
        if (!monthBarChart) {
          monthBarChart = echarts.init(monthBarChartRef.value)
        }
        updateBarChart()
        monthBarChart.resize()
      }
    })
  } else {
    // 收起时销毁图表实例，释放内存
    if (monthBarChart) {
      monthBarChart.dispose()
      monthBarChart = null
    }
  }
})

watch(() => yearBarChartExpanded.value, (expanded) => {
  if (expanded) {
    nextTick(() => {
      if (yearBarChartRef.value) {
        if (!yearBarChart) {
          yearBarChart = echarts.init(yearBarChartRef.value)
        }
        updateBarChart()
        yearBarChart.resize()
      }
    })
  } else {
    // 收起时销毁图表实例，释放内存
    if (yearBarChart) {
      yearBarChart.dispose()
      yearBarChart = null
    }
  }
})

const handleResize = () => {
  monthGaugeChart?.resize()
  yearGaugeChart?.resize()
  monthBarChart?.resize()
  yearBarChart?.resize()
  burndownChart?.resize()
  yearBurndownChart?.resize()
  varianceChart?.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()

      // 初始化燃尽图/积累图
      if (burndownChartRef.value) {
        burndownChart = echarts.init(burndownChartRef.value)
        updateBurndownChart()
      }

      if (yearBurndownChartRef.value) {
        yearBurndownChart = echarts.init(yearBurndownChartRef.value)
        updateYearBurndownChart()
      }

      // 初始化偏差图
      if (varianceChartRef.value) {
        varianceChart = echarts.init(varianceChartRef.value)
        updateVarianceChart()
      }
    }
    window.addEventListener('resize', handleResize)
  })
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  monthGaugeChart?.dispose()
  yearGaugeChart?.dispose()
  monthBarChart?.dispose()
  yearBarChart?.dispose()
  burndownChart?.dispose()
  yearBurndownChart?.dispose()
  varianceChart?.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;
}

.burndown-chart {
  height: 200px;
}

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

.expand-toggle-row {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0;
}

.expand-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 4px 12px;
  border-radius: 6px;
  transition: background-color 0.2s ease;
  user-select: none;
}

.expand-toggle:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.expand-toggle:active {
  background-color: rgba(0, 0, 0, 0.1);
}

.expand-icon {
  display: inline-block;
  font-size: 12px;
  color: var(--van-text-color-2);
  transition: transform 0.2s ease;
  transform-origin: center;
}

.expand-icon.expanded {
  transform: rotate(180deg);
}

.expand-text {
  font-size: 12px;
  color: var(--van-text-color-2);
  transition: color 0.2s ease;
}

.expand-toggle:hover .expand-text {
  color: var(--van-text-color);
}
</style>