package ui

import (
	"fmt"
	"image/color"
	"sort"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
	"git.leaktechnologies.dev/stu/VideoTools/internal/benchmark"
	"git.leaktechnologies.dev/stu/VideoTools/internal/sysinfo"
)

// BuildBenchmarkProgressView creates the benchmark progress UI
func BuildBenchmarkProgressView(
	hwInfo sysinfo.HardwareInfo,
	onCancel func(),
	titleColor, bgColor, textColor color.Color,
) *BenchmarkProgressView {
	view := &BenchmarkProgressView{
		hwInfo:     hwInfo,
		titleColor: titleColor,
		bgColor:    bgColor,
		textColor:  textColor,
		onCancel:   onCancel,
	}
	view.build()
	return view
}

// BenchmarkProgressView shows real-time benchmark progress
type BenchmarkProgressView struct {
	hwInfo     sysinfo.HardwareInfo
	titleColor color.Color
	bgColor    color.Color
	textColor  color.Color
	onCancel   func()

	container    *fyne.Container
	statusLabel  *widget.Label
	progressBar  *widget.ProgressBar
	currentLabel *widget.Label
	resultsBox   *fyne.Container
	cancelBtn    *widget.Button
}

func (v *BenchmarkProgressView) build() {
	// Header
	title := canvas.NewText("ENCODER BENCHMARK", v.titleColor)
	title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
	title.TextSize = 24

	v.cancelBtn = widget.NewButton("Cancel", v.onCancel)
	v.cancelBtn.Importance = widget.DangerImportance

	header := container.NewBorder(
		nil, nil,
		nil,
		v.cancelBtn,
		container.NewCenter(title),
	)

	// Hardware info section
	hwInfoTitle := widget.NewLabel("System Hardware")
	hwInfoTitle.TextStyle = fyne.TextStyle{Bold: true}
	hwInfoTitle.Alignment = fyne.TextAlignCenter

	cpuLabel := widget.NewLabel(fmt.Sprintf("CPU: %s (%d cores @ %s)", v.hwInfo.CPU, v.hwInfo.CPUCores, v.hwInfo.CPUMHz))
	cpuLabel.Wrapping = fyne.TextWrapWord

	gpuLabel := widget.NewLabel(fmt.Sprintf("GPU: %s", v.hwInfo.GPU))
	gpuLabel.Wrapping = fyne.TextWrapWord

	ramLabel := widget.NewLabel(fmt.Sprintf("RAM: %s", v.hwInfo.RAM))

	driverLabel := widget.NewLabel(fmt.Sprintf("Driver: %s", v.hwInfo.GPUDriver))
	driverLabel.Wrapping = fyne.TextWrapWord

	hwCard := canvas.NewRectangle(color.RGBA{R: 34, G: 38, B: 48, A: 255})
	hwCard.CornerRadius = 8

	hwContent := container.NewVBox(
		hwInfoTitle,
		cpuLabel,
		gpuLabel,
		ramLabel,
		driverLabel,
	)

	hwInfoSection := container.NewPadded(
		container.NewMax(hwCard, hwContent),
	)

	// Status section
	v.statusLabel = widget.NewLabel("Initializing benchmark...")
	v.statusLabel.TextStyle = fyne.TextStyle{Bold: true}
	v.statusLabel.Alignment = fyne.TextAlignCenter

	v.progressBar = widget.NewProgressBar()
	v.progressBar.Min = 0
	v.progressBar.Max = 100

	v.currentLabel = widget.NewLabel("")
	v.currentLabel.Alignment = fyne.TextAlignCenter
	v.currentLabel.Wrapping = fyne.TextWrapWord

	statusSection := container.NewVBox(
		v.statusLabel,
		v.progressBar,
		v.currentLabel,
	)

	// Results section
	resultsTitle := widget.NewLabel("Results")
	resultsTitle.TextStyle = fyne.TextStyle{Bold: true}
	resultsTitle.Alignment = fyne.TextAlignCenter

	v.resultsBox = container.NewVBox()
	resultsScroll := container.NewVScroll(v.resultsBox)
	resultsScroll.SetMinSize(fyne.NewSize(0, 300))

	resultsSection := container.NewBorder(
		resultsTitle,
		nil, nil, nil,
		resultsScroll,
	)

	// Main layout
	body := container.NewBorder(
		header,
		nil, nil, nil,
		container.NewVBox(
			hwInfoSection,
			widget.NewSeparator(),
			statusSection,
			widget.NewSeparator(),
			resultsSection,
		),
	)

	v.container = container.NewPadded(body)
}

