package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	tea "github.com/charmbracelet/bubbletea"
)

type DashboardModel struct {
	checks    []CheckResult
	cursor    int
	maxCursor int
	output    string
	width     int
}

func NewDashboardModel(checks []CheckResult) DashboardModel {
	return DashboardModel{
		checks:    checks,
		maxCursor: 2,
	}
}

type checksDoneMsg struct {
	results []CheckResult
}

type launchResultMsg struct {
	err error
}

type validateResultMsg struct {
	output string
	err    error
}

func runChecksCmd() tea.Cmd {
	return func() tea.Msg {
		return checksDoneMsg{results: RunChecks()}
	}
}

func launchOpencodeCmd() tea.Cmd {
	home, _ := os.UserHomeDir()
	wrapper := filepath.Join(home, ".local", "bin", "opencode")
	cmd := exec.Command(wrapper)
	return tea.ExecProcess(cmd, func(err error) tea.Msg {
		return launchResultMsg{err: err}
	})
}

func validateProfileCmd() tea.Cmd {
	return func() tea.Msg {
		cmd := exec.Command("nono", "profile", "validate", "opencode-tinfoil")
		out, err := cmd.CombinedOutput()
		return validateResultMsg{output: strings.TrimSpace(string(out)), err: err}
	}
}

func (m DashboardModel) Update(msg tea.Msg) (DashboardModel, tea.Cmd) {
	switch msg := msg.(type) {
	case checksDoneMsg:
		m.checks = msg.results
		return m, nil
	case launchResultMsg:
		if msg.err != nil {
			m.output = fmt.Sprintf("Launch failed: %v", msg.err)
		} else {
			m.output = "opencode exited normally"
		}
		return m, nil
	case validateResultMsg:
		if msg.err != nil {
			m.output = "Validation: " + msg.output
		} else {
			m.output = "Validation OK: " + msg.output
		}
		return m, nil
	case tea.KeyMsg:
		switch msg.String() {
		case "up", "k":
			if m.cursor > 0 {
				m.cursor--
			}
		case "down", "j":
			if m.cursor < m.maxCursor {
				m.cursor++
			}
		case "l":
			if m.cursor == 0 {
				return m, launchOpencodeCmd()
			}
		case "v":
			if m.cursor == 1 {
				return m, validateProfileCmd()
			}
		case "r":
			m.output = "Refreshing..."
			return m, runChecksCmd()
		}
	}
	return m, nil
}

func (m DashboardModel) View() string {
	var b strings.Builder

	b.WriteString("Dashboard\n\n")

	for _, check := range m.checks {
		var icon string
		style := checkOKStyle
		if check.Status == StatusOK {
			icon = "✓"
		} else {
			icon = "✗"
			style = checkFailStyle
		}
		b.WriteString(fmt.Sprintf("  %s  %s  %s\n",
			style.Render(icon),
			labelStyle.Render(check.Label),
			detailStyle.Render(check.Detail),
		))
	}

	b.WriteString("\n")

	actions := []string{"Launch opencode in sandbox", "Validate profile", "Refresh checks"}
	for i, action := range actions {
		cursor := "  "
		if i == m.cursor {
			cursor = cursorStyle.Render("> ")
		}
		b.WriteString(fmt.Sprintf("%s%s\n", cursor, action))
	}

	if m.output != "" {
		b.WriteString("\n" + detailStyle.Render(m.output))
	}

	b.WriteString("\n\n" + helpStyle.Render("  l:launch  v:validate  r:refresh  Tab:editor"))

	return b.String()
}
