package quit

import (
	"github.com/charmbracelet/bubbles/v2/key"
	tea "github.com/charmbracelet/bubbletea/v2"
	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
	"github.com/charmbracelet/crush/internal/tui/styles"
	"github.com/charmbracelet/crush/internal/tui/util"
	"github.com/charmbracelet/lipgloss/v2"
)

const (
	question                      = "Are you sure you want to quit?"
	QuitDialogID dialogs.DialogID = "quit"
)

// QuitDialog represents a confirmation dialog for quitting the application.
type QuitDialog interface {
	dialogs.DialogModel
}

type quitDialogCmp struct {
	wWidth  int
	wHeight int

	selectedNo bool // true if "No" button is selected
	keymap     KeyMap
}

// NewQuitDialog creates a new quit confirmation dialog.
func NewQuitDialog() QuitDialog {
	return &quitDialogCmp{
		selectedNo: true, // Default to "No" for safety
		keymap:     DefaultKeymap(),
	}
}

func (q *quitDialogCmp) Init() tea.Cmd {
	return nil
}

// Update handles keyboard input for the quit dialog.
func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.WindowSizeMsg:
		q.wWidth = msg.Width
		q.wHeight = msg.Height
	case tea.KeyPressMsg:
		switch {
		case key.Matches(msg, q.keymap.LeftRight, q.keymap.Tab):
			q.selectedNo = !q.selectedNo
			return q, nil
		case key.Matches(msg, q.keymap.EnterSpace):
			if !q.selectedNo {
				return q, tea.Quit
			}
			return q, util.CmdHandler(dialogs.CloseDialogMsg{})
		case key.Matches(msg, q.keymap.Yes):
			return q, tea.Quit
		case key.Matches(msg, q.keymap.No, q.keymap.Close):
			return q, util.CmdHandler(dialogs.CloseDialogMsg{})
		}
	}
	return q, nil
}

// View renders the quit dialog with Yes/No buttons.
func (q *quitDialogCmp) View() string {
	t := styles.CurrentTheme()
	baseStyle := t.S().Base
	yesStyle := t.S().Text
	noStyle := yesStyle

	if q.selectedNo {
		noStyle = noStyle.Foreground(t.White).Background(t.Secondary)
		yesStyle = yesStyle.Background(t.BgSubtle)
	} else {
		yesStyle = yesStyle.Foreground(t.White).Background(t.Secondary)
		noStyle = noStyle.Background(t.BgSubtle)
	}

	const horizontalPadding = 3
	yesButton := yesStyle.PaddingLeft(horizontalPadding).Underline(true).Render("Y") +
		yesStyle.PaddingRight(horizontalPadding).Render("ep!")
	noButton := noStyle.PaddingLeft(horizontalPadding).Underline(true).Render("N") +
		noStyle.PaddingRight(horizontalPadding).Render("ope")

	buttons := baseStyle.Width(lipgloss.Width(question)).Align(lipgloss.Right).Render(
		lipgloss.JoinHorizontal(lipgloss.Center, yesButton, "  ", noButton),
	)

	content := baseStyle.Render(
		lipgloss.JoinVertical(
			lipgloss.Center,
			question,
			"",
			buttons,
		),
	)

	quitDialogStyle := baseStyle.
		Padding(1, 2).
		Border(lipgloss.RoundedBorder()).
		BorderForeground(t.BorderFocus)

	return quitDialogStyle.Render(content)
}

func (q *quitDialogCmp) Position() (int, int) {
	row := q.wHeight / 2
	row -= 7 / 2
	col := q.wWidth / 2
	col -= (lipgloss.Width(question) + 4) / 2

	return row, col
}

func (q *quitDialogCmp) ID() dialogs.DialogID {
	return QuitDialogID
}