// GetContainer returns the main container
func (v *BenchmarkProgressView) GetContainer() *fyne.Container {
	return v.container
}

// UpdateProgress updates the progress bar and labels
func (v *BenchmarkProgressView) UpdateProgress(current, total int, encoder, preset string) {
	pct := (float64(current) / float64(total)) * 100 // Convert to 0-100 range
	fyne.CurrentApp().Driver().DoFromGoroutine(func() {
		v.progressBar.SetValue(pct)
		v.statusLabel.SetText(fmt.Sprintf("Testing encoder %d of %d", current, total))
		v.currentLabel.SetText(fmt.Sprintf("Testing: %s (preset: %s)", encoder, preset))
		v.progressBar.Refresh()
		v.statusLabel.Refresh()
		v.currentLabel.Refresh()
	}, false)
}

// AddResult adds a completed test result to the display
func (v *BenchmarkProgressView) AddResult(result benchmark.Result) {
	var statusColor color.Color
	var statusText string

	if result.Error != "" {
		statusColor = color.RGBA{R: 255, G: 68, B: 68, A: 255} // Red
		statusText = fmt.Sprintf("FAILED: %s", result.Error)
	} else {
		statusColor = color.RGBA{R: 76, G: 232, B: 112, A: 255} // Green
		statusText = fmt.Sprintf("%.1f FPS | %.1fs encoding time", result.FPS, result.EncodingTime)
	}

	// Status indicator
	statusRect := canvas.NewRectangle(statusColor)
	// statusRect.SetMinSize(fyne.NewSize(6, 0)) // Removed for flexible sizing

	// Encoder label
	encoderLabel := widget.NewLabel(fmt.Sprintf("%s (%s)", result.Encoder, result.Preset))
	encoderLabel.TextStyle = fyne.TextStyle{Bold: true}

	// Status label
	statusLabel := widget.NewLabel(statusText)
	statusLabel.Wrapping = fyne.TextWrapWord

	// Card content
	content := container.NewBorder(
		nil, nil,
		statusRect,
		nil,
		container.NewVBox(encoderLabel, statusLabel),
	)

	// Card background
	card := canvas.NewRectangle(v.bgColor)
	card.CornerRadius = 4

	item := container.NewPadded(
		container.NewMax(card, content),
	)

	fyne.CurrentApp().Driver().DoFromGoroutine(func() {
		v.resultsBox.Add(item)
		v.resultsBox.Refresh()
	}, false)
}

// SetComplete marks the benchmark as complete
func (v *BenchmarkProgressView) SetComplete() {
	fyne.CurrentApp().Driver().DoFromGoroutine(func() {
		v.statusLabel.SetText("Benchmark complete!")
		v.progressBar.SetValue(100.0)
		v.currentLabel.SetText("")
		v.cancelBtn.SetText("Close")
		v.statusLabel.Refresh()
		v.progressBar.Refresh()
		v.currentLabel.Refresh()
		v.cancelBtn.Refresh()
	}, false)
}

