package screens

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

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

// ResolveFunc is called by the resolve screen to build the next set
// of screens based on the selections made so far. It returns the
// screens to append to the session, or nil if no additional screens
// are needed (the session will complete immediately).
type ResolveFunc func() []ui.Screen

// resolvedMsg carries the result of an async resolve.
type resolvedMsg struct {
	screens []ui.Screen
}

// Resolve is a transparent Screen adapter that sits between the
// menu/preset screens and the command-specific screens. It calls an
// injected function to build the next screens, extends the session
// via [ui.ExtendMsg], and immediately advances via [ui.DoneCmd].
//
// The user never sees this screen — it completes within a single
// Update cycle.
type Resolve struct {
	fn ResolveFunc
}

// NewResolve creates a resolve screen with the given builder function.
func NewResolve(fn ResolveFunc) *Resolve {
	return &Resolve{fn: fn}
}

// Init triggers the async resolve.
func (r *Resolve) Init() tea.Cmd {
	return func() tea.Msg {
		screens := r.fn()
		return resolvedMsg{screens: screens}
	}
}

// Update handles the resolve result.
func (r *Resolve) Update(msg tea.Msg) (ui.Screen, tea.Cmd) {
	switch msg := msg.(type) {
	case resolvedMsg:
		if len(msg.screens) == 0 {
			return r, ui.DoneCmd
		}
		return r, tea.Sequence(
			func() tea.Msg { return ui.ExtendMsg{Screens: msg.screens} },
			ui.DoneCmd,
		)
	case tea.KeyPressMsg:
		if msg.Code == tea.KeyEscape {
			return r, ui.BackCmd
		}
	}
	return r, nil
}

// View is intentionally empty — this screen should not be visible.
func (r *Resolve) View() string { return "" }

// Title returns empty — this screen has no visible title.
func (r *Resolve) Title() string { return "" }

// KeyBindings returns no bindings.
func (r *Resolve) KeyBindings() []key.Binding { return nil }

// Selection returns empty — this screen has no user-visible selection.
func (r *Resolve) Selection() string { return "" }
