package onelead

import (
	"bytes"
	"fmt"
	"odoki/constants"
	"odoki/ui/components"
	"odoki/utils"
	"strconv"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"

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

var buf = new(bytes.Buffer)
var LeadBuffer = [constants.ChannelCount][]int32{}
var heartRateLabel *widget.Label

func updateLeadChart() {
	buf = new(bytes.Buffer)
	fr, fg, fb, fa := theme.ForegroundColor().RGBA()
	br, bg, bb, ba := theme.BackgroundColor().RGBA()

	var xValues [constants.ChannelCount][]float64
	var yValues [constants.ChannelCount][]float64
	if len(LeadBuffer[0]) < 2 {
		for i := range LeadBuffer {
			xValues[i] = []float64{0, 1}
			yValues[i] = []float64{0, 1}
		}
	}
	for i, channel := range LeadBuffer {
		for j, sample := range channel {
			xValues[i] = append(xValues[i], float64(j)*float64(constants.BufferDuration)/float64(constants.BufferSize))
			yValues[i] = append(yValues[i], float64(sample)/float64(constants.LeadMaxBValue)*float64(constants.LeadMaxVValue))
		}
	}
	// Create a bar chart.
	graph := chart.Chart{
		//Title: "Measured Voltage (mV) vs Time (s)",
		Background: chart.Style{
			FillColor:   drawing.Color{R: uint8(br), G: uint8(bg), B: uint8(bb), A: uint8(ba)}, // will supercede defaults
			StrokeColor: drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
		},
		Canvas: chart.Style{
			FillColor:   drawing.Color{R: uint8(br), G: uint8(bg), B: uint8(bb), A: uint8(ba)},
			StrokeColor: drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
		},
		XAxis: chart.XAxis{
			Style: chart.Style{
				StrokeColor: drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				FillColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				DotColor:    drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			},
		},
		YAxis: chart.YAxis{
			Style: chart.Style{
				StrokeColor: drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				FillColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			},
		},
		TitleStyle: chart.Style{
			StrokeColor: drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			FillColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
			FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
		},
		Series: []chart.Series{
			chart.ContinuousSeries{
				Style: chart.Style{
					StrokeColor: constants.TraceColor,                                                  // will supercede defaults
					FontColor:   drawing.Color{R: uint8(fr), G: uint8(fg), B: uint8(fb), A: uint8(fa)}, // will supercede defaults
				},
				XValues: xValues[0],
				YValues: yValues[0],
			},
		},
	}

	// Render the bar chart to a byte array.

	err := graph.Render(chart.PNG, buf)
	utils.Must("render bar chart", err)
}

func updateLoop(cimage *canvas.Image) {
	k := 0
	for {
		time.Sleep(1 * time.Second)
		updateLeadChart()
		cimage.Resource = fyne.NewStaticResource("barChart", buf.Bytes())
		cimage.Refresh()
		fmt.Println("updateLoop")
		k++
	}
}

func UpdateHeartrate(heartRate uint8) {
	heartRateLabel.Text = strconv.Itoa(int(heartRate)) + " BPM"
	heartRateLabel.Refresh()
}

func Widget() fyne.CanvasObject {
	updateLeadChart()
	cimage := canvas.NewImageFromReader(buf, "barChart")
	cimage.FillMode = canvas.ImageFillOriginal
	go updateLoop(cimage)

	heartRateLabel = widget.NewLabel("-- BPM")

	return container.NewPadded(container.NewVBox(
		components.TabTitle("1 Lead"),
		heartRateLabel,
		container.New(layout.NewStackLayout(), cimage),
	))
}