// BuildBenchmarkResultsView creates the final results/recommendation UI
func BuildBenchmarkResultsView(
	results []benchmark.Result,
	recommendation benchmark.Result,
	hwInfo sysinfo.HardwareInfo,
	onApply func(),
	onClose func(),
	titleColor, bgColor, textColor color.Color,
) fyne.CanvasObject {
	// Header
	title := canvas.NewText("BENCHMARK RESULTS", titleColor)
	title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
	title.TextSize = 24

	closeBtn := widget.NewButton("Close", onClose)
	closeBtn.Importance = widget.LowImportance

	header := container.NewBorder(
		nil, nil,
		nil,
		closeBtn,
		container.NewCenter(title),
	)

	// Hardware info section
	hwInfoTitle := widget.NewLabel("System Hardware")
	hwInfoTitle.TextStyle = fyne.TextStyle{Bold: true}
	hwInfoTitle.Alignment = fyne.TextAlignCenter

	cpuLabel := widget.NewLabel(fmt.Sprintf("CPU: %s (%d cores @ %s)", hwInfo.CPU, hwInfo.CPUCores, hwInfo.CPUMHz))
	cpuLabel.Wrapping = fyne.TextWrapWord

	gpuLabel := widget.NewLabel(fmt.Sprintf("GPU: %s", hwInfo.GPU))
	gpuLabel.Wrapping = fyne.TextWrapWord

	ramLabel := widget.NewLabel(fmt.Sprintf("RAM: %s", hwInfo.RAM))

	driverLabel := widget.NewLabel(fmt.Sprintf("Driver: %s", hwInfo.GPUDriver))
	driverLabel.Wrapping = fyne.TextWrapWord

	hwCard := canvas.NewRectangle(color.RGBA{R: 34, G: 38, B: 48, A: 255})
	hwCard.CornerRadius = 8

	hwContent := container.NewVBox(
		hwInfoTitle,
		cpuLabel,
		gpuLabel,
		ramLabel,
		driverLabel,
	)

	hwInfoSection := container.NewPadded(
		container.NewMax(hwCard, hwContent),
	)

	// Recommendation section
	if recommendation.Encoder != "" {
		recTitle := widget.NewLabel("RECOMMENDED ENCODER")
		recTitle.TextStyle = fyne.TextStyle{Bold: true}
		recTitle.Alignment = fyne.TextAlignCenter

		recEncoder := widget.NewLabel(fmt.Sprintf("%s (preset: %s)", recommendation.Encoder, recommendation.Preset))
		recEncoder.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
		recEncoder.Alignment = fyne.TextAlignCenter

		recStats := widget.NewLabel(fmt.Sprintf("%.1f FPS | %.1fs encoding time | Score: %.1f",
			recommendation.FPS, recommendation.EncodingTime, recommendation.Score))
		recStats.Alignment = fyne.TextAlignCenter

		applyBtn := widget.NewButton("Apply to Settings", onApply)
		applyBtn.Importance = widget.HighImportance

		recCard := canvas.NewRectangle(color.RGBA{R: 68, G: 136, B: 255, A: 50})
		recCard.CornerRadius = 8

		recContent := container.NewVBox(
			recTitle,
			recEncoder,
			recStats,
			container.NewCenter(applyBtn),
		)

		recommendationSection := container.NewPadded(
			container.NewMax(recCard, recContent),
		)

		// Top results list
		topResultsTitle := widget.NewLabel("Top Encoders")
		topResultsTitle.TextStyle = fyne.TextStyle{Bold: true}
		topResultsTitle.Alignment = fyne.TextAlignCenter

		var filtered []benchmark.Result
		for _, result := range results {
			if result.Error == "" {
				filtered = append(filtered, result)
			}
		}

		sort.Slice(filtered, func(i, j int) bool {
			return filtered[i].Score > filtered[j].Score
		})

		var resultItems []fyne.CanvasObject
		for i, result := range filtered {
			rankLabel := widget.NewLabel(fmt.Sprintf("#%d", i+1))
			rankLabel.TextStyle = fyne.TextStyle{Bold: true}

			encoderLabel := widget.NewLabel(fmt.Sprintf("%s (%s)", result.Encoder, result.Preset))

			statsLabel := widget.NewLabel(fmt.Sprintf("%.1f FPS | %.1fs | Score: %.1f",
				result.FPS, result.EncodingTime, result.Score))
			statsLabel.TextStyle = fyne.TextStyle{Italic: true}

			content := container.NewBorder(
				nil, nil,
				rankLabel,
				nil,
				container.NewVBox(encoderLabel, statsLabel),
			)

			card := canvas.NewRectangle(bgColor)
			card.CornerRadius = 4

			item := container.NewPadded(
				container.NewMax(card, content),
			)

			resultItems = append(resultItems, item)
		}

		resultsBox := container.NewVBox(resultItems...)
		resultsScroll := container.NewVScroll(resultsBox)
		// resultsScroll.SetMinSize(fyne.NewSize(0, 300)) // Removed for flexible sizing

		resultsSection := container.NewBorder(
			topResultsTitle,
			nil, nil, nil,
			resultsScroll,
		)

		// Main layout
		body := container.NewBorder(
			header,
			nil, nil, nil,
			container.NewVBox(
				hwInfoSection,
				widget.NewSeparator(),
				recommendationSection,
				widget.NewSeparator(),
				resultsSection,
			),
		)

		return container.NewPadded(body)
	}

	// No results case
	emptyMsg := widget.NewLabel("No benchmark results available")
	emptyMsg.Alignment = fyne.TextAlignCenter

	body := container.NewBorder(
		header,
		nil, nil, nil,
		container.NewCenter(emptyMsg),
	)

	return container.NewPadded(body)
}

