"""zuzu.app() — App runner with auto-generated pages."""

from __future__ import annotations

from contextlib import contextmanager
from typing import Any, Generator

from zuzu.record import Record
from zuzu.runtime.spec import _set_app_config, _add_page, _add_component, _components, show


class App:
    """A zuzu application.

    Usage:
        app = zuzu.app("My CRM", records=[clients, deals])
        app.run()

    Theming:
        app = zuzu.app("My CRM",
            records=[clients, deals],
            accent="blue",      # purple|blue|green|red|yellow|orange|cyan|pink|indigo
            theme="dark",       # dark|light|auto
            nav="tabs",         # tabs|sidebar
            icon="💼",          # emoji or None
        )
    """

    def __init__(
        self,
        name: str,
        *,
        records: list[Record] | None = None,
        accent: str = "purple",
        theme: str = "dark",
        nav: str = "tabs",
        icon: str | None = None,
        radius: str = "md",
        card_style: str = "outlined",
        density: str = "default",
        content_width: str = "md",
    ) -> None:
        self._name = name
        self._records = records or []
        self._accent = accent
        self._theme = theme
        self._nav = nav
        self._icon = icon
        self._radius = radius
        self._card_style = card_style
        self._density = density
        self._content_width = content_width
        self._pages: dict[str, PageConfig] = {}
        self._custom_pages: list[str] = []

    def page(self, name: str) -> PageConfig:
        """Get or create a page configuration."""
        if name not in self._pages:
            self._pages[name] = PageConfig(name)
        return self._pages[name]

    def run(self) -> None:
        """Run the app — generates spec and outputs it."""
        _set_app_config({
            "name": self._name,
            "accent": self._accent,
            "theme": self._theme,
            "nav": self._nav,
            "icon": self._icon,
            "radius": self._radius,
            "card_style": self._card_style,
            "density": self._density,
            "content_width": self._content_width,
            "records": [r._to_spec() for r in self._records],
        })

        # Auto-generate pages for each record
        for rec in self._records:
            rec._ensure_table()
            config = self._pages.get(rec._name, PageConfig(rec._name))

            # List page
            _add_page({
                "name": f"{rec._name}",
                "type": "list",
                "record": rec._table_name,
                "config": config._to_spec(),
            })

            # Detail page
            _add_page({
                "name": f"{rec._name} Detail",
                "type": "detail",
                "record": rec._table_name,
            })

            # Add form page
            _add_page({
                "name": f"Add {rec._name}",
                "type": "form",
                "record": rec._table_name,
            })

        # Add custom pages
        for page_name in self._custom_pages:
            if page_name in self._pages:
                pg = self._pages[page_name]
                _add_page({
                    "name": page_name,
                    "type": "custom",
                    "components": pg._components,
                })

        show()


class PageConfig:
    """Configuration for an app page."""

    def __init__(self, name: str) -> None:
        self._name = name
        self._show_config: dict[str, Any] = {}
        self._components: list[dict[str, Any]] = []

    def show(self, **kwargs: Any) -> PageConfig:
        """Configure how the auto-generated page displays data.

        Usage:
            app.page("Clients").show(
                title="name",
                subtitle="company",
                badge="status",
                sort="revenue",
            )
        """
        self._show_config.update(kwargs)
        return self

    def _to_spec(self) -> dict[str, Any]:
        return self._show_config


# ── Context manager for custom pages ─────────────────────────────────────

_current_page: PageConfig | None = None
_current_app: App | None = None


@contextmanager
def page(name: str, **kwargs: Any) -> Generator[None, None, None]:
    """Context manager for building custom pages.

    Usage:
        with zuzu.page("Dashboard"):
            zuzu.metric("Revenue", 42000)
            zuzu.chart(deals, x="stage", y="value")
    """
    global _current_page, _current_app

    if _current_app is None:
        # Standalone page (no app context) — just use global components
        yield
        return

    pg = _current_app.page(name)
    if name not in _current_app._custom_pages:
        _current_app._custom_pages.append(name)

    # Temporarily redirect components to this page
    saved_components = _components.copy()
    _components.clear()
    _current_page = pg

    yield

    # Move accumulated components to the page
    pg._components = _components.copy()
    _components.clear()
    _components.extend(saved_components)
    _current_page = None


def app(
    name: str,
    *,
    records: list[Record] | None = None,
    accent: str = "purple",
    theme: str = "dark",
    nav: str = "tabs",
    icon: str | None = None,
    radius: str = "md",
    card_style: str = "outlined",
    density: str = "default",
    content_width: str = "md",
) -> App:
    """Create a new zuzu app.

    Usage:
        app = zuzu.app("My CRM", records=[clients, deals])
        app.run()

    Theming:
        app = zuzu.app("My CRM", records=[...], accent="blue", nav="sidebar", icon="💼")
    """
    global _current_app
    a = App(name, records=records, accent=accent, theme=theme, nav=nav, icon=icon, radius=radius, card_style=card_style, density=density, content_width=content_width)
    _current_app = a
    return a
