package tui

import (
	"fmt"
	"strings"
)

// View is PURE: Model → string. No side effects.
func View(model Model) string {
	switch model.Screen {
	case ScreenMain:
		return viewMain(model)
	case ScreenAgentList:
		return viewAgentList(model)
	case ScreenAgentActions:
		return viewAgentActions(model)
	case ScreenLogs:
		return viewLogs(model)
	case ScreenServer:
		return viewServer(model)
	case ScreenTests:
		return viewTests(model)
	case ScreenTestOutput:
		return viewTestOutput(model)
	default:
		return ""
	}
}

func viewMain(m Model) string {
	var b strings.Builder

	b.WriteString("\n  Bot Server Dashboard\n")
	b.WriteString("  " + strings.Repeat("─", 36) + "\n")

	// Summary
	running, stopped, disabled := countStatuses(m.Agents)
	total := len(m.Agents)
	if total > 0 {
		b.WriteString(fmt.Sprintf("  %d agents (%d running, %d stopped, %d disabled)\n\n",
			total, running, stopped, disabled))
	} else {
		b.WriteString("  Loading...\n\n")
	}

	// Menu
	for i, opt := range MainMenuOptions() {
		cursor := "  "
		if i == m.Cursor {
			cursor = "> "
		}
		b.WriteString(fmt.Sprintf("  %s%-16s %s\n", cursor, opt.Label, opt.Desc))
	}

	b.WriteString("\n  ↑↓ navegar  enter seleccionar  q salir\n")
	return b.String()
}

func viewAgentList(m Model) string {
	var b strings.Builder

	b.WriteString("\n  Agents\n")
	b.WriteString("  " + strings.Repeat("─", 60) + "\n")

	if len(m.Agents) == 0 {
		b.WriteString("  No agents found.\n")
	}

	for i, a := range m.Agents {
		cursor := "  "
		if i == m.Cursor {
			cursor = "> "
		}

		icon := "○"
		status := "stopped"
		if !a.Enabled {
			icon = " "
			status = "disabled"
		} else if a.Running {
			icon = "●"
			if a.Instances > 1 {
				status = fmt.Sprintf("running  %d instances", a.Instances)
			} else {
				status = fmt.Sprintf("running  PID %d", a.PID)
			}
		}

		b.WriteString(fmt.Sprintf("  %s%s %-20s %-8s %s\n",
			cursor, icon, a.ID, a.Version, status))
	}

	if m.StatusMsg != "" {
		b.WriteString("\n  " + m.StatusMsg + "\n")
	}

	b.WriteString("\n  ↑↓ navegar  enter acciones  0 volver\n")
	return b.String()
}

func viewAgentActions(m Model) string {
	var b strings.Builder

	if m.Selected == nil {
		return "  No agent selected.\n"
	}

	a := m.Selected
	var icon string
	switch {
	case !a.Enabled:
		icon = "  disabled"
	case a.Running:
		icon = "● enabled (running)"
	default:
		icon = "○ enabled (stopped)"
	}

	b.WriteString(fmt.Sprintf("\n  %s  %s\n", a.ID, icon))
	b.WriteString("  " + strings.Repeat("─", 44) + "\n")

	if a.Desc != "" {
		b.WriteString("  " + a.Desc + "\n")
	}

	b.WriteString("\n")

	opts := AgentActionOptions(a.Enabled)
	for i, opt := range opts {
		cursor := "  "
		if i == m.Cursor {
			cursor = "> "
		}
		b.WriteString(fmt.Sprintf("  %s%-16s %s\n", cursor, opt.Label, opt.Desc))
	}

	if m.StatusMsg != "" {
		b.WriteString("\n  " + m.StatusMsg + "\n")
	}

	b.WriteString("\n  ↑↓ navegar  enter ejecutar  0 volver\n")
	return b.String()
}

func viewLogs(m Model) string {
	var b strings.Builder

	agentID := "Launcher"
	if m.Selected != nil {
		agentID = m.Selected.ID
	}

	b.WriteString(fmt.Sprintf("\n  %s — Logs\n", agentID))
	b.WriteString("  " + strings.Repeat("─", 60) + "\n")

	if len(m.LogLines) == 0 {
		b.WriteString("  (no log data)\n")
	} else {
		visible := visibleLogLines(m)
		end := m.LogScroll + visible
		if end > len(m.LogLines) {
			end = len(m.LogLines)
		}
		start := m.LogScroll
		if start >= len(m.LogLines) {
			start = max(0, len(m.LogLines)-1)
		}
		for _, line := range m.LogLines[start:end] {
			// Truncate long lines
			if len(line) > m.WindowWidth-4 && m.WindowWidth > 10 {
				line = line[:m.WindowWidth-7] + "..."
			}
			b.WriteString("  " + line + "\n")
		}
	}

	b.WriteString("\n  ↑↓ scroll  r recargar  0 volver\n")
	return b.String()
}