// BuildBenchmarkHistoryView creates the benchmark history browser UI
func BuildBenchmarkHistoryView(
	history []BenchmarkHistoryRun,
	onSelectRun func(int),
	onClose func(),
	titleColor, bgColor, textColor color.Color,
) fyne.CanvasObject {
	// Header
	title := canvas.NewText("BENCHMARK HISTORY", titleColor)
	title.TextStyle = fyne.TextStyle{Monospace: true, Bold: true}
	title.TextSize = 24

	closeBtn := widget.NewButton("← Back", onClose)
	closeBtn.Importance = widget.LowImportance

	header := container.NewBorder(
		nil, nil,
		closeBtn,
		nil,
		container.NewCenter(title),
	)

	if len(history) == 0 {
		emptyMsg := widget.NewLabel("No benchmark history yet.\n\nRun your first benchmark to see results here.")
		emptyMsg.Alignment = fyne.TextAlignCenter
		emptyMsg.Wrapping = fyne.TextWrapWord

		body := container.NewBorder(
			header,
			nil, nil, nil,
			container.NewCenter(emptyMsg),
		)

		return container.NewPadded(body)
	}

	// Build list of benchmark runs
	var runItems []fyne.CanvasObject
	for i, run := range history {
		idx := i // Capture for closure
		runItems = append(runItems, buildHistoryRunItem(run, idx, onSelectRun, bgColor, textColor))
	}

	runsList := container.NewVBox(runItems...)
	runsScroll := container.NewVScroll(runsList)
	// runsScroll.SetMinSize(fyne.NewSize(0, 400)) // Removed for flexible sizing

	infoLabel := widget.NewLabel("Click on a benchmark run to view detailed results")
	infoLabel.Alignment = fyne.TextAlignCenter
	infoLabel.TextStyle = fyne.TextStyle{Italic: true}

	body := container.NewBorder(
		header,
		container.NewVBox(widget.NewSeparator(), infoLabel),
		nil, nil,
		runsScroll,
	)

	return container.NewPadded(body)
}

// BenchmarkHistoryRun represents a benchmark run in the history view
type BenchmarkHistoryRun struct {
	Timestamp          string
	ResultCount        int
	RecommendedEncoder string
	RecommendedPreset  string
	RecommendedFPS     float64
}

func buildHistoryRunItem(
	run BenchmarkHistoryRun,
	index int,
	onSelect func(int),
	bgColor, textColor color.Color,
) fyne.CanvasObject {
	// Timestamp label
	timeLabel := widget.NewLabel(run.Timestamp)
	timeLabel.TextStyle = fyne.TextStyle{Bold: true}

	// Recommendation info
	recLabel := widget.NewLabel(fmt.Sprintf("Recommended: %s (%s) - %.1f FPS",
		run.RecommendedEncoder, run.RecommendedPreset, run.RecommendedFPS))

	// Result count
	countLabel := widget.NewLabel(fmt.Sprintf("%d encoders tested", run.ResultCount))
	countLabel.TextStyle = fyne.TextStyle{Italic: true}

	// Content
	content := container.NewVBox(
		timeLabel,
		recLabel,
		countLabel,
	)

	// Card background
	card := canvas.NewRectangle(bgColor)
	card.CornerRadius = 4

	item := container.NewPadded(
		container.NewMax(card, content),
	)

	// Make it tappable
	tappable := NewTappable(item, func() {
		onSelect(index)
	})

	return tappable
}
