"""Main entry point for rendering a virtual collection."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/collection.ipynb.

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

# %% ../../nbs/components/collection.ipynb #e0f08a9c
from typing import Any, Callable, List, Optional

from fasthtml.common import Div, Hidden

from cjm_fasthtml_tailwind.utilities.layout import overflow
from cjm_fasthtml_tailwind.utilities.sizing import w, min_h
from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import flex_display, flex_direction, flex, grow
from cjm_fasthtml_tailwind.utilities.interactivity import touch
from cjm_fasthtml_tailwind.utilities.tables import table_display, border_collapse
from cjm_fasthtml_tailwind.core.base import combine_classes

from cjm_fasthtml_virtual_collection.core.models import (
    VirtualCollectionConfig, VirtualCollectionState, VirtualCollectionUrls,
)
from ..core.html_ids import VirtualCollectionHtmlIds
from .table import render_header_row, render_table_rows
from .footer import render_footer
from .scrollbar import render_scrollbar

# %% ../../nbs/components/collection.ipynb #e0eadf8a
def render_virtual_collection(
    items: list,                                # Full item list
    config: VirtualCollectionConfig,             # Collection config
    state: VirtualCollectionState,               # Collection state
    ids: VirtualCollectionHtmlIds,               # HTML IDs
    urls: VirtualCollectionUrls,                 # URL bundle
    render_cell: Optional[Callable] = None,      # Table layout cell render callback
    render_item: Optional[Callable] = None,      # Grid layout item render callback
    render_empty: Optional[Callable] = None,     # Empty state callback: () -> FT component
) -> Div:  # Complete collection element
    """Render a complete virtual collection with wrapper, table, scrollbar, and footer."""
    children = []

    if config.layout == "table":
        assert render_cell is not None, "render_cell required for table layout"

        # Empty state: replace table body with consumer-provided component
        if state.total_items == 0 and render_empty is not None:
            table = Div(
                Div(
                    render_header_row(config, ids, state=state, sort_url=urls.sort),
                    cls=combine_classes(table_display.header_group),
                ),
                render_empty(),
                id=ids.table,
                cls=combine_classes(table_display, w.full, border_collapse.collapse),
            )
        else:
            # CSS Table: header group + body group
            table = Div(
                Div(
                    render_header_row(config, ids, state=state, sort_url=urls.sort),
                    cls=combine_classes(table_display.header_group),
                ),
                render_table_rows(items, config, state, ids, render_cell, focus_url=urls.focus_row),
                id=ids.table,
                cls=combine_classes(table_display, w.full, border_collapse.collapse),
            )

        # Wrapper (viewport-fit target) + scrollbar side-by-side
        # touch-pan-x: allow native horizontal pan for wide tables,
        # suppress vertical (handled by discrete navigation)
        # min-h-0: allow shrinking below content height in flex parents
        wrapper = Div(
            table,
            id=ids.wrapper,
            cls=combine_classes(flex(1), min_h._0, overflow.y.hidden, touch.pan_x),
        )

        if config.show_scrollbar:
            # Scrollbar always visible — serves as position indicator (cursor-based model)
            scrollbar = render_scrollbar(state, config, ids)
            body = Div(wrapper, scrollbar, cls=combine_classes(flex_display, grow(), min_h._0))
        else:
            body = wrapper

        children.append(body)

    elif config.layout == "grid":
        raise NotImplementedError("Grid layout will be added in Phase 14")
    else:
        raise ValueError(f"Unknown layout: {config.layout}")

    # Footer
    children.append(render_footer(state, ids))

    # Hidden input for JS thumb positioning (OOB-updated on navigation)
    children.append(Hidden(
        value=str(state.window_start),
        id=ids.window_start_input,
        name="window_start",
    ))

    # Refit trigger — empty div for OOB-swapping auto-fit scripts after item mutations
    children.append(Div(id=ids.refit_trigger, style="display:none"))

    # grow + min-h-0: fill flex parent without exceeding it
    return Div(
        *children,
        id=ids.collection,
        cls=combine_classes(flex_display, flex_direction.col, grow(), min_h._0, touch.pan_x),
    )
