package chart

import (
	"bytes"
	"fmt"
	"math"

	"ops-assistant/internal/service"

	"github.com/wcharczuk/go-chart/v2"
	"github.com/wcharczuk/go-chart/v2/drawing"
)

// 分类对应的颜色
var categoryColors = []drawing.Color{
	{R: 255, G: 99, B: 132, A: 255},  // 红
	{R: 54, G: 162, B: 235, A: 255},   // 蓝
	{R: 255, G: 206, B: 86, A: 255},   // 黄
	{R: 75, G: 192, B: 192, A: 255},   // 青
	{R: 153, G: 102, B: 255, A: 255},  // 紫
	{R: 255, G: 159, B: 64, A: 255},   // 橙
	{R: 46, G: 204, B: 113, A: 255},   // 绿
	{R: 231, G: 76, B: 60, A: 255},    // 深红
	{R: 52, G: 73, B: 94, A: 255},     // 深蓝灰
	{R: 241, G: 196, B: 15, A: 255},   // 金
}

// GeneratePieChart 生成分类占比饼图
func GeneratePieChart(stats []service.CategoryStat, title string) ([]byte, error) {
	if len(stats) == 0 {
		return nil, fmt.Errorf("no data")
	}

	var total float64
	for _, s := range stats {
		total += float64(s.Total)
	}

	var values []chart.Value
	for i, s := range stats {
		yuan := float64(s.Total) / 100.0
		pct := float64(s.Total) / total * 100
		label := fmt.Sprintf("%s %.0f元(%.0f%%)", s.Category, yuan, pct)
		values = append(values, chart.Value{
			Value: yuan,
			Label: label,
			Style: chart.Style{
				FillColor:   categoryColors[i%len(categoryColors)],
				StrokeColor: drawing.ColorWhite,
				StrokeWidth: 2,
			},
		})
	}

	pie := chart.PieChart{
		Title:  title,
		Width:  600,
		Height: 500,
		TitleStyle: chart.Style{
			FontSize: 16,
		},
		Values: values,
	}

	buf := &bytes.Buffer{}
	if err := pie.Render(chart.PNG, buf); err != nil {
		return nil, fmt.Errorf("render pie chart: %w", err)
	}
	return buf.Bytes(), nil
}

// GenerateBarChart 生成每日消费柱状图
func GenerateBarChart(stats []service.DailyStat, title string) ([]byte, error) {
	if len(stats) == 0 {
		return nil, fmt.Errorf("no data")
	}

	var values []chart.Value
	var maxVal float64
	for _, s := range stats {
		yuan := float64(s.Total) / 100.0
		if yuan > maxVal {
			maxVal = yuan
		}
		// 日期只取 MM-DD
		dateLabel := s.Date
		if len(s.Date) > 5 {
			dateLabel = s.Date[5:]
		}
		values = append(values, chart.Value{
			Value: yuan,
			Label: dateLabel,
			Style: chart.Style{
				FillColor:   drawing.Color{R: 54, G: 162, B: 235, A: 255},
				StrokeColor: drawing.Color{R: 54, G: 162, B: 235, A: 255},
				StrokeWidth: 1,
			},
		})
	}

	bar := chart.BarChart{
		Title:  title,
		Width:  600,
		Height: 400,
		TitleStyle: chart.Style{
			FontSize: 16,
		},
		YAxis: chart.YAxis{
			Range: &chart.ContinuousRange{
				Min: 0,
				Max: math.Ceil(maxVal*1.2/10) * 10,
			},
			ValueFormatter: func(v interface{}) string {
				return fmt.Sprintf("%.0f", v)
			},
		},
		BarWidth: 40,
		Bars:     values,
	}

	buf := &bytes.Buffer{}
	if err := bar.Render(chart.PNG, buf); err != nil {
		return nil, fmt.Errorf("render bar chart: %w", err)
	}
	return buf.Bytes(), nil
}
