"""Tests for KeyMap."""

from pyos import Keys
from pyos.KeyMap import KeyMap


class TestKeyMapDispatch:
    def test_global_binding_fires(self):
        called = []
        km = KeyMap({Keys.ESC: lambda: called.append("esc")})
        assert km.dispatch(Keys.ESC) is True
        assert called == ["esc"]

    def test_unbound_key_returns_false(self):
        km = KeyMap()
        assert km.dispatch(Keys.ESC) is False

    def test_scoped_binding_takes_priority(self):
        called = []
        km = KeyMap({Keys.ENTER: lambda: called.append("global")})
        km.when("listing", {Keys.ENTER: lambda: called.append("scoped")})

        km.dispatch(Keys.ENTER, focus="listing")
        assert called == ["scoped"]

    def test_scoped_falls_through_to_global(self):
        called = []
        km = KeyMap({Keys.ESC: lambda: called.append("global")})
        km.when("listing", {Keys.ENTER: lambda: called.append("scoped")})

        km.dispatch(Keys.ESC, focus="listing")
        assert called == ["global"]

    def test_no_focus_uses_global(self):
        called = []
        km = KeyMap({Keys.ENTER: lambda: called.append("global")})
        km.when("listing", {Keys.ENTER: lambda: called.append("scoped")})

        km.dispatch(Keys.ENTER, focus=None)
        assert called == ["global"]


class TestKeyMapBindUnbind:
    def test_bind_adds_global(self):
        called = []
        km = KeyMap()
        km.bind(Keys.TAB, lambda: called.append("tab"))
        km.dispatch(Keys.TAB)
        assert called == ["tab"]

    def test_unbind_removes_global(self):
        km = KeyMap({Keys.ESC: lambda: None})
        km.unbind(Keys.ESC)
        assert km.dispatch(Keys.ESC) is False

    def test_unbind_nonexistent_is_noop(self):
        km = KeyMap()
        km.unbind(Keys.ESC)  # should not raise


class TestKeyMapWhen:
    def test_multiple_scopes(self):
        called = []
        km = KeyMap()
        km.when("a", {Keys.ENTER: lambda: called.append("a")})
        km.when("b", {Keys.ENTER: lambda: called.append("b")})

        km.dispatch(Keys.ENTER, focus="a")
        km.dispatch(Keys.ENTER, focus="b")
        assert called == ["a", "b"]

    def test_unknown_focus_falls_to_global(self):
        called = []
        km = KeyMap({Keys.ENTER: lambda: called.append("global")})
        km.dispatch(Keys.ENTER, focus="unknown")
        assert called == ["global"]
