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"
)

// StatusScreen displays system status overview
type StatusScreen struct{}

// NewStatusScreen creates a new status screen
func NewStatusScreen() *StatusScreen {
	return &StatusScreen{}
}

// Name returns the screen name
func (s *StatusScreen) Name() string {
	return "System Status"
}

// Render renders the status screen
func (s *StatusScreen) Render(canvas *layout.Canvas, info *statcollector.SystemInfo) error {
	// Use consistent font size for entire screen
	const fontSize = 16

	// Colors
	textColor := color.RGBA{255, 255, 255, 255}
	dimColor := color.RGBA{150, 150, 150, 255}

	// Styles
	normalStyle := layout.TextStyle{Size: fontSize, Color: textColor}
	dimStyle := layout.TextStyle{Size: fontSize, Color: dimColor}

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

	// Starting Y position (after header)
	y := 150

	// Title
	titleText := fmt.Sprintf("%s: system status", shortHostname)
	_ = canvas.DrawText(titleText, layout.Point{X: 16, Y: y}, normalStyle)
	y += 40

	// CPU section
	cpuLabel := fmt.Sprintf("CPU:                        %.1f%% average across %d cores",
		getAverageCPU(info.CPUPercent), len(info.CPUPercent))
	_ = canvas.DrawText(cpuLabel, layout.Point{X: 16, Y: y}, normalStyle)
	y += 25

	// CPU progress bar
	_ = canvas.DrawText("0%", layout.Point{X: 100, Y: y}, dimStyle)
	drawProgressBar(canvas, 130, y-10, getAverageCPU(info.CPUPercent)/100.0, textColor)
	_ = canvas.DrawText("100%", layout.Point{X: 985, Y: y}, dimStyle)
	y += 40

	// Memory section
	memUsedPercent := float64(info.MemoryUsed) / float64(info.MemoryTotal) * 100.0
	memLabel := fmt.Sprintf("MEMORY:                         %s of %s (%.1f%%)",
		layout.FormatBytes(info.MemoryUsed),
		layout.FormatBytes(info.MemoryTotal),
		memUsedPercent)
	_ = canvas.DrawText(memLabel, layout.Point{X: 16, Y: y}, normalStyle)
	y += 25

	// Memory progress bar
	_ = canvas.DrawText("0B", layout.Point{X: 100, Y: y}, dimStyle)
	drawProgressBar(canvas, 130, y-10, float64(info.MemoryUsed)/float64(info.MemoryTotal), textColor)
	_ = canvas.DrawText(layout.FormatBytes(info.MemoryTotal), layout.Point{X: 985, Y: y}, dimStyle)
	y += 40

	// Temperature section
	if len(info.Temperature) > 0 {
		maxTemp, maxSensor := getMaxTemperature(info.Temperature)
		tempLabel := fmt.Sprintf("TEMPERATURE:                   %.1f°C (%s)", maxTemp, maxSensor)
		_ = canvas.DrawText(tempLabel, layout.Point{X: 16, Y: y}, normalStyle)
		y += 25

		// Temperature progress bar (30-99°C scale)
		_ = canvas.DrawText("30°C", layout.Point{X: 90, Y: y}, dimStyle)
		tempValue := (maxTemp - 30.0) / (99.0 - 30.0)
		if tempValue < 0 {
			tempValue = 0
		}
		if tempValue > 1 {
			tempValue = 1
		}
		drawProgressBar(canvas, 130, y-10, tempValue, textColor)
		_ = canvas.DrawText("99°C", layout.Point{X: 985, Y: y}, dimStyle)
		y += 40
	}

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

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

		diskLabel := fmt.Sprintf(" * %-12s %s of %s (%.1f%%)",
			disk.Path,
			layout.FormatBytes(disk.Used),
			layout.FormatBytes(disk.Total),
			disk.UsedPercent)
		_ = canvas.DrawText(diskLabel, layout.Point{X: 16, Y: y}, normalStyle)

		// Disk progress bar
		_ = canvas.DrawText("0B", layout.Point{X: 470, Y: y}, dimStyle)
		drawDiskProgressBar(canvas, 500, y-10, disk.UsedPercent/100.0, textColor)
		_ = canvas.DrawText(layout.FormatBytes(disk.Total), layout.Point{X: 985, Y: y}, dimStyle)
		y += 30

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

	// Network section
	if len(info.Network) > 0 {
		y += 15
		_ = canvas.DrawText("NETWORK:", layout.Point{X: 16, Y: y}, normalStyle)
		y += 25

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

			// Get link speed for scaling (default to 1 Gbps if unknown)
			linkSpeed := net.LinkSpeed
			linkSpeedText := ""
			if linkSpeed == 0 {
				linkSpeed = 1000 * 1000 * 1000 // 1 Gbps in bits
				linkSpeedText = "1G link"
			} else {
				linkSpeedText = fmt.Sprintf("%s link", humanize.SI(float64(linkSpeed), "bit/s"))
			}

			// Upload rate
			upLabel := fmt.Sprintf("   ↑ %7s (%s)", net.FormatSentRate(), linkSpeedText)
			_ = canvas.DrawText(upLabel, layout.Point{X: 16, Y: y}, normalStyle)
			_ = canvas.DrawText("0 bit/s", layout.Point{X: 400, Y: y}, dimStyle)
			drawNetworkProgressBar(canvas, 500, y-10, float64(net.BitsSentRate)/float64(linkSpeed), textColor)
			_ = canvas.DrawText(humanize.SI(float64(linkSpeed), "bit/s"), layout.Point{X: 960, Y: y}, dimStyle)
			y += 25

			// Download rate
			downLabel := fmt.Sprintf("   ↓ %7s", net.FormatRecvRate())
			_ = canvas.DrawText(downLabel, layout.Point{X: 16, Y: y}, normalStyle)
			_ = canvas.DrawText("0 bit/s", layout.Point{X: 400, Y: y}, dimStyle)
			drawNetworkProgressBar(canvas, 500, y-10, float64(net.BitsRecvRate)/float64(linkSpeed), textColor)
			_ = canvas.DrawText(humanize.SI(float64(linkSpeed), "bit/s"), layout.Point{X: 960, Y: y}, dimStyle)
			y += 35

			if y > 900 {
				break
			}
		}
	}

	return nil
}

