"""Events defpage setup — registers layouts, page helpers, and loads .sx pages."""
from __future__ import annotations

from typing import Any


def setup_events_pages() -> None:
    """Register events-specific layouts, page helpers, and load page definitions."""
    _register_events_layouts()
    _register_events_helpers()
    _load_events_page_files()


def _load_events_page_files() -> None:
    import os
    from shared.sx.pages import load_page_dir
    load_page_dir(os.path.dirname(__file__), "events")


# ---------------------------------------------------------------------------
# Layouts
# ---------------------------------------------------------------------------

def _register_events_layouts() -> None:
    from shared.sx.layouts import register_custom_layout
    register_custom_layout("events-calendar-admin", _cal_admin_full, _cal_admin_oob)
    register_custom_layout("events-slots", _slots_full, _slots_oob)
    register_custom_layout("events-slot", _slot_full, _slot_oob)
    register_custom_layout("events-day-admin", _day_admin_full, _day_admin_oob)
    register_custom_layout("events-entry", _entry_full, _entry_oob)
    register_custom_layout("events-entry-admin", _entry_admin_full, _entry_admin_oob)
    register_custom_layout("events-ticket-types", _ticket_types_full, _ticket_types_oob)
    register_custom_layout("events-ticket-type", _ticket_type_full, _ticket_type_oob)
    register_custom_layout("events-markets", _markets_full, _markets_oob)


# --- Calendar admin layout (root + post + child(post-admin + calendar + cal-admin)) ---

async def _cal_admin_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, post_admin_header_sx, header_child_sx
    from sx.sx_components import (
        _ensure_container_nav, _post_header_sx,
        _calendar_header_sx, _calendar_admin_header_sx,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    root_hdr = root_header_sx(ctx)
    post_hdr = _post_header_sx(ctx)
    admin_hdr = post_admin_header_sx(ctx, slug, selected="calendars")
    child = admin_hdr + _calendar_header_sx(ctx) + _calendar_admin_header_sx(ctx)
    return root_hdr + post_hdr + header_child_sx(child)


async def _cal_admin_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import post_admin_header_sx, oob_header_sx
    from sx.sx_components import (
        _ensure_container_nav, _calendar_header_sx,
        _calendar_admin_header_sx, _clear_deeper_oob,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    oobs = (post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
            + _calendar_header_sx(ctx, oob=True))
    oobs += oob_header_sx("calendar-header-child", "calendar-admin-header-child",
                              _calendar_admin_header_sx(ctx))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "post-admin-row", "post-admin-header-child",
                               "calendar-row", "calendar-header-child",
                               "calendar-admin-row", "calendar-admin-header-child")
    return oobs


# --- Slots layout (same full as cal-admin but different OOB) ---

async def _slots_full(ctx: dict, **kw: Any) -> str:
    return await _cal_admin_full({**ctx, "is_admin_section": True}, **kw)


async def _slots_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import post_admin_header_sx
    from sx.sx_components import (
        _ensure_container_nav, _calendar_admin_header_sx, _clear_deeper_oob,
    )
    ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
    slug = (ctx.get("post") or {}).get("slug", "")
    oobs = (post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
            + _calendar_admin_header_sx(ctx, oob=True))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "post-admin-row", "post-admin-header-child",
                               "calendar-row", "calendar-header-child",
                               "calendar-admin-row", "calendar-admin-header-child")
    return oobs


# --- Slot detail layout (extends cal-admin with slot header) ---

async def _slot_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, post_admin_header_sx, header_child_sx
    from sx.sx_components import (
        _ensure_container_nav, _post_header_sx,
        _calendar_header_sx, _calendar_admin_header_sx, _slot_header_html,
    )
    ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
    slug = (ctx.get("post") or {}).get("slug", "")
    root_hdr = root_header_sx(ctx)
    post_hdr = _post_header_sx(ctx)
    admin_hdr = post_admin_header_sx(ctx, slug, selected="calendars")
    child = (admin_hdr + _calendar_header_sx(ctx)
             + _calendar_admin_header_sx(ctx) + _slot_header_html(ctx))
    return root_hdr + post_hdr + header_child_sx(child)


async def _slot_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import post_admin_header_sx, oob_header_sx
    from sx.sx_components import (
        _ensure_container_nav, _calendar_admin_header_sx,
        _slot_header_html, _clear_deeper_oob,
    )
    ctx = await _ensure_container_nav({**ctx, "is_admin_section": True})
    slug = (ctx.get("post") or {}).get("slug", "")
    oobs = (post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
            + _calendar_admin_header_sx(ctx, oob=True))
    oobs += oob_header_sx("calendar-admin-header-child", "slot-header-child",
                              _slot_header_html(ctx))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "post-admin-row", "post-admin-header-child",
                               "calendar-row", "calendar-header-child",
                               "calendar-admin-row", "calendar-admin-header-child",
                               "slot-row", "slot-header-child")
    return oobs


