"""Convenience router factory that wires up standard virtual collection routes (Tier 2 API)."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/routes/router.ipynb.

# %% auto #0
__all__ = ['init_virtual_collection_router']

# %% ../../nbs/routes/router.ipynb #711bb97a
from typing import Any, Callable, List, Optional, Tuple

from fasthtml.common import APIRouter

from cjm_fasthtml_virtual_collection.core.models import (
    VirtualCollectionConfig, VirtualCollectionState, VirtualCollectionUrls,
)
from ..core.html_ids import VirtualCollectionHtmlIds
from cjm_fasthtml_virtual_collection.routes.handlers import (
    handle_navigate, handle_navigate_to_index, handle_update_viewport,
    handle_focus_row, handle_activate, handle_sort,
)

# %% ../../nbs/routes/router.ipynb #a93f7b39
def init_virtual_collection_router(
    config: VirtualCollectionConfig,                    # Collection config
    state_getter: Callable[[], VirtualCollectionState],  # Function to get current state
    state_setter: Callable[[VirtualCollectionState], None],  # Function to save state
    get_items: Callable[[], list],                       # Function to get current items
    render_cell: Callable,                               # Cell render callback
    on_activate: Optional[Callable] = None,              # Consumer callback for Space/Enter on focused row
    on_refocus: Optional[Callable] = None,               # Consumer callback when clicking already-focused row
    sort_callback: Optional[Callable] = None,            # Consumer callback: (items, column_key, ascending) -> None
    is_skippable: Optional[Callable] = None,             # Predicate: (item) -> bool, cursor skips these items
    on_cursor_change: Optional[Callable] = None,         # Callback: (item, cursor_index, state) -> Tuple of extra OOB elements
    route_prefix: str = "/collection",                   # Route prefix
) -> Tuple[APIRouter, VirtualCollectionUrls]:  # (router, urls) tuple
    """Initialize an APIRouter with all standard virtual collection routes."""
    router = APIRouter(prefix=route_prefix)
    ids = VirtualCollectionHtmlIds(prefix=config.prefix)

    # Forward references resolved after route registration
    _focus_url = ""
    _sort_url = ""

    def _get_focus_url() -> str:
        return _focus_url

    def _get_sort_url() -> str:
        return _sort_url

    # -----------------------------------------------------------------
    # Navigation routes
    # -----------------------------------------------------------------

    def _nav(direction: str) -> Any:
        """Shared navigation handler."""
        state = state_getter()
        items = get_items()
        result = handle_navigate(
            direction=direction, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            focus_url=_get_focus_url(),
            is_skippable=is_skippable,
            on_cursor_change=on_cursor_change,
        )
        state_setter(state)
        return result

    @router
    def nav_up() -> Any: return _nav("up")

    @router
    def nav_down() -> Any: return _nav("down")

    @router
    def nav_first() -> Any: return _nav("first")

    @router
    def nav_last() -> Any: return _nav("last")

    @router
    def nav_page_up() -> Any: return _nav("page_up")

    @router
    def nav_page_down() -> Any: return _nav("page_down")

    @router
    def nav_to_index(target_index: int) -> Any:
        """Navigate to a specific window_start index."""
        state = state_getter()
        items = get_items()
        result = handle_navigate_to_index(
            target_index=target_index, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            focus_url=_get_focus_url(),
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Viewport route
    # -----------------------------------------------------------------

    @router
    def update_viewport(visible_rows: int, is_auto: str = "true") -> Any:
        """Update viewport with new row count."""
        state = state_getter()
        items = get_items()
        result = handle_update_viewport(
            visible_rows=visible_rows, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            is_auto=(is_auto == "true"),
            focus_url=_get_focus_url(),
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Focus route
    # -----------------------------------------------------------------

    @router
    def focus_row(request, row_index: int) -> Any:
        """Move cursor to a specific row via click/tap."""
        state = state_getter()
        items = get_items()
        result = handle_focus_row(
            row_index=row_index, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            focus_url=_get_focus_url(),
            on_refocus=on_refocus,
            is_skippable=is_skippable,
            on_cursor_change=on_cursor_change,
            request=request,
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Scrollbar focus route (no refocus callback)
    # -----------------------------------------------------------------

    @router
    def scrollbar_focus(row_index: int) -> Any:
        """Move cursor via scrollbar drag/click. No refocus — prevents
        unintentional activation of already-focused rows during drag."""
        state = state_getter()
        items = get_items()
        result = handle_focus_row(
            row_index=row_index, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            focus_url=_get_focus_url(),
            on_refocus=None,
            is_skippable=is_skippable,
            on_cursor_change=on_cursor_change,
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Activate route
    # -----------------------------------------------------------------

    @router
    def activate(request) -> Any:
        """Activate the focused row via Space/Enter."""
        if on_activate is None:
            return ()
        state = state_getter()
        items = get_items()
        result = handle_activate(
            items=items, state=state, config=config, ids=ids,
            render_cell=render_cell, on_activate=on_activate,
            focus_url=_get_focus_url(),
            request=request,
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Sort route
    # -----------------------------------------------------------------

    @router
    def sort(column: str) -> Any:
        """Sort by column key."""
        if sort_callback is None:
            return ()
        state = state_getter()
        items = get_items()
        result = handle_sort(
            column_key=column, items=items, state=state,
            config=config, ids=ids, render_cell=render_cell,
            sort_callback=sort_callback,
            sort_url=_get_sort_url(),
            focus_url=_get_focus_url(),
            is_skippable=is_skippable,
            on_cursor_change=on_cursor_change,
        )
        state_setter(state)
        return result

    # -----------------------------------------------------------------
    # Build URL bundle from registered routes
    # -----------------------------------------------------------------

    _focus_url = focus_row.to()
    _sort_url = sort.to()

    urls = VirtualCollectionUrls(
        nav_up=nav_up.to(),
        nav_down=nav_down.to(),
        nav_page_up=nav_page_up.to(),
        nav_page_down=nav_page_down.to(),
        nav_first=nav_first.to(),
        nav_last=nav_last.to(),
        nav_to_index=nav_to_index.to(),
        update_viewport=update_viewport.to(),
        focus_row=_focus_url,
        scrollbar_focus=scrollbar_focus.to(),
        activate=activate.to(),
        sort=_sort_url,
    )

    return router, urls