// drawProgressBar draws a progress bar matching the mockup style
func drawProgressBar(canvas *layout.Canvas, x, y int, value float64, color color.Color) {
	const barWidth = 850

	// Draw opening bracket
	_ = canvas.DrawText("[", layout.Point{X: x, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})

	// Calculate fill
	fillChars := int(value * 80)
	emptyChars := 80 - fillChars

	// Draw bar content
	barContent := strings.Repeat("█", fillChars) + strings.Repeat("▒", emptyChars)
	_ = canvas.DrawText(barContent, layout.Point{X: x + 10, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})

	// Draw closing bracket
	_ = canvas.DrawText("]", layout.Point{X: x + barWidth - 10, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})
}

// drawDiskProgressBar draws a smaller progress bar for disk usage
func drawDiskProgressBar(canvas *layout.Canvas, x, y int, value float64, color color.Color) {
	const barWidth = 480

	// Draw opening bracket
	_ = canvas.DrawText("[", layout.Point{X: x, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})

	// Calculate fill (50 chars total)
	fillChars := int(value * 50)
	emptyChars := 50 - fillChars

	// Draw bar content
	barContent := strings.Repeat("█", fillChars) + strings.Repeat("▒", emptyChars)
	_ = canvas.DrawText(barContent, layout.Point{X: x + 10, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})

	// Draw closing bracket
	_ = canvas.DrawText("]", layout.Point{X: x + barWidth - 10, Y: y + 15}, layout.TextStyle{Size: 16, Color: color})
}

// drawNetworkProgressBar draws a progress bar for network rates
func drawNetworkProgressBar(canvas *layout.Canvas, x, y int, value float64, color color.Color) {
	// Same as disk progress bar
	drawDiskProgressBar(canvas, x, y, value, color)
}

// getAverageCPU calculates average CPU usage across all cores
func getAverageCPU(cpuPercents []float64) float64 {
	if len(cpuPercents) == 0 {
		return 0
	}
	total := 0.0
	for _, cpu := range cpuPercents {
		total += cpu
	}
	return total / float64(len(cpuPercents))
}

// getMaxTemperature finds the highest temperature and its sensor name
func getMaxTemperature(temps map[string]float64) (float64, string) {
	maxTemp := 0.0
	maxSensor := ""
	for sensor, temp := range temps {
		if temp > maxTemp {
			maxTemp = temp
			maxSensor = sensor
		}
	}
	return maxTemp, maxSensor
}
