package renderer

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

	"git.eeqj.de/sneak/hdmistat/internal/layout"
	"git.eeqj.de/sneak/hdmistat/internal/statcollector"
)

const (
	// Display constants
	maxProcessNameLen = 30
	maxUsernameLen    = 12
	topProcessCount   = 20
	cpuHighThreshold  = 50.0
	memoryHighRatio   = 0.1
	percentMultiplier = 100.0
	halfDivisor       = 2
)

// ProcessScreen displays top processes
type ProcessScreen struct {
	SortBy string // "cpu" or "memory"
}

// NewProcessScreenCPU creates a new process screen sorted by CPU usage
func NewProcessScreenCPU() *ProcessScreen {
	return &ProcessScreen{SortBy: "cpu"}
}

// NewProcessScreenMemory creates a new process screen sorted by memory usage
func NewProcessScreenMemory() *ProcessScreen {
	return &ProcessScreen{SortBy: "memory"}
}

// Name returns the name of this screen
func (s *ProcessScreen) Name() string {
	if s.SortBy == "cpu" {
		return "Top Processes by CPU"
	}
	return "Top Processes by Memory"
}

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

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

	// Styles
	titleStyle := layout.TextStyle{Size: 36, Color: headerColor}
	headerStyle := layout.TextStyle{Size: 20, Color: headerColor}
	normalStyle := layout.TextStyle{Size: 16, Color: textColor}
	smallStyle := layout.TextStyle{Size: 14, Color: dimColor}

	y := 120 // Start below header - same as overview

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

	// Title - left aligned at consistent position
	titleText := ""
	if s.SortBy == "cpu" {
		titleText = fmt.Sprintf("%s: cpu", shortHostname)
	} else {
		titleText = fmt.Sprintf("%s: memory", shortHostname)
	}
	_ = canvas.DrawText(titleText, layout.Point{X: 50, Y: y}, layout.TextStyle{
		Size:      36, // Same size as overview
		Color:     titleStyle.Color,
		Alignment: layout.AlignLeft,
	})
	y += 60

	// Sort processes
	processes := make([]statcollector.ProcessInfo, len(info.Processes))
	copy(processes, info.Processes)

	if s.SortBy == "cpu" {
		sort.Slice(processes, func(i, j int) bool {
			return processes[i].CPUPercent > processes[j].CPUPercent
		})
	} else {
		sort.Slice(processes, func(i, j int) bool {
			return processes[i].MemoryRSS > processes[j].MemoryRSS
		})
	}

	// Table headers
	x := 50
	_ = canvas.DrawText("PID", layout.Point{X: x, Y: y}, headerStyle)
	_ = canvas.DrawText("USER", layout.Point{X: x + 100, Y: y}, headerStyle)
	_ = canvas.DrawText("PROCESS", layout.Point{X: x + 250, Y: y}, headerStyle)
	_ = canvas.DrawText("CPU %", layout.Point{X: x + 600, Y: y}, headerStyle)
	_ = canvas.DrawText("MEMORY", layout.Point{X: x + 700, Y: y}, headerStyle)

	y += 30
	canvas.DrawHLine(x, y, width-100, color.RGBA{100, 100, 100, 255})
	y += 20

	// Display top 20 processes
	for i, proc := range processes {
		if i >= topProcessCount {
			break
		}

		// Truncate long names
		name := proc.Name
		if len(name) > maxProcessNameLen {
			name = name[:maxProcessNameLen-3] + "..."
		}

		user := proc.Username
		if len(user) > maxUsernameLen {
			user = user[:maxUsernameLen-3] + "..."
		}

		// Highlight bar for high usage (draw BEFORE text)
		if s.SortBy == "cpu" && proc.CPUPercent > cpuHighThreshold {
			canvas.DrawBox(x-5, y-15, width-90, 20, color.RGBA{100, 50, 50, 100})
		} else if s.SortBy == "memory" && float64(proc.MemoryRSS)/float64(info.MemoryTotal) > memoryHighRatio {
			canvas.DrawBox(x-5, y-15, width-90, 20, color.RGBA{50, 50, 100, 100})
		}

		_ = canvas.DrawText(fmt.Sprintf("%d", proc.PID), layout.Point{X: x, Y: y}, normalStyle)
		_ = canvas.DrawText(user, layout.Point{X: x + 100, Y: y}, normalStyle)
		_ = canvas.DrawText(name, layout.Point{X: x + 250, Y: y}, normalStyle)
		_ = canvas.DrawText(fmt.Sprintf("%.1f", proc.CPUPercent), layout.Point{X: x + 600, Y: y}, normalStyle)
		_ = canvas.DrawText(layout.FormatBytes(proc.MemoryRSS), layout.Point{X: x + 700, Y: y}, normalStyle)

		y += 25
	}

	// Footer with system totals
	y = 950
	canvas.DrawHLine(50, y, width-100, color.RGBA{100, 100, 100, 255})
	y += 30

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

	footerText := fmt.Sprintf("System: CPU %.1f%% | Memory: %s / %s (%.1f%%)",
		avgCPU,
		layout.FormatBytes(info.MemoryUsed),
		layout.FormatBytes(info.MemoryTotal),
		float64(info.MemoryUsed)/float64(info.MemoryTotal)*percentMultiplier)

	_ = canvas.DrawText(footerText, layout.Point{X: width / halfDivisor, Y: y}, layout.TextStyle{
		Size:      smallStyle.Size,
		Color:     smallStyle.Color,
		Alignment: layout.AlignCenter,
	})

	return nil
}
