"""Keyboard navigation focus zone and action factories for the card stack."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/keyboard/actions.ipynb.

# %% auto #0
__all__ = ['create_card_stack_focus_zone', 'create_card_stack_nav_actions', 'build_card_stack_url_map',
           'render_card_stack_action_buttons']

# %% ../../nbs/keyboard/actions.ipynb #ka000003
from typing import Optional, Tuple, Dict

from fasthtml.common import Button, Div, FT
from cjm_fasthtml_tailwind.utilities.layout import display_tw

from cjm_fasthtml_keyboard_navigation.core.focus_zone import FocusZone
from cjm_fasthtml_keyboard_navigation.core.actions import KeyAction
from cjm_fasthtml_keyboard_navigation.core.navigation import ScrollOnly

from ..core.config import CardStackConfig
from ..core.html_ids import CardStackHtmlIds
from ..core.button_ids import CardStackButtonIds
from ..core.models import CardStackUrls
from ..js.core import global_callback_name

# %% ../../nbs/keyboard/actions.ipynb #ka000005
def create_card_stack_focus_zone(
    ids: CardStackHtmlIds,  # HTML IDs for this card stack instance
    on_focus_change: Optional[str] = None,  # JS callback name on focus change
    hidden_input_prefix: Optional[str] = None,  # Prefix for keyboard nav hidden inputs
    data_attributes: Tuple[str, ...] = (),  # Data attributes to track on focused items
) -> FocusZone:  # Configured focus zone for the card stack
    """Create a focus zone for a card stack viewport."""
    return FocusZone(
        id=ids.card_stack,
        item_selector="[data-card-role='focused']",
        navigation=ScrollOnly(),
        data_attributes=data_attributes,
        zone_focus_classes=(),
        item_focus_classes=(),
        on_focus_change=on_focus_change or "",
        hidden_input_prefix=hidden_input_prefix or f"{ids.prefix}-focused",
    )

# %% ../../nbs/keyboard/actions.ipynb #ka000010
def create_card_stack_nav_actions(
    zone_id: str,  # Focus zone ID to restrict actions to
    button_ids: CardStackButtonIds,  # Button IDs for HTMX triggers
    config: CardStackConfig,  # Config (for prefix-unique callback names)
    disable_in_modes: Tuple[str, ...] = (),  # Mode names that disable navigation
) -> Tuple[KeyAction, ...]:  # Standard card stack navigation actions
    """Create standard keyboard navigation actions for a card stack."""
    zone_ids = (zone_id,)
    not_modes = disable_in_modes if disable_in_modes else ()
    prefix = config.prefix

    return (
        # --- Item navigation (HTMX triggers) ---
        KeyAction(
            key="ArrowUp",
            htmx_trigger=button_ids.nav_up,
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="Previous item",
            hint_group="Navigation",
        ),
        KeyAction(
            key="ArrowDown",
            htmx_trigger=button_ids.nav_down,
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="Next item",
            hint_group="Navigation",
        ),

        # --- Page jump (JS callbacks, prefix-unique) ---
        KeyAction(
            key="ArrowUp",
            modifiers=frozenset({"ctrl"}),
            js_callback=global_callback_name(prefix, "jumpPageUp"),
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="Page up",
            hint_group="Navigation",
        ),
        KeyAction(
            key="ArrowDown",
            modifiers=frozenset({"ctrl"}),
            js_callback=global_callback_name(prefix, "jumpPageDown"),
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="Page down",
            hint_group="Navigation",
        ),

        # --- First/last item (JS callbacks, prefix-unique) ---
        KeyAction(
            key="ArrowUp",
            modifiers=frozenset({"ctrl", "shift"}),
            js_callback=global_callback_name(prefix, "jumpToFirstItem"),
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="First item",
            hint_group="Navigation",
        ),
        KeyAction(
            key="ArrowDown",
            modifiers=frozenset({"ctrl", "shift"}),
            js_callback=global_callback_name(prefix, "jumpToLastItem"),
            zone_ids=zone_ids,
            not_modes=not_modes,
            description="Last item",
            hint_group="Navigation",
        ),

        # --- Width adjustment (available in any mode) ---
        KeyAction(
            key="[",
            js_callback=global_callback_name(prefix, "decreaseWidth"),
            zone_ids=zone_ids,
            description="Narrower",
            hint_group="View",
        ),
        KeyAction(
            key="]",
            js_callback=global_callback_name(prefix, "increaseWidth"),
            zone_ids=zone_ids,
            description="Wider",
            hint_group="View",
        ),

        # --- Scale adjustment (available in any mode) ---
        KeyAction(
            key="-",
            js_callback=global_callback_name(prefix, "decreaseScale"),
            zone_ids=zone_ids,
            description="Smaller",
            hint_group="View",
        ),
        KeyAction(
            key="=",
            js_callback=global_callback_name(prefix, "increaseScale"),
            zone_ids=zone_ids,
            description="Larger",
            hint_group="View",
        ),
    )

# %% ../../nbs/keyboard/actions.ipynb #q6nqfsne4vf
def build_card_stack_url_map(
    button_ids: CardStackButtonIds,  # Button IDs for this card stack instance
    urls: CardStackUrls,  # URL bundle for routing
) -> Dict[str, str]:  # Mapping of button ID -> route URL
    """Build url_map for render_keyboard_system with all card stack navigation buttons.

    Returns a dict mapping button IDs to URLs for all navigation actions:
    nav_up, nav_down, nav_first, nav_last, nav_page_up, nav_page_down.
    
    Merge with consumer's own action URLs when building the keyboard system:
        url_map = {**build_card_stack_url_map(btn_ids, urls), **my_action_urls}
    """
    return {
        button_ids.nav_up: urls.nav_up,
        button_ids.nav_down: urls.nav_down,
        button_ids.nav_first: urls.nav_first,
        button_ids.nav_last: urls.nav_last,
        button_ids.nav_page_up: urls.nav_page_up,
        button_ids.nav_page_down: urls.nav_page_down,
    }

# %% ../../nbs/keyboard/actions.ipynb #m9cf824czm
def render_card_stack_action_buttons(
    button_ids: CardStackButtonIds,  # Button IDs for this card stack instance
    urls: CardStackUrls,  # URL bundle for routing
    ids: CardStackHtmlIds,  # HTML IDs (for hx-include of focused_index_input)
) -> 'FT':  # Div containing hidden action buttons
    """Render hidden HTMX buttons for JS-callback-triggered navigation actions.

    Creates buttons for: page_up, page_down, first, last.
    These are clicked programmatically by the card stack's JS functions.
    Must be included in the DOM alongside the keyboard system's own buttons.
    """
    include_selector = f"#{ids.focused_index_input}"
    hidden_cls = str(display_tw.hidden)

    def _btn(btn_id, url):
        return Button(
            id=btn_id,
            hx_post=url,
            hx_swap="none",
            hx_include=include_selector,
            cls=hidden_cls,
        )

    return Div(
        _btn(button_ids.nav_page_up, urls.nav_page_up),
        _btn(button_ids.nav_page_down, urls.nav_page_down),
        _btn(button_ids.nav_first, urls.nav_first),
        _btn(button_ids.nav_last, urls.nav_last),
        cls=hidden_cls,
    )
