package app

import tea "charm.land/bubbletea/v2"

// bubbletea v2 collapsed key events into a single (Code rune, Mod KeyMod) form
// and dropped the v1 KeyType enum the handlers were written against. Rather than
// rewrite ~190 key-match sites, this shim adapts a v2 key press into the same
// v1-shaped struct (Type + Runes + modifier flags), so all the matching logic
// downstream stays untouched. The only place that ever touches the raw v2 key
// is toKeyMsg below, called once at the Update boundary.

type keyType int

const (
	keyRunes keyType = iota
	keyEnter
	keyUp
	keyDown
	keyLeft
	keyRight
	keySpace
	keyEsc
	keyBackspace
	keyTab
	keyPgUp
	keyPgDown
	keyCtrlA
	keyCtrlC
	keyCtrlD
	keyCtrlJ
	keyCtrlR
	keyCtrlU
	keyCtrlX
	keyCtrlP
	keyCtrlUp
	keyCtrlDown
	keyOther
)

// keyMsg is the v1-shaped key event the handlers consume: a Type plus the typed
// Runes and modifier flags. Shift is newly meaningful under v2's kitty key
// disambiguation — it powers Shift+Enter newlines (see handleInsertKey).
type keyMsg struct {
	Type  keyType
	Runes []rune
	Alt   bool
	Shift bool
	str   string
}

func (k keyMsg) String() string { return k.str }

// toKeyMsg converts a bubbletea v2 key press into the shim's v1-shaped form.
func toKeyMsg(p tea.KeyPressMsg) keyMsg {
	k := p.Key()
	out := keyMsg{
		Alt:   k.Mod.Contains(tea.ModAlt),
		Shift: k.Mod.Contains(tea.ModShift),
		str:   k.Keystroke(),
	}
	ctrl := k.Mod.Contains(tea.ModCtrl)
	switch k.Code {
	case tea.KeyEnter:
		out.Type = keyEnter
	case tea.KeyEscape:
		out.Type = keyEsc
	case tea.KeyTab:
		out.Type = keyTab
	case tea.KeyBackspace:
		out.Type = keyBackspace
	case tea.KeySpace:
		out.Type = keySpace
		out.Runes = []rune{' '}
	case tea.KeyUp:
		if ctrl {
			out.Type = keyCtrlUp
		} else {
			out.Type = keyUp
		}
	case tea.KeyDown:
		if ctrl {
			out.Type = keyCtrlDown
		} else {
			out.Type = keyDown
		}
	case tea.KeyLeft:
		out.Type = keyLeft
	case tea.KeyRight:
		out.Type = keyRight
	case tea.KeyPgUp:
		out.Type = keyPgUp
	case tea.KeyPgDown:
		out.Type = keyPgDown
	default:
		if ctrl {
			switch k.Code {
			case 'a':
				out.Type = keyCtrlA
			case 'c':
				out.Type = keyCtrlC
			case 'd':
				out.Type = keyCtrlD
			case 'p':
				out.Type = keyCtrlP
			case 'j':
				out.Type = keyCtrlJ
			case 'r':
				out.Type = keyCtrlR
			case 'u':
				out.Type = keyCtrlU
			case 'x':
				out.Type = keyCtrlX
			default:
				out.Type = keyOther
			}
			return out
		}
		if k.Text != "" {
			out.Type = keyRunes
			out.Runes = []rune(k.Text)
		} else {
			out.Type = keyOther
		}
	}
	return out
}
