// Package renderer provides screen rendering implementations for hdmistat
package renderer

import (
	"fmt"
	"image/color"
	"strings"

	"git.eeqj.de/sneak/hdmistat/internal/layout"
	"git.eeqj.de/sneak/hdmistat/internal/statcollector"
	"github.com/dustin/go-humanize"
)

// OverviewScreen displays system overview
type OverviewScreen struct{}

// NewOverviewScreen creates a new overview screen renderer
func NewOverviewScreen() *OverviewScreen {
	return &OverviewScreen{}
}

// Name returns the name of this screen
func (s *OverviewScreen) Name() string {
	return "System Overview"
}

// Render draws the overview screen to the provided canvas
func (s *OverviewScreen) Render(canvas *layout.Canvas, info *statcollector.SystemInfo) error {
	_, _ = canvas.Size()

	// Colors
	textColor := color.RGBA{255, 255, 255, 255}
	headerColor := color.RGBA{100, 200, 255, 255}

	// Styles
	titleStyle := layout.TextStyle{Size: 48, Color: headerColor}
	headerStyle := layout.TextStyle{Size: 18, Color: headerColor, Bold: true}
	normalStyle := layout.TextStyle{Size: 18, Color: textColor}

	y := 120 // Start below header

	// Get short hostname
	shortHostname := info.Hostname
	if idx := strings.Index(shortHostname, "."); idx > 0 {
		shortHostname = shortHostname[:idx]
	}

	// Title - left aligned at consistent position
	titleText := fmt.Sprintf("%s: status", shortHostname)
	_ = canvas.DrawText(titleText, layout.Point{X: 50, Y: y}, layout.TextStyle{
		Size:      36, // Smaller than before
		Color:     titleStyle.Color,
		Alignment: layout.AlignLeft,
	})
	y += 60

	// Standard bar dimensions
	barWidth := 400
	barHeight := 20
	sectionSpacing := 60

	// CPU section
	_ = canvas.DrawText("CPU", layout.Point{X: 50, Y: y}, headerStyle)
	y += 30

	// Calculate average CPU usage
	totalCPU := 0.0
	for _, cpu := range info.CPUPercent {
		totalCPU += cpu
	}
	avgCPU := totalCPU / float64(len(info.CPUPercent))

	// Draw composite CPU bar below header
	cpuBar := &layout.ProgressBar{
		X: 50, Y: y,
		Width: barWidth, Height: barHeight,
		Value:      avgCPU / 100.0,
		Label:      fmt.Sprintf("%.1f%% average across %d cores", avgCPU, len(info.CPUPercent)),
		LeftLabel:  "0%",
		RightLabel: "100%",
		BarColor:   color.RGBA{255, 100, 100, 255},
	}
	cpuBar.Draw(canvas)
	y += sectionSpacing

	// Memory section
	_ = canvas.DrawText("MEMORY", layout.Point{X: 50, Y: y}, headerStyle)
	y += 30

	memUsedPercent := float64(info.MemoryUsed) / float64(info.MemoryTotal)
	memoryBar := &layout.ProgressBar{
		X: 50, Y: y,
		Width: barWidth, Height: barHeight,
		Value:      memUsedPercent,
		Label:      fmt.Sprintf("%s of %s", layout.FormatBytes(info.MemoryUsed), layout.FormatBytes(info.MemoryTotal)),
		LeftLabel:  "0B",
		RightLabel: layout.FormatBytes(info.MemoryTotal),
		BarColor:   color.RGBA{100, 200, 100, 255},
	}
	memoryBar.Draw(canvas)
	y += sectionSpacing

	// Temperature section
	if len(info.Temperature) > 0 {
		_ = canvas.DrawText("TEMPERATURE", layout.Point{X: 50, Y: y}, headerStyle)
		y += 30

		// Find the highest temperature
		maxTemp := 0.0
		maxSensor := ""
		for sensor, temp := range info.Temperature {
			if temp > maxTemp {
				maxTemp = temp
				maxSensor = sensor
			}
		}

		// Temperature scale from 30°C to 99°C
		tempValue := (maxTemp - 30.0) / (99.0 - 30.0)
		if tempValue < 0 {
			tempValue = 0
		}
		if tempValue > 1 {
			tempValue = 1
		}

		tempBar := &layout.ProgressBar{
			X: 50, Y: y,
			Width: barWidth, Height: barHeight,
			Value:      tempValue,
			Label:      fmt.Sprintf("%s: %.1f°C", maxSensor, maxTemp),
			LeftLabel:  "30°C",
			RightLabel: "99°C",
			BarColor:   color.RGBA{255, 150, 50, 255},
		}
		tempBar.Draw(canvas)
		y += sectionSpacing
	}

	// Disk usage section
	_ = canvas.DrawText("DISK USAGE", layout.Point{X: 50, Y: y}, headerStyle)
	y += 30

	for _, disk := range info.DiskUsage {
		// Skip snap disks
		if strings.HasPrefix(disk.Path, "/snap") {
			continue
		}

		diskBar := &layout.ProgressBar{
			X: 50, Y: y,
			Width: barWidth, Height: barHeight,
			Value:      disk.UsedPercent / 100.0,
			Label:      fmt.Sprintf("%s: %s of %s", disk.Path, layout.FormatBytes(disk.Used), layout.FormatBytes(disk.Total)),
			LeftLabel:  "0B",
			RightLabel: layout.FormatBytes(disk.Total),
			BarColor:   color.RGBA{200, 200, 100, 255},
		}
		diskBar.Draw(canvas)
		y += 40

		if y > 700 {
			break // Don't overflow the screen
		}
	}

	y += sectionSpacing

	// Network section
	if len(info.Network) > 0 {
		_ = canvas.DrawText("NETWORK", layout.Point{X: 50, Y: y}, headerStyle)
		y += 30

		for _, net := range info.Network {
			// Network interface info
			interfaceText := net.Name
			if len(net.IPAddresses) > 0 {
				interfaceText = fmt.Sprintf("%s (%s)", net.Name, net.IPAddresses[0])
			}
			_ = canvas.DrawText(interfaceText, layout.Point{X: 50, Y: y}, normalStyle)
			y += 25

			// Get link speed for scaling (default to 1 Gbps if unknown)
			linkSpeed := net.LinkSpeed
			if linkSpeed == 0 {
				linkSpeed = 1000 * 1000 * 1000 // 1 Gbps in bits
			}

			// TX rate bar
			txValue := float64(net.BitsSentRate) / float64(linkSpeed)
			txBar := &layout.ProgressBar{
				X: 50, Y: y,
				Width: barWidth/2 - 10, Height: barHeight,
				Value:      txValue,
				Label:      fmt.Sprintf("↑ %s", net.FormatSentRate()),
				LeftLabel:  "0",
				RightLabel: humanize.SI(float64(linkSpeed), "bit/s"),
				BarColor:   color.RGBA{100, 255, 100, 255},
			}
			txBar.Draw(canvas)

			// RX rate bar
			rxValue := float64(net.BitsRecvRate) / float64(linkSpeed)
			rxBar := &layout.ProgressBar{
				X: 50 + barWidth/2 + 10, Y: y,
				Width: barWidth/2 - 10, Height: barHeight,
				Value:      rxValue,
				Label:      fmt.Sprintf("↓ %s", net.FormatRecvRate()),
				LeftLabel:  "0",
				RightLabel: humanize.SI(float64(linkSpeed), "bit/s"),
				BarColor:   color.RGBA{100, 100, 255, 255},
			}
			rxBar.Draw(canvas)

			y += 60

			if y > 900 {
				break // Don't overflow the screen
			}
		}
	}

	return nil
}