func viewServer(m Model) string {
	var b strings.Builder

	b.WriteString("\n  Launcher Management\n")
	b.WriteString("  " + strings.Repeat("─", 44) + "\n")

	// Launcher status
	if m.LauncherRunning {
		b.WriteString(fmt.Sprintf("  ● Launcher running  PID %d\n", m.LauncherPID))
		parts := []string{}
		if m.LauncherUptime != "" {
			parts = append(parts, "uptime: "+m.LauncherUptime)
		}
		if m.LauncherMemory != "" {
			parts = append(parts, "mem: "+m.LauncherMemory)
		}
		if m.LauncherCPU != "" {
			parts = append(parts, "cpu: "+m.LauncherCPU)
		}
		if m.LauncherLogSize != "" {
			parts = append(parts, "log: "+m.LauncherLogSize)
		}
		if len(parts) > 0 {
			b.WriteString("  " + strings.Join(parts, "  ") + "\n")
		}
	} else {
		b.WriteString("  ○ Launcher stopped\n")
	}

	// Agent summary
	_, _, disabled := countStatuses(m.Agents)
	enabled := len(m.Agents) - disabled
	if len(m.Agents) > 0 {
		b.WriteString(fmt.Sprintf("\n  %d agents (%d enabled, %d disabled)\n", len(m.Agents), enabled, disabled))
		for _, a := range m.Agents {
			icon := "●"
			if !a.Enabled {
				icon = "○"
			}
			b.WriteString(fmt.Sprintf("  %s %s\n", icon, a.ID))
		}
	}

	b.WriteString("\n")

	// Action menu
	for i, opt := range ServerMenuOptions(m.LauncherRunning) {
		cursor := "  "
		if i == m.Cursor {
			cursor = "> "
		}
		b.WriteString(fmt.Sprintf("  %s%-20s %s\n", cursor, opt.Label, opt.Desc))
	}

	if m.StatusMsg != "" {
		b.WriteString("\n  " + m.StatusMsg + "\n")
	}

	b.WriteString("\n  ↑↓ navegar  enter ejecutar  0 volver\n")
	return b.String()
}

func viewTests(m Model) string {
	var b strings.Builder

	b.WriteString("\n  Tests\n")
	b.WriteString("  " + strings.Repeat("─", 44) + "\n")

	for i, opt := range TestMenuOptions() {
		cursor := "  "
		if i == m.Cursor {
			cursor = "> "
		}
		b.WriteString(fmt.Sprintf("  %s%-22s %s\n", cursor, opt.Label, opt.Desc))
	}

	if m.LastTestKind != TestKindNone {
		b.WriteString(fmt.Sprintf("\n  Last run: %s", testKindLabel(m.LastTestKind)))
		if m.StatusMsg != "" && (strings.HasSuffix(m.StatusMsg, "PASSED") || strings.HasSuffix(m.StatusMsg, "FAILED")) {
			// Extract result from status
			if strings.HasSuffix(m.StatusMsg, "PASSED") {
				b.WriteString(" — PASSED")
			} else {
				b.WriteString(" — FAILED")
			}
		}
		b.WriteString("\n")
	}

	b.WriteString("\n  ↑↓ navegar  enter ejecutar  0 volver\n")
	return b.String()
}

func viewTestOutput(m Model) string {
	var b strings.Builder

	title := "Test Results"
	if m.LastTestKind != TestKindNone {
		title = "Test Results — " + testKindLabel(m.LastTestKind)
	}
	b.WriteString("\n  " + title + "\n")
	b.WriteString("  " + strings.Repeat("─", 60) + "\n")

	if m.StatusMsg != "" {
		b.WriteString("  " + m.StatusMsg + "\n\n")
	}

	if len(m.LogLines) == 0 {
		b.WriteString("  Running tests...\n")
	} else {
		visible := visibleLogLines(m)
		end := m.LogScroll + visible
		if end > len(m.LogLines) {
			end = len(m.LogLines)
		}
		start := m.LogScroll
		if start >= len(m.LogLines) {
			start = max(0, len(m.LogLines)-1)
		}
		for _, line := range m.LogLines[start:end] {
			if len(line) > m.WindowWidth-4 && m.WindowWidth > 10 {
				line = line[:m.WindowWidth-7] + "..."
			}
			b.WriteString("  " + line + "\n")
		}
	}

	b.WriteString("\n  ↑↓ scroll  r re-ejecutar  0 volver\n")
	return b.String()
}

func countStatuses(agents []AgentView) (running, stopped, disabled int) {
	for _, a := range agents {
		switch {
		case !a.Enabled:
			disabled++
		case a.Running:
			running++
		default:
			stopped++
		}
	}
	return
}
