"""
Key constants and key-binding registry for the console UI.

Key provides named constants matching curses key codes so that screens
and renderers never need to import curses directly.

KeyBindings maps key codes to callable actions and tracks the footer
labels displayed at the bottom of the screen.
"""

import curses


class Key:
    """Key constants matching curses key codes."""

    ESCAPE = 27
    ENTER = 10
    TAB = 9
    BACKSPACE = 127

    UP = curses.KEY_UP
    DOWN = curses.KEY_DOWN
    LEFT = curses.KEY_LEFT
    RIGHT = curses.KEY_RIGHT

    PGUP = curses.KEY_PPAGE
    PGDN = curses.KEY_NPAGE
    HOME = curses.KEY_HOME
    END = curses.KEY_END

    F1 = curses.KEY_F1
    F2 = curses.KEY_F2
    F3 = curses.KEY_F3
    F4 = curses.KEY_F4
    F5 = curses.KEY_F5
    F6 = curses.KEY_F6
    F7 = curses.KEY_F7
    F8 = curses.KEY_F8
    F9 = curses.KEY_F9
    F10 = curses.KEY_F10


class KeyBindings:
    """Registry that maps key codes to callable actions.

    Usage::

        kb = KeyBindings()
        kb.bind(Key.ENTER, lambda: do_something())
        handled = kb.handle(Key.ENTER)  # True, callback was invoked
    """

    def __init__(self):
        self._bindings: dict[int, callable] = {}
        self._footer_labels: list[tuple[str, str]] = []

    def bind(self, key: int, action: callable) -> None:
        """Register *action* as the callback for *key*.

        If *key* already has a binding it is replaced.
        """
        self._bindings[key] = action

    def handle(self, key: int) -> bool:
        """Look up *key* and invoke its callback if one exists.

        Returns ``True`` if a callback was found and executed,
        ``False`` otherwise.
        """
        action = self._bindings.get(key)
        if action is not None:
            action()
            return True
        return False

    def set_footer(self, labels: list[tuple[str, str]]) -> None:
        """Set the footer bar labels.

        *labels* is a list of ``(key_label, description)`` tuples, e.g.
        ``[("F1", "Help"), ("F10", "Quit")]``.
        """
        self._footer_labels = list(labels)

    def get_footer_labels(self) -> list[tuple[str, str]]:
        """Return the current footer labels list."""
        return list(self._footer_labels)
