package tui

import (
	"fmt"

	"rmm-hunter/internal/suspicious"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

// RequestEliminateMsg is emitted by the detail view when '!' is pressed
type RequestEliminateMsg struct {
	TypeKey string
	Index   int
}

// DeletedMsg is emitted after successful elimination to update lists
type DeletedMsg struct {
	TypeKey string
	Index   int
}

type DetailViewModel struct {
	typeKey    string
	index      int
	data       suspicious.Suspicious
	eliminated map[string]map[int]bool
	// When modal* != "", show modal and require ESC to dismiss
	modalErr  string
	modalWarn string
}

func NewDetailView(typeKey string, index int, data suspicious.Suspicious, eliminated map[string]map[int]bool) DetailViewModel {
	return DetailViewModel{typeKey: typeKey, index: index, data: data, eliminated: eliminated}
}

func (m DetailViewModel) Init() tea.Cmd { return nil }

func (m DetailViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch v := msg.(type) {
	case tea.KeyMsg:
		if m.modalErr != "" || m.modalWarn != "" {
			// Modal active: only ESC dismisses
			if v.String() == "esc" {
				m.modalErr = ""
				m.modalWarn = ""
			}
			return m, nil
		}
		switch v.String() {
		case "left":
			return m, func() tea.Msg { return BackMsg{} }
		case "!":
			return m, func() tea.Msg { return RequestEliminateMsg{TypeKey: m.typeKey, Index: m.index} }
		case "q", "esc", "ctrl+c":
			return m, tea.Quit
		}
	}
	return m, nil
}

func (m DetailViewModel) View() string {
	isEliminated := m.eliminated[m.typeKey] != nil && m.eliminated[m.typeKey][m.index]

	var title string
	if isEliminated {
		title = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("10")).Render("Details — ELIMINATED — Left to go back, q to quit")
	} else {
		title = lipgloss.NewStyle().Bold(true).Render("Details — press ! to eliminate, Left to go back, q to quit")
	}

	body := m.renderDetails()

	// Apply green styling to body if eliminated
	if isEliminated {
		body = lipgloss.NewStyle().Foreground(lipgloss.Color("10")).Render(body)
	}

	view := title + "\n\n" + body
	if m.modalWarn != "" {
		modal := lipgloss.NewStyle().Padding(1, 2).Foreground(lipgloss.Color("214")).Border(lipgloss.RoundedBorder()).Render("Warning:\n" + m.modalWarn + "\n\nPress ESC to dismiss")
		view += "\n\n" + modal
	}
	if m.modalErr != "" {
		modal := lipgloss.NewStyle().Padding(1, 2).Foreground(lipgloss.Color("203")).Border(lipgloss.RoundedBorder()).Render("Elimination failed:\n" + m.modalErr + "\n\nPress ESC to dismiss")
		view += "\n\n" + modal
	}
	return view
}

func (m DetailViewModel) renderDetails() string {
	switch m.typeKey {
	case "autoruns":
		if m.index >= len(m.data.AutoRuns) {
			return "Item no longer available"
		}
		ar := m.data.AutoRuns[m.index]
		return fmt.Sprintf("Type: %s\nEntry: %s\nLaunch: %s\nLocation: %s\nImage: %s\nArgs: %s\nMD5: %s\nSHA1: %s\nSHA256: %s", ar.Type, ar.Entry, ar.LaunchString, ar.Location, ar.ImagePath, ar.Arguments, ar.MD5, ar.SHA1, ar.SHA256)
	case "binaries":
		if m.index >= len(m.data.Binaries) {
			return "Item no longer available"
		}
		b := m.data.Binaries[m.index]
		return fmt.Sprintf("Binary: %s\nAction: delete file", b.Path)
	case "connections":
		if m.index >= len(m.data.OutboundConnections) {
			return "Item no longer available"
		}
		c := m.data.OutboundConnections[m.index]
		return fmt.Sprintf("Local: %s\nRemote: %s\nHost: %s\nState: %s\nPID: %s\nProcess: %s\nAction: add firewall block", c.LocalAddr, c.RemoteAddr, c.RemoteHost, c.State, c.PID, c.Process)
	case "directories":
		if m.index >= len(m.data.Directories) {
			return "Item no longer available"
		}
		d := m.data.Directories[m.index]
		return fmt.Sprintf("Directory: %s\nAction: delete recursively", d.Path)
	case "processes":
		if m.index >= len(m.data.Processes) {
			return "Item no longer available"
		}
		p := m.data.Processes[m.index]
		return fmt.Sprintf("Name: %s\nPID: %d\nPPID: %d\nParent: %s\nArgs: %s\nCreated: %s\nPath: %s\nAction: stop then delete", p.Name, p.PID, p.PPID, p.Parent, p.Args, p.Created, p.Path)
	case "scheduledTasks":
		if m.index >= len(m.data.ScheduledTasks) {
			return "Item no longer available"
		}
		t := m.data.ScheduledTasks[m.index]
		return fmt.Sprintf("Name: %s\nAuthor: %s\nState: %s\nEnabled: %v\nLastResult: %s\nNextRun: %s\nLastRun: %s\nPath: %s\nAction: disable then delete", t.Name, t.Author, t.State, t.Enabled, t.LastResult, t.NextRun, t.LastRun, t.Path)
	case "services":
		if m.index >= len(m.data.Services) {
			return "Item no longer available"
		}
		s := m.data.Services[m.index]
		return fmt.Sprintf("Name: %s\nDisplay: %s\nType: %s\nStartType: %s\nBinPath: %s\nStartName: %s\nDescription: %s\nAction: stop then delete", s.Name, s.DisplayName, s.ServiceType, s.StartType, s.BinaryPathName, s.ServiceStartName, s.Description)
	}
	return ""
}
