package bindings

import (
	"fmt"
	"slices"
)

// Binding maps a key (or key sequence) to an action in a scope.
type Binding struct {
	Action Action
	Desc   string
	Scope  ScopeName
	Key    []string
	Seq    []string
	Args   map[string]any
}

func (b Binding) validate() error {
	if b.Action == "" {
		return fmt.Errorf("binding action is required")
	}
	if b.Scope == "" {
		return fmt.Errorf("binding scope is required")
	}

	hasKey := len(b.Key) > 0
	hasSeq := len(b.Seq) > 0
	if hasKey == hasSeq {
		return fmt.Errorf("binding %q in scope %q must set exactly one of key or seq", b.Action, b.Scope)
	}

	if slices.Contains(b.Key, "") {
		return fmt.Errorf("binding %q in scope %q contains empty key", b.Action, b.Scope)
	}
	if slices.Contains(b.Seq, "") {
		return fmt.Errorf("binding %q in scope %q contains empty sequence key", b.Action, b.Scope)
	}
	if len(b.Seq) == 1 {
		return fmt.Errorf("binding %q in scope %q has seq with only one key; use key instead", b.Action, b.Scope)
	}

	return nil
}

func ValidateBindings(bindings []Binding) error {
	for i, binding := range bindings {
		if err := binding.validate(); err != nil {
			return fmt.Errorf("invalid binding at index %d: %w", i, err)
		}
	}
	return nil
}
