package graph

import (
	"image/color"
	"math"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
)

func clamp01(v float64) float64 {
	if v < 0 {
		return 0
	}
	if v > 1 {
		return 1
	}
	return v
}

func normalize(v, max float64) float64 {
	if max <= 0 {
		return 0
	}
	return clamp01(v / max)
}

// DrawSparkline draws a simple single-series sparkline (values assumed 0..maxValue).
// Returns nil if there isn't enough data to render.
func DrawSparkline(data []float64, width, height float32, maxValue float64) *fyne.Container {
	if len(data) < 2 {
		return nil
	}
	if maxValue <= 0 {
		maxValue = 100
	}

	lines := make([]fyne.CanvasObject, 0, len(data)-1)

	for i := 1; i < len(data); i++ {
		x1 := float32(i-1) * (width / float32(len(data)-1))
		x2 := float32(i) * (width / float32(len(data)-1))

		y1 := height - float32(normalize(data[i-1], maxValue))*height
		y2 := height - float32(normalize(data[i], maxValue))*height

		line := canvas.NewLine(color.NRGBA{R: 153, G: 0, B: 0, A: 255})
		line.StrokeWidth = 2
		line.Position1 = fyne.Position{X: x1, Y: y1}
		line.Position2 = fyne.Position{X: x2, Y: y2}

		lines = append(lines, line)
	}

	return fyne.NewContainerWithoutLayout(lines...)
}

// DrawDualSparkline overlays two series in the same plot.
// seriesA uses Sith red. seriesB uses a cyan-ish accent.
// maxValueA/maxValueB allow independent scaling; if <=0, auto-scale by max of series (with floor).
func DrawDualSparkline(seriesA, seriesB []float64, width, height float32, maxValueA, maxValueB float64) *fyne.Container {
	n := int(math.Min(float64(len(seriesA)), float64(len(seriesB))))
	if n < 2 {
		return nil
	}
	a := seriesA[:n]
	b := seriesB[:n]

	if maxValueA <= 0 {
		maxValueA = 1
		for _, v := range a {
			if v > maxValueA {
				maxValueA = v
			}
		}
	}
	if maxValueB <= 0 {
		maxValueB = 1
		for _, v := range b {
			if v > maxValueB {
				maxValueB = v
			}
		}
	}

	objs := make([]fyne.CanvasObject, 0, (n-1)*2)

	// A
	for i := 1; i < n; i++ {
		x1 := float32(i-1) * (width / float32(n-1))
		x2 := float32(i) * (width / float32(n-1))

		y1 := height - float32(normalize(a[i-1], maxValueA))*height
		y2 := height - float32(normalize(a[i], maxValueA))*height

		line := canvas.NewLine(color.NRGBA{R: 153, G: 0, B: 0, A: 255})
		line.StrokeWidth = 2
		line.Position1 = fyne.Position{X: x1, Y: y1}
		line.Position2 = fyne.Position{X: x2, Y: y2}
		objs = append(objs, line)
	}

	// B
	for i := 1; i < n; i++ {
		x1 := float32(i-1) * (width / float32(n-1))
		x2 := float32(i) * (width / float32(n-1))

		y1 := height - float32(normalize(b[i-1], maxValueB))*height
		y2 := height - float32(normalize(b[i], maxValueB))*height

		line := canvas.NewLine(color.NRGBA{R: 0, G: 255, B: 198, A: 200})
		line.StrokeWidth = 2
		line.Position1 = fyne.Position{X: x1, Y: y1}
		line.Position2 = fyne.Position{X: x2, Y: y2}
		objs = append(objs, line)
	}

	return fyne.NewContainerWithoutLayout(objs...)
}
