package screens

import (
	"charm.land/bubbles/v2/key"
	tea "charm.land/bubbletea/v2"

	"charm.land/huh/v2"

	"git.secluded.site/keld/internal/theme"
	"git.secluded.site/keld/internal/ui"
)

// overwriteOptions defines the choices for restic's --overwrite flag
// in the order they are presented to the user.
var overwriteOptions = []huh.Option[string]{
	huh.NewOption("if-changed  (recommended — only restore what differs)", "if-changed"),
	huh.NewOption("if-newer    (only overwrite older files)", "if-newer"),
	huh.NewOption("never       (skip existing files entirely)", "never"),
	huh.NewOption("always      (restic default — overwrite everything)", "always"),
}

// Overwrite is a Screen adapter that wraps a huh Select for choosing
// the restore --overwrite behaviour. It follows the same pattern as
// [Preset]: builds the huh form on Init, intercepts Esc for back
// navigation, and returns DoneCmd on completion.
type Overwrite struct {
	styles    *theme.Styles
	form      *huh.Form
	selected  string
	selection string
}

// NewOverwrite creates an overwrite selector screen. The styles
// pointer should come from the session so theme updates propagate.
func NewOverwrite(styles *theme.Styles) *Overwrite {
	return &Overwrite{
		styles: styles,
	}
}

// buildForm constructs the huh form and select field.
func (o *Overwrite) buildForm() {
	o.selection = ""

	sel := huh.NewSelect[string]().
		Options(overwriteOptions...).
		Value(&o.selected)

	o.form = huh.NewForm(
		huh.NewGroup(sel),
	).WithTheme(o.styles.Huh).WithShowHelp(false)
}

// Init initialises the embedded form. On first call or after
// completion, the form is (re)built.
func (o *Overwrite) Init() tea.Cmd {
	if o.form == nil || o.form.State != huh.StateNormal {
		o.buildForm()
	}
	return o.form.Init()
}

// Update handles messages. Esc is intercepted for back navigation.
func (o *Overwrite) Update(msg tea.Msg) (ui.Screen, tea.Cmd) {
	if o.form == nil {
		return o, nil
	}

	switch msg.(type) {
	case tea.BackgroundColorMsg:
		o.buildForm()
		return o, o.form.Init()
	}

	if kp, ok := msg.(tea.KeyPressMsg); ok {
		if kp.Code == tea.KeyEscape {
			return o, ui.BackCmd
		}
	}

	model, cmd := o.form.Update(msg)
	if f, ok := model.(*huh.Form); ok {
		o.form = f
	}

	if o.form.State == huh.StateCompleted {
		o.selection = o.selected
		return o, ui.DoneCmd
	}

	return o, cmd
}

// View renders the form.
func (o *Overwrite) View() string {
	if o.form == nil {
		return ""
	}
	return o.form.View()
}

// Title returns the screen's display title.
func (o *Overwrite) Title() string { return "Overwrite existing files?" }

// KeyBindings returns bindings for the help bar.
func (o *Overwrite) KeyBindings() []key.Binding {
	return []key.Binding{
		key.NewBinding(key.WithKeys("↑/↓"), key.WithHelp("↑/↓", "navigate")),
		key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "select")),
	}
}

// Selection returns the chosen overwrite mode for breadcrumb display,
// or "" if nothing has been selected yet.
func (o *Overwrite) Selection() string { return o.selection }

// Value returns the chosen overwrite mode value (one of: if-changed,
// if-newer, never, always).
func (o *Overwrite) Value() string { return o.selected }