# --- Day admin layout (root + post + post-admin + child(cal + day + day-admin)) ---

async def _day_admin_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, post_admin_header_sx, header_child_sx
    from sx.sx_components import (
        _ensure_container_nav, _post_header_sx,
        _calendar_header_sx, _day_header_sx, _day_admin_header_sx,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    root_hdr = root_header_sx(ctx)
    post_hdr = _post_header_sx(ctx)
    admin_hdr = post_admin_header_sx(ctx, slug, selected="calendars")
    child = (admin_hdr + _calendar_header_sx(ctx) + _day_header_sx(ctx)
             + _day_admin_header_sx(ctx))
    return root_hdr + post_hdr + header_child_sx(child)


async def _day_admin_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import post_admin_header_sx, oob_header_sx
    from sx.sx_components import (
        _ensure_container_nav, _calendar_header_sx,
        _day_admin_header_sx, _clear_deeper_oob,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    oobs = (post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
            + _calendar_header_sx(ctx, oob=True))
    oobs += oob_header_sx("day-header-child", "day-admin-header-child",
                              _day_admin_header_sx(ctx))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "post-admin-row", "post-admin-header-child",
                               "calendar-row", "calendar-header-child",
                               "day-row", "day-header-child",
                               "day-admin-row", "day-admin-header-child")
    return oobs


# --- Entry layout (root + child(post + cal + day + entry), + menu) ---

def _entry_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, header_child_sx
    from sx.sx_components import (
        _post_header_sx, _calendar_header_sx,
        _day_header_sx, _entry_header_html,
    )
    root_hdr = root_header_sx(ctx)
    child = (_post_header_sx(ctx) + _calendar_header_sx(ctx)
             + _day_header_sx(ctx) + _entry_header_html(ctx))
    return root_hdr + header_child_sx(child)


def _entry_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import oob_header_sx
    from sx.sx_components import (
        _day_header_sx, _entry_header_html, _clear_deeper_oob,
    )
    oobs = _day_header_sx(ctx, oob=True)
    oobs += oob_header_sx("day-header-child", "entry-header-child",
                              _entry_header_html(ctx))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "calendar-row", "calendar-header-child",
                               "day-row", "day-header-child",
                               "entry-row", "entry-header-child")
    return oobs


# --- Entry admin layout (root + post + child(post-admin + cal + day + entry + entry-admin), + menu) ---

