"""Calendar grid, day panels, month navigation, calendar-specific helpers."""
from __future__ import annotations

from shared.sx.helpers import (
    call_url, sx_call, render_to_sx_with_env,
    post_admin_header_sx,
)
from shared.sx.parser import SxExpr

from .utils import (
    _clear_deeper_oob, _ensure_container_nav,
    _entry_state_badge_html, _list_container,
)


# ---------------------------------------------------------------------------
# Post header helpers
# ---------------------------------------------------------------------------

async def _post_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build the post-level header row — delegates to shared sx helper."""
    from shared.sx.helpers import post_header_sx
    return await post_header_sx(ctx, oob=oob)


def _post_nav_sx(ctx: dict) -> str:
    """Post desktop nav: calendar links + container nav (markets, etc.)."""
    from quart import url_for, g

    calendars = ctx.get("calendars") or []
    select_colours = ctx.get("select_colours", "")
    current_cal_slug = getattr(g, "calendar_slug", None)

    parts = []
    for cal in calendars:
        cal_slug = getattr(cal, "slug", "") if hasattr(cal, "slug") else cal.get("slug", "")
        cal_name = getattr(cal, "name", "") if hasattr(cal, "name") else cal.get("name", "")
        href = url_for("calendar.get", calendar_slug=cal_slug)
        is_sel = (cal_slug == current_cal_slug)
        parts.append(sx_call("nav-link", href=href, icon="fa fa-calendar",
                            label=cal_name, select_colours=select_colours,
                            is_selected=is_sel))
    # Container nav fragments (markets, etc.)
    container_nav = ctx.get("container_nav", "")
    if container_nav:
        parts.append(container_nav)

    # Admin cog → blog admin for this post (cross-domain, no HTMX)
    rights = ctx.get("rights") or {}
    has_admin = rights.get("admin") if isinstance(rights, dict) else getattr(rights, "admin", False)
    if has_admin:
        post = ctx.get("post") or {}
        slug = post.get("slug", "")
        styles = ctx.get("styles") or {}
        nav_btn = styles.get("nav_button", "") if isinstance(styles, dict) else getattr(styles, "nav_button", "")
        select_colours = ctx.get("select_colours", "")
        admin_href = call_url(ctx, "blog_url", f"/{slug}/admin/")
        aclass = f"{nav_btn} {select_colours}".strip() or (
            "justify-center cursor-pointer flex flex-row items-center gap-2 "
            "rounded bg-stone-200 text-black p-3"
        )
        parts.append(
            f'<div class="relative nav-group">'
            f'<a href="{admin_href}" class="{aclass}">'
            f'<i class="fa fa-cog" aria-hidden="true"></i></a></div>'
        )

    return "".join(parts)


# ---------------------------------------------------------------------------
# Calendars header
# ---------------------------------------------------------------------------

def _calendars_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build the calendars section header row."""
    from quart import url_for
    link_href = url_for("calendars.home")
    return sx_call("menu-row-sx", id="calendars-row", level=3,
                  link_href=link_href,
                  link_label_content=sx_call("events-calendars-label"),
                  child_id="calendars-header-child", oob=oob)


# ---------------------------------------------------------------------------
# Calendar header
# ---------------------------------------------------------------------------

def _calendar_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build a single calendar's header row."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    cal_name = getattr(calendar, "name", "")
    cal_desc = getattr(calendar, "description", "") or ""

    link_href = url_for("calendar.get", calendar_slug=cal_slug)
    label_html = sx_call("events-calendar-label",
                        name=cal_name, description=cal_desc)

    # Desktop nav: slots + admin
    nav_html = _calendar_nav_sx(ctx)

    return sx_call("menu-row-sx", id="calendar-row", level=3,
                  link_href=link_href, link_label_content=label_html,
                  nav=SxExpr(nav_html) if nav_html else None, child_id="calendar-header-child", oob=oob)


