package ui

import (
	"github.com/charmbracelet/bubbles/key"
	"strings"
)

type KeyMap struct {
	Up, Down, Left, Right key.Binding
	Undo, Redo            key.Binding
	ToggleAuto            key.Binding
	ToggleTimer           key.Binding
	Help                  key.Binding
	MainMenu              key.Binding
	Hint                  key.Binding
	Pause                 key.Binding
	ToggleNote            key.Binding
	Save                  key.Binding
	Load                  key.Binding
}

func DefaultKeyMap() KeyMap {
	return KeyMap{
		Up:          key.NewBinding(key.WithKeys("up", "k"), key.WithHelp("↑/k", "Up")),
		Down:        key.NewBinding(key.WithKeys("down", "j"), key.WithHelp("↓/j", "Down")),
		Left:        key.NewBinding(key.WithKeys("left", "h"), key.WithHelp("←/h", "Left")),
		Right:       key.NewBinding(key.WithKeys("right", "l"), key.WithHelp("→/l", "Right")),
		Undo:        key.NewBinding(key.WithKeys("ctrl+z", "u"), key.WithHelp("u/Ctrl+Z", "Undo")),
		Redo:        key.NewBinding(key.WithKeys("ctrl+y", "ctrl+r"), key.WithHelp("Ctrl+Y/R", "Redo")),
		ToggleAuto:  key.NewBinding(key.WithKeys("a"), key.WithHelp("a", "Auto-Check")),
		ToggleTimer: key.NewBinding(key.WithKeys("t"), key.WithHelp("t", "Timer")),
		Help:        key.NewBinding(key.WithKeys("?"), key.WithHelp("?", "Help")),
		MainMenu:    key.NewBinding(key.WithKeys("m"), key.WithHelp("m", "Main Menu")),
		Hint:        key.NewBinding(key.WithKeys("ctrl+h"), key.WithHelp("Ctrl+H", "Hint")),
		Pause:       key.NewBinding(key.WithKeys("p"), key.WithHelp("p", "Pause")),
		ToggleNote:  key.NewBinding(key.WithKeys("n"), key.WithHelp("n", "Note Mode")),
		Save:        key.NewBinding(key.WithKeys("ctrl+s"), key.WithHelp("Ctrl+S", "Save")),
		Load:        key.NewBinding(key.WithKeys("ctrl+l"), key.WithHelp("Ctrl+L", "Load")),
	}
}

func (km *KeyMap) ApplyBindings(bindings map[string][]string) {
	if bindings == nil {
		return
	}
	set := func(b *key.Binding, keys []string, help string) {
		if len(keys) == 0 {
			return
		}
		*b = key.NewBinding(key.WithKeys(keys...), key.WithHelp(strings.Join(keys, "/"), help))
	}
	if v, ok := bindings["up"]; ok {
		set(&km.Up, v, "Up")
	}
	if v, ok := bindings["down"]; ok {
		set(&km.Down, v, "Down")
	}
	if v, ok := bindings["left"]; ok {
		set(&km.Left, v, "Left")
	}
	if v, ok := bindings["right"]; ok {
		set(&km.Right, v, "Right")
	}
	if v, ok := bindings["undo"]; ok {
		set(&km.Undo, v, "Undo")
	}
	if v, ok := bindings["redo"]; ok {
		set(&km.Redo, v, "Redo")
	}
	if v, ok := bindings["auto"]; ok {
		set(&km.ToggleAuto, v, "Auto-Check")
	}
	if v, ok := bindings["timer"]; ok {
		set(&km.ToggleTimer, v, "Timer")
	}
	if v, ok := bindings["help"]; ok {
		set(&km.Help, v, "Help")
	}
	if v, ok := bindings["main"]; ok {
		set(&km.MainMenu, v, "Main Menu")
	}
	if v, ok := bindings["hint"]; ok {
		set(&km.Hint, v, "Hint")
	}
	if v, ok := bindings["pause"]; ok {
		set(&km.Pause, v, "Pause")
	}
	if v, ok := bindings["note"]; ok {
		set(&km.ToggleNote, v, "Note Mode")
	}
	if v, ok := bindings["save"]; ok {
		set(&km.Save, v, "Save")
	}
	if v, ok := bindings["load"]; ok {
		set(&km.Load, v, "Load")
	}
}
