"""Singleton widget registry for cross-domain UI composition.

Usage::

    from shared.services.widget_registry import widgets

    # Register at app startup (after domain services)
    widgets.add_container_nav(NavWidget(...))

    # Query in templates / context processors
    for w in widgets.container_nav:
        ctx = await w.context_fn(session, container_type="page", ...)
"""
from __future__ import annotations

from shared.contracts.widgets import (
    NavWidget,
    CardWidget,
    AccountPageWidget,
    AccountNavLink,
)


class _WidgetRegistry:
    """Central registry holding all widget descriptors.

    Widgets are added at startup and read at request time.
    Properties return sorted-by-order copies.
    """

    def __init__(self) -> None:
        self._container_nav: list[NavWidget] = []
        self._container_card: list[CardWidget] = []
        self._account_pages: list[AccountPageWidget] = []
        self._account_nav: list[AccountNavLink] = []

    # -- registration ---------------------------------------------------------

    def add_container_nav(self, w: NavWidget) -> None:
        self._container_nav.append(w)

    def add_container_card(self, w: CardWidget) -> None:
        self._container_card.append(w)

    def add_account_page(self, w: AccountPageWidget) -> None:
        self._account_pages.append(w)
        # Auto-create a matching internal nav link
        slug = w.slug

        def _href(s=slug):
            from shared.infrastructure.urls import coop_url
            return coop_url(f"/auth/{s}/")

        self._account_nav.append(AccountNavLink(
            label=w.label,
            order=w.order,
            href_fn=_href,
            external=False,
        ))

    def add_account_link(self, link: AccountNavLink) -> None:
        self._account_nav.append(link)

    # -- read access (sorted copies) ------------------------------------------

    @property
    def container_nav(self) -> list[NavWidget]:
        return sorted(self._container_nav, key=lambda w: w.order)

    @property
    def container_cards(self) -> list[CardWidget]:
        return sorted(self._container_card, key=lambda w: w.order)

    @property
    def account_pages(self) -> list[AccountPageWidget]:
        return sorted(self._account_pages, key=lambda w: w.order)

    @property
    def account_nav(self) -> list[AccountNavLink]:
        return sorted(self._account_nav, key=lambda w: w.order)

    def account_page_by_slug(self, slug: str) -> AccountPageWidget | None:
        for w in self._account_pages:
            if w.slug == slug:
                return w
        return None


# Module-level singleton — import this everywhere.
widgets = _WidgetRegistry()