def _calendar_nav_sx(ctx: dict) -> str:
    """Calendar desktop nav: Slots + admin link."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    rights = ctx.get("rights") or {}
    is_admin = getattr(rights, "admin", False) if hasattr(rights, "admin") else rights.get("admin", False)
    select_colours = ctx.get("select_colours", "")

    parts = []
    slots_href = url_for("defpage_slots_listing", calendar_slug=cal_slug)
    parts.append(sx_call("nav-link", href=slots_href, icon="fa fa-clock",
                        label="Slots", select_colours=select_colours))
    if is_admin:
        admin_href = url_for("defpage_calendar_admin", calendar_slug=cal_slug)
        parts.append(sx_call("nav-link", href=admin_href, icon="fa fa-cog",
                            select_colours=select_colours))
    return "(<> " + " ".join(parts) + ")" if parts else ""


# ---------------------------------------------------------------------------
# Day header
# ---------------------------------------------------------------------------

def _day_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build day detail header row."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day_date = ctx.get("day_date")
    if not day_date:
        return ""

    link_href = url_for(
        "calendar.day.show_day",
        calendar_slug=cal_slug,
        year=day_date.year,
        month=day_date.month,
        day=day_date.day,
    )
    label_html = sx_call("events-day-label",
                        date_str=day_date.strftime("%A %d %B %Y"))

    nav_html = _day_nav_sx(ctx)

    return sx_call("menu-row-sx", id="day-row", level=4,
                  link_href=link_href, link_label_content=label_html,
                  nav=SxExpr(nav_html) if nav_html else None, child_id="day-header-child", oob=oob)


def _day_nav_sx(ctx: dict) -> str:
    """Day desktop nav: confirmed entries scrolling menu + admin link."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day_date = ctx.get("day_date")
    confirmed_entries = ctx.get("confirmed_entries") or []
    rights = ctx.get("rights") or {}
    is_admin = getattr(rights, "admin", False) if hasattr(rights, "admin") else rights.get("admin", False)

    parts = []
    # Confirmed entries nav (scrolling menu)
    if confirmed_entries:
        entry_links = []
        for entry in confirmed_entries:
            href = url_for(
                "defpage_entry_detail",
                calendar_slug=cal_slug,
                year=day_date.year,
                month=day_date.month,
                day=day_date.day,
                entry_id=entry.id,
            )
            start = entry.start_at.strftime("%H:%M") if entry.start_at else ""
            end = f" \u2013 {entry.end_at.strftime('%H:%M')}" if entry.end_at else ""
            entry_links.append(sx_call("events-day-entry-link",
                                      href=href, name=entry.name,
                                      time_str=f"{start}{end}"))
        inner = "".join(entry_links)
        parts.append(sx_call("events-day-entries-nav", inner=SxExpr(inner)))

    if is_admin and day_date:
        admin_href = url_for(
            "defpage_day_admin",
            calendar_slug=cal_slug,
            year=day_date.year,
            month=day_date.month,
            day=day_date.day,
        )
        parts.append(sx_call("nav-link", href=admin_href, icon="fa fa-cog"))
    return "".join(parts)


# ---------------------------------------------------------------------------
# Day admin header
# ---------------------------------------------------------------------------

def _day_admin_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build day admin header row."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day_date = ctx.get("day_date")
    if not day_date:
        return ""

    link_href = url_for(
        "defpage_day_admin",
        calendar_slug=cal_slug,
        year=day_date.year,
        month=day_date.month,
        day=day_date.day,
    )
    return sx_call("menu-row-sx", id="day-admin-row", level=5,
                  link_href=link_href, link_label="admin", icon="fa fa-cog",
                  child_id="day-admin-header-child", oob=oob)


# ---------------------------------------------------------------------------
# Calendar admin header
# ---------------------------------------------------------------------------

