// Package form provides interactive huh-based prompts for collecting user
// input when keld is invoked via the interactive menu.
package form

import (
	"errors"
	"fmt"
	"strings"

	"charm.land/huh/v2"
)

// ErrAborted is returned when the user cancels a form (ctrl+c / q).
var ErrAborted = errors.New("aborted by user")

// wrapAbort converts huh's abort error into our own sentinel.
func wrapAbort(err error) error {
	if err != nil && errors.Is(err, huh.ErrUserAborted) {
		return ErrAborted
	}
	return err
}

// SelectPreset displays an interactive selector for the given preset names.
// Returns the selected preset, or "" if the user picks "(none)".
func SelectPreset(presets []string) (string, error) {
	if len(presets) == 0 {
		return "", nil
	}

	opts := make([]huh.Option[string], 0, len(presets)+1)
	opts = append(opts, huh.NewOption("(global defaults only)", ""))
	for _, p := range presets {
		opts = append(opts, huh.NewOption(p, p))
	}

	var selected string
	form := huh.NewForm(
		huh.NewGroup(
			huh.NewSelect[string]().
				Title("Select a preset").
				Options(opts...).
				Value(&selected),
		),
	)

	if err := wrapAbort(form.Run()); err != nil {
		return "", err
	}
	return selected, nil
}

// TargetDirectory prompts for a restore target directory.
func TargetDirectory() (string, error) {
	var target string
	form := huh.NewForm(
		huh.NewGroup(
			huh.NewInput().
				Title("Target directory").
				Placeholder("e.g. /tmp/restore").
				Value(&target).
				Validate(notEmpty("target directory")),
		),
	)

	if err := wrapAbort(form.Run()); err != nil {
		return "", err
	}
	return target, nil
}

// BackupPaths collects one or more paths to back up when none are configured.
func BackupPaths() ([]string, error) {
	var raw string
	form := huh.NewForm(
		huh.NewGroup(
			huh.NewInput().
				Title("Paths to back up").
				Description("Space-separated list of files or directories.").
				Placeholder("e.g. /home/user /etc").
				Value(&raw).
				Validate(notEmpty("backup path")),
		),
	)

	if err := wrapAbort(form.Run()); err != nil {
		return nil, err
	}
	return splitFields(raw), nil
}

// notEmpty returns a validation function that rejects blank or
// whitespace-only input.
func notEmpty(fieldName string) func(string) error {
	return func(s string) error {
		if strings.TrimSpace(s) == "" {
			return fmt.Errorf("%s is required", fieldName)
		}
		return nil
	}
}

// splitFields splits a string on whitespace.
func splitFields(s string) []string {
	return strings.Fields(s)
}