async def _entry_admin_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, post_admin_header_sx, header_child_sx
    from sx.sx_components import (
        _ensure_container_nav, _post_header_sx,
        _calendar_header_sx, _day_header_sx,
        _entry_header_html, _entry_admin_header_html,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    root_hdr = root_header_sx(ctx)
    post_hdr = _post_header_sx(ctx)
    admin_hdr = post_admin_header_sx(ctx, slug, selected="calendars")
    child = (admin_hdr + _calendar_header_sx(ctx) + _day_header_sx(ctx)
             + _entry_header_html(ctx) + _entry_admin_header_html(ctx))
    return root_hdr + post_hdr + header_child_sx(child)


async def _entry_admin_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import post_admin_header_sx, oob_header_sx
    from sx.sx_components import (
        _ensure_container_nav, _entry_header_html,
        _entry_admin_header_html, _clear_deeper_oob,
    )
    ctx = await _ensure_container_nav(ctx)
    slug = (ctx.get("post") or {}).get("slug", "")
    oobs = (post_admin_header_sx(ctx, slug, oob=True, selected="calendars")
            + _entry_header_html(ctx, oob=True))
    oobs += oob_header_sx("entry-header-child", "entry-admin-header-child",
                              _entry_admin_header_html(ctx))
    oobs += _clear_deeper_oob("post-row", "post-header-child",
                               "post-admin-row", "post-admin-header-child",
                               "calendar-row", "calendar-header-child",
                               "day-row", "day-header-child",
                               "entry-row", "entry-header-child",
                               "entry-admin-row", "entry-admin-header-child")
    return oobs


# --- Ticket types layout (extends entry admin with ticket-types header, + menu) ---

def _ticket_types_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, header_child_sx
    from sx.sx_components import (
        _post_header_sx, _calendar_header_sx, _day_header_sx,
        _entry_header_html, _entry_admin_header_html,
        _ticket_types_header_html,
    )
    root_hdr = root_header_sx(ctx)
    child = (_post_header_sx(ctx) + _calendar_header_sx(ctx)
             + _day_header_sx(ctx) + _entry_header_html(ctx)
             + _entry_admin_header_html(ctx) + _ticket_types_header_html(ctx))
    return root_hdr + header_child_sx(child)


def _ticket_types_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import oob_header_sx
    from sx.sx_components import (
        _entry_admin_header_html, _ticket_types_header_html, _clear_deeper_oob,
    )
    oobs = _entry_admin_header_html(ctx, oob=True)
    oobs += oob_header_sx("entry-admin-header-child", "ticket_types-header-child",
                              _ticket_types_header_html(ctx))
    return oobs


# --- Ticket type detail layout (extends ticket types with ticket-type header, + menu) ---

def _ticket_type_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, header_child_sx
    from sx.sx_components import (
        _post_header_sx, _calendar_header_sx, _day_header_sx,
        _entry_header_html, _entry_admin_header_html,
        _ticket_types_header_html, _ticket_type_header_html,
    )
    root_hdr = root_header_sx(ctx)
    child = (_post_header_sx(ctx) + _calendar_header_sx(ctx)
             + _day_header_sx(ctx) + _entry_header_html(ctx)
             + _entry_admin_header_html(ctx) + _ticket_types_header_html(ctx)
             + _ticket_type_header_html(ctx))
    return root_hdr + header_child_sx(child)


def _ticket_type_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import oob_header_sx
    from sx.sx_components import (
        _ticket_types_header_html, _ticket_type_header_html,
    )
    oobs = _ticket_types_header_html(ctx, oob=True)
    oobs += oob_header_sx("ticket_types-header-child", "ticket_type-header-child",
                              _ticket_type_header_html(ctx))
    return oobs


# --- Markets layout (root + child(post + markets)) ---

def _markets_full(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import root_header_sx, header_child_sx
    from sx.sx_components import _post_header_sx, _markets_header_sx
    root_hdr = root_header_sx(ctx)
    child = _post_header_sx(ctx) + _markets_header_sx(ctx)
    return root_hdr + header_child_sx(child)


def _markets_oob(ctx: dict, **kw: Any) -> str:
    from shared.sx.helpers import oob_header_sx
    from sx.sx_components import _post_header_sx, _markets_header_sx
    oobs = _post_header_sx(ctx, oob=True)
    oobs += oob_header_sx("post-header-child", "markets-header-child",
                              _markets_header_sx(ctx))
    return oobs


# ---------------------------------------------------------------------------
# Page helpers
# ---------------------------------------------------------------------------

def _register_events_helpers() -> None:
    from shared.sx.pages import register_page_helpers

    register_page_helpers("events", {
        "calendar-admin-content": _h_calendar_admin_content,
        "day-admin-content": _h_day_admin_content,
        "slots-content": _h_slots_content,
        "slot-content": _h_slot_content,
        "entry-content": _h_entry_content,
        "entry-menu": _h_entry_menu,
        "entry-admin-content": _h_entry_admin_content,
        "admin-menu": _h_admin_menu,
        "ticket-types-content": _h_ticket_types_content,
        "ticket-type-content": _h_ticket_type_content,
        "tickets-content": _h_tickets_content,
        "ticket-detail-content": _h_ticket_detail_content,
        "ticket-admin-content": _h_ticket_admin_content,
        "markets-content": _h_markets_content,
    })


def _h_calendar_admin_content():
    from quart import g
    return getattr(g, "calendar_admin_content", "")


def _h_day_admin_content():
    from quart import g
    return getattr(g, "day_admin_content", "")


def _h_slots_content():
    from quart import g
    return getattr(g, "slots_content", "")


def _h_slot_content():
    from quart import g
    return getattr(g, "slot_content", "")


def _h_entry_content():
    from quart import g
    return getattr(g, "entry_content", "")


def _h_entry_menu():
    from quart import g
    return getattr(g, "entry_menu", "")


def _h_entry_admin_content():
    from quart import g
    return getattr(g, "entry_admin_content", "")


def _h_admin_menu():
    from shared.sx.helpers import sx_call
    return sx_call("events-admin-placeholder-nav")


def _h_ticket_types_content():
    from quart import g
    return getattr(g, "ticket_types_content", "")


def _h_ticket_type_content():
    from quart import g
    return getattr(g, "ticket_type_content", "")


def _h_tickets_content():
    from quart import g
    return getattr(g, "tickets_content", "")


def _h_ticket_detail_content():
    from quart import g
    return getattr(g, "ticket_detail_content", "")


def _h_ticket_admin_content():
    from quart import g
    return getattr(g, "ticket_admin_content", "")


def _h_markets_content():
    from quart import g
    return getattr(g, "markets_content", "")