def _calendar_admin_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build calendar admin header row with nav links."""
    from quart import url_for
    calendar = ctx.get("calendar")
    cal_slug = getattr(calendar, "slug", "") if calendar else ""
    select_colours = ctx.get("select_colours", "")

    nav_parts = []
    if cal_slug:
        for endpoint, label in [
            ("defpage_slots_listing", "slots"),
            ("calendar.admin.calendar_description_edit", "description"),
        ]:
            href = url_for(endpoint, calendar_slug=cal_slug)
            nav_parts.append(sx_call("nav-link", href=href, label=label,
                                    select_colours=select_colours))

    nav_html = "".join(nav_parts)
    return sx_call("menu-row-sx", id="calendar-admin-row", level=4,
                  link_label="admin", icon="fa fa-cog",
                  nav=SxExpr(nav_html) if nav_html else None, child_id="calendar-admin-header-child", oob=oob)


# ---------------------------------------------------------------------------
# Markets header
# ---------------------------------------------------------------------------

def _markets_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build the markets section header row."""
    from quart import url_for
    link_href = url_for("defpage_events_markets")
    return sx_call("menu-row-sx", id="markets-row", level=3,
                  link_href=link_href,
                  link_label_content=sx_call("events-markets-label"),
                  child_id="markets-header-child", oob=oob)


# ---------------------------------------------------------------------------
# Calendars main panel
# ---------------------------------------------------------------------------

def _calendars_main_panel_sx(ctx: dict) -> str:
    """Render the calendars list + create form panel."""
    from quart import url_for
    rights = ctx.get("rights") or {}
    is_admin = getattr(rights, "admin", False) if hasattr(rights, "admin") else rights.get("admin", False)
    has_access = ctx.get("has_access")
    can_create = has_access("calendars.create_calendar") if callable(has_access) else is_admin
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")

    calendars = ctx.get("calendars") or []

    form_html = ""
    if can_create:
        create_url = url_for("calendars.create_calendar")
        form_html = sx_call("crud-create-form",
                           create_url=create_url, csrf=csrf,
                           errors_id="cal-create-errors", list_id="calendars-list",
                           placeholder="e.g. Events, Gigs, Meetings", btn_label="Add calendar")

    list_html = _calendars_list_sx(ctx, calendars)
    return sx_call("crud-panel",
                  form=SxExpr(form_html), list=SxExpr(list_html),
                  list_id="calendars-list")


def _calendars_list_sx(ctx: dict, calendars: list) -> str:
    """Render the calendars list items."""
    from quart import url_for
    from shared.utils import route_prefix
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")
    prefix = route_prefix()

    if not calendars:
        return sx_call("empty-state", message="No calendars yet. Create one above.",
                      cls="text-gray-500 mt-4")

    parts = []
    for cal in calendars:
        cal_slug = getattr(cal, "slug", "")
        cal_name = getattr(cal, "name", "")
        href = prefix + url_for("calendar.get", calendar_slug=cal_slug)
        del_url = url_for("calendar.delete", calendar_slug=cal_slug)
        csrf_hdr = {"X-CSRFToken": csrf}
        parts.append(sx_call("crud-item",
                            href=href, name=cal_name, slug=cal_slug,
                            del_url=del_url, csrf_hdr=csrf_hdr,
                            list_id="calendars-list",
                            confirm_title="Delete calendar?",
                            confirm_text="Entries will be hidden (soft delete)"))
    return "".join(parts)


# ---------------------------------------------------------------------------
# Calendar month grid
# ---------------------------------------------------------------------------

def _calendar_main_panel_html(ctx: dict) -> str:
    """Render the calendar month grid."""
    from quart import url_for
    from quart import session as qsession

    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    hx_select = ctx.get("hx_select_search", "#main-panel")
    styles = ctx.get("styles") or {}
    pill_cls = getattr(styles, "pill", "") if hasattr(styles, "pill") else styles.get("pill", "")

    year = ctx.get("year", 2024)
    month = ctx.get("month", 1)
    month_name = ctx.get("month_name", "")
    weekday_names = ctx.get("weekday_names", [])
    weeks = ctx.get("weeks", [])
    prev_month = ctx.get("prev_month", 1)
    prev_month_year = ctx.get("prev_month_year", year)
    next_month = ctx.get("next_month", 1)
    next_month_year = ctx.get("next_month_year", year)
    prev_year = ctx.get("prev_year", year - 1)
    next_year = ctx.get("next_year", year + 1)
    month_entries = ctx.get("month_entries") or []
    user = ctx.get("user")
    qs = qsession if "qsession" not in ctx else ctx["qsession"]

    def nav_link(y, m):
        return url_for("calendar.get", calendar_slug=cal_slug, year=y, month=m)

    # Month navigation arrows
    nav_arrows = []
    for label, yr, mn in [
        ("\u00ab", prev_year, month),
        ("\u2039", prev_month_year, prev_month),
    ]:
        href = nav_link(yr, mn)
        nav_arrows.append(sx_call("events-calendar-nav-arrow",
                                 pill_cls=pill_cls, href=href, label=label))

    nav_arrows.append(sx_call("events-calendar-month-label",
                             month_name=month_name, year=str(year)))

    for label, yr, mn in [
        ("\u203a", next_month_year, next_month),
        ("\u00bb", next_year, month),
    ]:
        href = nav_link(yr, mn)
        nav_arrows.append(sx_call("events-calendar-nav-arrow",
                                 pill_cls=pill_cls, href=href, label=label))

    # Weekday headers
    wd_parts = []
    for wd in weekday_names:
        wd_parts.append(sx_call("events-calendar-weekday", name=wd))
    wd_html = "".join(wd_parts)

    # Day cells
    cells = []
    for week in weeks:
        for day_cell in week:
            if isinstance(day_cell, dict):
                in_month = day_cell.get("in_month", True)
                is_today = day_cell.get("is_today", False)
                day_date = day_cell.get("date")
            else:
                in_month = getattr(day_cell, "in_month", True)
                is_today = getattr(day_cell, "is_today", False)
                day_date = getattr(day_cell, "date", None)

            cell_cls = "min-h-20 sm:min-h-24 bg-white px-3 py-2 text-xs"
            if not in_month:
                cell_cls += " bg-stone-50 text-stone-400"
            if is_today:
                cell_cls += " ring-2 ring-blue-500 z-10 relative"

            # Day number link
            day_num_html = ""
            day_short_html = ""
            if day_date:
                day_href = url_for(
                    "calendar.day.show_day",
                    calendar_slug=cal_slug,
                    year=day_date.year, month=day_date.month, day=day_date.day,
                )
                day_short_html = sx_call("events-calendar-day-short",
                                        day_str=day_date.strftime("%a"))
                day_num_html = sx_call("events-calendar-day-num",
                                      pill_cls=pill_cls, href=day_href,
                                      num=str(day_date.day))

            # Entry badges for this day
            entry_badges = []
            if day_date:
                for e in month_entries:
                    if e.start_at and e.start_at.date() == day_date:
                        is_mine = (
                            (user and e.user_id == user.id)
                            or (not user and e.session_id == qs.get("calendar_sid"))
                        )
                        if e.state == "confirmed":
                            bg_cls = "bg-emerald-200 text-emerald-900" if is_mine else "bg-emerald-100 text-emerald-800"
                        else:
                            bg_cls = "bg-sky-100 text-sky-800" if is_mine else "bg-stone-100 text-stone-700"
                        state_label = (e.state or "pending").replace("_", " ")
                        entry_badges.append(sx_call("events-calendar-entry-badge",
                                                   bg_cls=bg_cls, name=e.name,
                                                   state_label=state_label))

            badges_html = "(<> " + "".join(entry_badges) + ")" if entry_badges else ""
            cells.append(sx_call("events-calendar-cell",
                                cell_cls=cell_cls, day_short=SxExpr(day_short_html),
                                day_num=SxExpr(day_num_html),
                                badges=SxExpr(badges_html) if badges_html else None))

    cells_html = "(<> " + "".join(cells) + ")"
    arrows_html = "(<> " + "".join(nav_arrows) + ")"
    wd_html = "(<> " + wd_html + ")"
    return sx_call("events-calendar-grid",
                  arrows=SxExpr(arrows_html), weekdays=SxExpr(wd_html),
                  cells=SxExpr(cells_html))


# ---------------------------------------------------------------------------
# Day main panel
# ---------------------------------------------------------------------------

def _day_main_panel_html(ctx: dict) -> str:
    """Render the day entries table + add button."""
    from quart import url_for

    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day_entries = ctx.get("day_entries") or []
    day = ctx.get("day")
    month = ctx.get("month")
    year = ctx.get("year")
    hx_select = ctx.get("hx_select_search", "#main-panel")
    styles = ctx.get("styles") or {}
    list_container = getattr(styles, "list_container", "") if hasattr(styles, "list_container") else styles.get("list_container", "")
    pill_cls = getattr(styles, "pill", "") if hasattr(styles, "pill") else styles.get("pill", "")
    tr_cls = getattr(styles, "tr", "") if hasattr(styles, "tr") else styles.get("tr", "")
    pre_action = getattr(styles, "pre_action_button", "") if hasattr(styles, "pre_action_button") else styles.get("pre_action_button", "")

    rows_html = ""
    if day_entries:
        row_parts = []
        for entry in day_entries:
            row_parts.append(_day_row_html(ctx, entry))
        rows_html = "".join(row_parts)
    else:
        rows_html = sx_call("events-day-empty-row")

    add_url = url_for(
        "calendar.day.calendar_entries.add_form",
        calendar_slug=cal_slug,
        day=day, month=month, year=year,
    )

    return sx_call("events-day-table",
                  list_container=list_container, rows=SxExpr(rows_html),
                  pre_action=pre_action, add_url=add_url)


def _day_row_html(ctx: dict, entry) -> str:
    """Render a single day table row."""
    from quart import url_for
    calendar = ctx.get("calendar")
    cal_slug = getattr(calendar, "slug", "")
    day = ctx.get("day")
    month = ctx.get("month")
    year = ctx.get("year")
    hx_select = ctx.get("hx_select_search", "#main-panel")
    styles = ctx.get("styles") or {}
    pill_cls = getattr(styles, "pill", "") if hasattr(styles, "pill") else styles.get("pill", "")
    tr_cls = getattr(styles, "tr", "") if hasattr(styles, "tr") else styles.get("tr", "")

    entry_href = url_for(
        "defpage_entry_detail",
        calendar_slug=cal_slug, day=day, month=month, year=year, entry_id=entry.id,
    )

    # Name
    name_html = sx_call("events-day-row-name",
                       href=entry_href, pill_cls=pill_cls, name=entry.name)

    # Slot/Time
    slot = getattr(entry, "slot", None)
    if slot:
        slot_href = url_for("defpage_slot_detail", calendar_slug=cal_slug, slot_id=slot.id)
        time_start = slot.time_start.strftime("%H:%M") if slot.time_start else ""
        time_end = f" \u2192 {slot.time_end.strftime('%H:%M')}" if slot.time_end else ""
        slot_html = sx_call("events-day-row-slot",
                           href=slot_href, pill_cls=pill_cls, slot_name=slot.name,
                           time_str=f"({time_start}{time_end})")
    else:
        start = entry.start_at.strftime("%H:%M") if entry.start_at else ""
        end = f" \u2192 {entry.end_at.strftime('%H:%M')}" if entry.end_at else ""
        slot_html = sx_call("events-day-row-time", start=start, end=end)

    # State
    state = getattr(entry, "state", "pending") or "pending"
    state_badge = _entry_state_badge_html(state)
    state_td = sx_call("events-day-row-state",
                      state_id=f"entry-state-{entry.id}", badge=state_badge)

    # Cost
    cost = getattr(entry, "cost", None)
    cost_str = f"\u00a3{cost:.2f}" if cost is not None else "\u00a30.00"
    cost_td = sx_call("events-day-row-cost", cost_str=cost_str)

    # Tickets
    tp = getattr(entry, "ticket_price", None)
    if tp is not None:
        tc = getattr(entry, "ticket_count", None)
        tc_str = f"{tc} tickets" if tc is not None else "Unlimited"
        tickets_td = sx_call("events-day-row-tickets",
                            price_str=f"\u00a3{tp:.2f}", count_str=tc_str)
    else:
        tickets_td = sx_call("events-day-row-no-tickets")

    actions_td = sx_call("events-day-row-actions")

    return sx_call("events-day-row",
                  tr_cls=tr_cls, name=name_html, slot=slot_html,
                  state=state_td, cost=cost_td,
                  tickets=tickets_td, actions=actions_td)


# ---------------------------------------------------------------------------
# Day admin main panel
# ---------------------------------------------------------------------------

def _day_admin_main_panel_html(ctx: dict) -> str:
    """Render day admin panel (placeholder nav)."""
    return sx_call("events-day-admin-panel")


# ---------------------------------------------------------------------------
# Calendar admin main panel
# ---------------------------------------------------------------------------

def _calendar_admin_main_panel_html(ctx: dict) -> str:
    """Render calendar admin config panel with description editor."""
    from quart import url_for
    calendar = ctx.get("calendar")
    if not calendar:
        return ""
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")
    cal_slug = getattr(calendar, "slug", "")
    desc = getattr(calendar, "description", "") or ""
    hx_select = ctx.get("hx_select_search", "#main-panel")

    desc_edit_url = url_for("calendar.admin.calendar_description_edit", calendar_slug=cal_slug)
    description_html = _calendar_description_display_html(calendar, desc_edit_url)

    return sx_call("events-calendar-admin-panel",
                  description_content=description_html, csrf=csrf,
                  description=desc)


def _calendar_description_display_html(calendar, edit_url: str) -> str:
    """Render calendar description display with edit button."""
    desc = getattr(calendar, "description", "") or ""
    return sx_call("events-calendar-description-display",
                  description=desc, edit_url=edit_url)


# ---------------------------------------------------------------------------
# Markets main panel
# ---------------------------------------------------------------------------

def _markets_main_panel_html(ctx: dict) -> str:
    """Render markets list + create form panel."""
    from quart import url_for
    rights = ctx.get("rights") or {}
    is_admin = getattr(rights, "admin", False) if hasattr(rights, "admin") else rights.get("admin", False)
    has_access = ctx.get("has_access")
    can_create = has_access("markets.create_market") if callable(has_access) else is_admin
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")
    markets = ctx.get("markets") or []

    form_html = ""
    if can_create:
        create_url = url_for("markets.create_market")
        form_html = sx_call("crud-create-form",
                           create_url=create_url, csrf=csrf,
                           errors_id="market-create-errors", list_id="markets-list",
                           placeholder="e.g. Farm Shop, Bakery", btn_label="Add market")

    list_html = _markets_list_html(ctx, markets)
    return sx_call("crud-panel",
                  form=SxExpr(form_html), list=SxExpr(list_html),
                  list_id="markets-list")


def _markets_list_html(ctx: dict, markets: list) -> str:
    """Render markets list items."""
    from quart import url_for
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")
    post = ctx.get("post") or {}
    slug = post.get("slug", "")

    if not markets:
        return sx_call("empty-state", message="No markets yet. Create one above.",
                      cls="text-gray-500 mt-4")

    parts = []
    for m in markets:
        m_slug = getattr(m, "slug", "") if hasattr(m, "slug") else m.get("slug", "")
        m_name = getattr(m, "name", "") if hasattr(m, "name") else m.get("name", "")
        market_href = call_url(ctx, "market_url", f"/{slug}/{m_slug}/")
        del_url = url_for("markets.delete_market", market_slug=m_slug)
        csrf_hdr = {"X-CSRFToken": csrf}
        parts.append(sx_call("crud-item",
                            href=market_href, name=m_name,
                            slug=m_slug, del_url=del_url,
                            csrf_hdr=csrf_hdr,
                            list_id="markets-list",
                            confirm_title="Delete market?",
                            confirm_text="Products will be hidden (soft delete)"))
    return "".join(parts)


# ---------------------------------------------------------------------------
# Calendar admin helper
# ---------------------------------------------------------------------------

async def _events_post_admin_header_sx(ctx: dict, *, oob: bool = False,
                                    selected: str = "") -> str:
    """Post-level admin row for events — delegates to shared helper."""
    slug = (ctx.get("post") or {}).get("slug", "")
    return await post_admin_header_sx(ctx, slug, oob=oob, selected=selected)
