"""Ticket panels, forms, admin views, buy/adjust controls."""
from __future__ import annotations

from markupsafe import escape

from shared.sx.helpers import sx_call
from shared.sx.parser import SxExpr

from .utils import (
    _ticket_state_badge_html, _list_container, _cart_icon_oob,
)


# ---------------------------------------------------------------------------
# Ticket widget (inline +/- for entry cards)
# ---------------------------------------------------------------------------

def _ticket_widget_html(entry, qty: int, ticket_url: str, *, ctx: dict) -> str:
    """Render the inline +/- ticket widget."""
    csrf_token_val = ""
    if ctx:
        ct = ctx.get("csrf_token")
        csrf_token_val = ct() if callable(ct) else (ct or "")
    else:
        try:
            from flask_wtf.csrf import generate_csrf
            csrf_token_val = generate_csrf()
        except Exception:
            pass

    eid = entry.id
    tp = getattr(entry, "ticket_price", 0) or 0
    tgt = f"#page-ticket-{eid}"

    def _tw_form(count_val, btn_html):
        return sx_call("events-tw-form",
                      ticket_url=ticket_url, target=tgt,
                      csrf=csrf_token_val, entry_id=str(eid),
                      count_val=str(count_val), btn=btn_html)

    if qty == 0:
        inner = _tw_form(1, sx_call("events-tw-cart-plus"))
    else:
        minus = _tw_form(qty - 1, sx_call("events-tw-minus"))
        cart_icon = sx_call("events-tw-cart-icon", qty=str(qty))
        plus = _tw_form(qty + 1, sx_call("events-tw-plus"))
        inner = minus + cart_icon + plus

    return sx_call("events-tw-widget",
                  entry_id=str(eid), price=f"\u00a3{tp:.2f}",
                  inner=SxExpr(inner))


# ---------------------------------------------------------------------------
# Tickets main panel (my tickets)
# ---------------------------------------------------------------------------

def _tickets_main_panel_html(ctx: dict, tickets: list) -> str:
    """Render my tickets list."""
    from quart import url_for

    ticket_cards = []
    if tickets:
        for ticket in tickets:
            href = url_for("defpage_ticket_detail", code=ticket.code)
            entry = getattr(ticket, "entry", None)
            entry_name = entry.name if entry else "Unknown event"
            tt = getattr(ticket, "ticket_type", None)
            state = getattr(ticket, "state", "")
            cal = getattr(entry, "calendar", None) if entry else None

            time_str = ""
            if entry and entry.start_at:
                time_str = entry.start_at.strftime("%A, %B %d, %Y at %H:%M")
                if entry.end_at:
                    time_str += f" \u2013 {entry.end_at.strftime('%H:%M')}"

            ticket_cards.append(sx_call("events-ticket-card",
                                       href=href, entry_name=entry_name,
                                       type_name=tt.name if tt else None,
                                       time_str=time_str or None,
                                       cal_name=cal.name if cal else None,
                                       badge=_ticket_state_badge_html(state),
                                       code_prefix=ticket.code[:8]))

    cards_html = "".join(ticket_cards)
    return sx_call("events-tickets-panel",
                  list_container=_list_container(ctx),
                  has_tickets=bool(tickets), cards=SxExpr(cards_html))


# ---------------------------------------------------------------------------
# Ticket detail panel
# ---------------------------------------------------------------------------

def _ticket_detail_panel_html(ctx: dict, ticket) -> str:
    """Render a single ticket detail with QR code."""
    from quart import url_for

    entry = getattr(ticket, "entry", None)
    tt = getattr(ticket, "ticket_type", None)
    state = getattr(ticket, "state", "")
    code = ticket.code
    cal = getattr(entry, "calendar", None) if entry else None
    checked_in_at = getattr(ticket, "checked_in_at", None)

    bg_map = {"confirmed": "bg-emerald-50", "checked_in": "bg-blue-50", "reserved": "bg-amber-50"}
    header_bg = bg_map.get(state, "bg-stone-50")
    entry_name = entry.name if entry else "Ticket"
    back_href = url_for("defpage_my_tickets")

    # Badge with larger sizing
    badge = (_ticket_state_badge_html(state)).replace('px-2 py-0.5 text-xs', 'px-3 py-1 text-sm')

    # Time info
    time_date = entry.start_at.strftime("%A, %B %d, %Y") if entry and entry.start_at else None
    time_range = entry.start_at.strftime("%H:%M") if entry and entry.start_at else None
    if time_range and entry.end_at:
        time_range += f" \u2013 {entry.end_at.strftime('%H:%M')}"

    tt_desc = f"{tt.name} \u2014 \u00a3{tt.cost:.2f}" if tt and getattr(tt, "cost", None) else None
    checkin_str = checked_in_at.strftime("Checked in: %B %d, %Y at %H:%M") if checked_in_at else None

    qr_script = (
        f"(function(){{var c=document.getElementById('ticket-qr-{code}');"
        "if(c&&typeof QRCode!=='undefined'){"
        "var cv=document.createElement('canvas');"
        f"QRCode.toCanvas(cv,'{code}',{{width:200,margin:2,color:{{dark:'#1c1917',light:'#ffffff'}}}},function(e){{if(!e)c.appendChild(cv)}});"
        "}})()"
    )

    return sx_call("events-ticket-detail",
                  list_container=_list_container(ctx), back_href=back_href,
                  header_bg=header_bg, entry_name=entry_name,
                  badge=SxExpr(badge), type_name=tt.name if tt else None,
                  code=code, time_date=time_date, time_range=time_range,
                  cal_name=cal.name if cal else None,
                  type_desc=tt_desc, checkin_str=checkin_str,
                  qr_script=qr_script)


# ---------------------------------------------------------------------------
# Ticket admin main panel
# ---------------------------------------------------------------------------

def _ticket_admin_main_panel_html(ctx: dict, tickets: list, stats: dict) -> str:
    """Render ticket admin dashboard."""
    from quart import url_for
    csrf_token = ctx.get("csrf_token")
    csrf = csrf_token() if callable(csrf_token) else (csrf_token or "")
    lookup_url = url_for("ticket_admin.lookup")

    # Stats cards
    stats_html = ""
    for label, key, border, bg, text_cls in [
        ("Total", "total", "border-stone-200", "", "text-stone-900"),
        ("Confirmed", "confirmed", "border-emerald-200", "bg-emerald-50", "text-emerald-700"),
        ("Checked In", "checked_in", "border-blue-200", "bg-blue-50", "text-blue-700"),
        ("Reserved", "reserved", "border-amber-200", "bg-amber-50", "text-amber-700"),
    ]:
        val = stats.get(key, 0)
        lbl_cls = text_cls.replace("700", "600").replace("900", "500") if "stone" not in text_cls else "text-stone-500"
        stats_html += sx_call("events-ticket-admin-stat",
                             border=border, bg=bg, text_cls=text_cls,
                             label_cls=lbl_cls, value=str(val), label=label)

    # Ticket rows
    rows_html = ""
    for ticket in tickets:
        entry = getattr(ticket, "entry", None)
        tt = getattr(ticket, "ticket_type", None)
        state = getattr(ticket, "state", "")
        code = ticket.code

        date_html = ""
        if entry and entry.start_at:
            date_html = sx_call("events-ticket-admin-date",
                               date_str=entry.start_at.strftime("%d %b %Y, %H:%M"))

        action_html = ""
        if state in ("confirmed", "reserved"):
            checkin_url = url_for("ticket_admin.do_checkin", code=code)
            action_html = sx_call("events-ticket-admin-checkin-form",
                                 checkin_url=checkin_url, code=code, csrf=csrf)
        elif state == "checked_in":
            checked_in_at = getattr(ticket, "checked_in_at", None)
            t_str = checked_in_at.strftime("%H:%M") if checked_in_at else ""
            action_html = sx_call("events-ticket-admin-checked-in",
                                 time_str=t_str)

        rows_html += sx_call("events-ticket-admin-row",
                            code=code, code_short=code[:12] + "...",
                            entry_name=entry.name if entry else "\u2014",
                            date=SxExpr(date_html),
                            type_name=tt.name if tt else "\u2014",
                            badge=_ticket_state_badge_html(state),
                            action=SxExpr(action_html))

    return sx_call("events-ticket-admin-panel",
                  list_container=_list_container(ctx), stats=SxExpr(stats_html),
                  lookup_url=lookup_url, has_tickets=bool(tickets),
                  rows=SxExpr(rows_html))


# ---------------------------------------------------------------------------
# Public render: ticket widget
# ---------------------------------------------------------------------------

def render_ticket_widget(entry, qty: int, ticket_url: str) -> str:
    """Render the +/- ticket widget for page_summary / all_events adjust_ticket."""
    return _ticket_widget_html(entry, qty, ticket_url, ctx={})


# ---------------------------------------------------------------------------
# Ticket admin: checkin result
# ---------------------------------------------------------------------------

def render_checkin_result(success: bool, error: str | None, ticket) -> str:
    """Render checkin result: table row on success, error div on failure."""
    if not success:
        return sx_call("events-checkin-error",
                      message=error or "Check-in failed")
    if not ticket:
        return ""
    code = ticket.code
    entry = getattr(ticket, "entry", None)
    tt = getattr(ticket, "ticket_type", None)
    checked_in_at = getattr(ticket, "checked_in_at", None)
    time_str = checked_in_at.strftime("%H:%M") if checked_in_at else "Just now"

    date_html = ""
    if entry and entry.start_at:
        date_html = sx_call("events-ticket-admin-date",
                           date_str=entry.start_at.strftime("%d %b %Y, %H:%M"))

    return sx_call("events-checkin-success-row",
                  code=code, code_short=code[:12] + "...",
                  entry_name=entry.name if entry else "\u2014",
                  date=SxExpr(date_html),
                  type_name=tt.name if tt else "\u2014",
                  badge=_ticket_state_badge_html("checked_in"),
                  time_str=time_str)


# ---------------------------------------------------------------------------
# Ticket admin: lookup result
# ---------------------------------------------------------------------------

def render_lookup_result(ticket, error: str | None) -> str:
    """Render ticket lookup result: error div or ticket info card."""
    from quart import url_for
    from shared.browser.app.csrf import generate_csrf_token

    if error:
        return sx_call("events-lookup-error", message=error)
    if not ticket:
        return ""

    entry = getattr(ticket, "entry", None)
    tt = getattr(ticket, "ticket_type", None)
    state = getattr(ticket, "state", "")
    code = ticket.code
    checked_in_at = getattr(ticket, "checked_in_at", None)
    csrf = generate_csrf_token()

    # Info section
    info_html = sx_call("events-lookup-info",
                       entry_name=entry.name if entry else "Unknown event")
    if tt:
        info_html += sx_call("events-lookup-type", type_name=tt.name)
    if entry and entry.start_at:
        info_html += sx_call("events-lookup-date",
                            date_str=entry.start_at.strftime("%A, %B %d, %Y at %H:%M"))
    cal = getattr(entry, "calendar", None) if entry else None
    if cal:
        info_html += sx_call("events-lookup-cal", cal_name=cal.name)
    info_html += sx_call("events-lookup-status",
                        badge=_ticket_state_badge_html(state), code=code)
    if checked_in_at:
        info_html += sx_call("events-lookup-checkin-time",
                            date_str=checked_in_at.strftime("%B %d, %Y at %H:%M"))

    # Action area
    action_html = ""
    if state in ("confirmed", "reserved"):
        checkin_url = url_for("ticket_admin.do_checkin", code=code)
        action_html = sx_call("events-lookup-checkin-btn",
                             checkin_url=checkin_url, code=code, csrf=csrf)
    elif state == "checked_in":
        action_html = sx_call("events-lookup-checked-in")
    elif state == "cancelled":
        action_html = sx_call("events-lookup-cancelled")

    return sx_call("events-lookup-card",
                  info=SxExpr(info_html), code=code, action=SxExpr(action_html))


# ---------------------------------------------------------------------------
# Ticket admin: entry tickets table
# ---------------------------------------------------------------------------

def render_entry_tickets_admin(entry, tickets: list) -> str:
    """Render admin ticket table for a specific entry."""
    from quart import url_for
    from shared.browser.app.csrf import generate_csrf_token
    csrf = generate_csrf_token()

    count = len(tickets)
    suffix = "s" if count != 1 else ""

    rows_html = ""
    for ticket in tickets:
        tt = getattr(ticket, "ticket_type", None)
        state = getattr(ticket, "state", "")
        code = ticket.code
        checked_in_at = getattr(ticket, "checked_in_at", None)

        action_html = ""
        if state in ("confirmed", "reserved"):
            checkin_url = url_for("ticket_admin.do_checkin", code=code)
            action_html = sx_call("events-entry-tickets-admin-checkin",
                                 checkin_url=checkin_url, code=code, csrf=csrf)
        elif state == "checked_in":
            t_str = checked_in_at.strftime("%H:%M") if checked_in_at else ""
            action_html = sx_call("events-ticket-admin-checked-in",
                                 time_str=t_str)

        rows_html += sx_call("events-entry-tickets-admin-row",
                            code=code, code_short=code[:12] + "...",
                            type_name=tt.name if tt else "\u2014",
                            badge=_ticket_state_badge_html(state),
                            action=SxExpr(action_html))

    if tickets:
        body_html = sx_call("events-entry-tickets-admin-table",
                           rows=SxExpr(rows_html))
    else:
        body_html = sx_call("events-entry-tickets-admin-empty")

    return sx_call("events-entry-tickets-admin-panel",
                  entry_name=entry.name,
                  count_label=f"{count} ticket{suffix}",
                  body=body_html)


# ---------------------------------------------------------------------------
# Ticket type main panel
# ---------------------------------------------------------------------------

def render_ticket_type_main_panel(ticket_type, entry, calendar, day, month, year, *, oob: bool = False) -> str:
    """Render ticket type detail view."""
    from quart import url_for, g

    styles = getattr(g, "styles", None) or {}
    list_container = getattr(styles, "list_container", "") if hasattr(styles, "list_container") else styles.get("list_container", "")
    pre_action = getattr(styles, "pre_action_button", "") if hasattr(styles, "pre_action_button") else styles.get("pre_action_button", "")
    cal_slug = getattr(calendar, "slug", "")

    cost = getattr(ticket_type, "cost", None)
    cost_str = f"\u00a3{cost:.2f}" if cost is not None else "\u00a30.00"
    count = getattr(ticket_type, "count", 0)
    tid = str(ticket_type.id)

    edit_url = url_for(
        "calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.get_edit",
        ticket_type_id=ticket_type.id, calendar_slug=cal_slug,
        year=year, month=month, day=day, entry_id=entry.id,
    )

    def _col(label, val):
        return sx_call("events-ticket-type-col", label=label, value=val)

    return sx_call("events-ticket-type-panel",
                  ticket_id=tid, list_container=list_container,
                  c1=_col("Name", ticket_type.name),
                  c2=_col("Cost", cost_str),
                  c3=_col("Count", str(count)),
                  pre_action=pre_action, edit_url=edit_url)


# ---------------------------------------------------------------------------
# Ticket types table
# ---------------------------------------------------------------------------

def render_ticket_types_table(ticket_types, entry, calendar, day, month, year) -> str:
    """Render ticket types table with rows and add button."""
    from quart import url_for, g
    from shared.browser.app.csrf import generate_csrf_token
    csrf = generate_csrf_token()

    styles = getattr(g, "styles", None) or {}
    list_container = getattr(styles, "list_container", "") if hasattr(styles, "list_container") else styles.get("list_container", "")
    tr_cls = getattr(styles, "tr", "") if hasattr(styles, "tr") else styles.get("tr", "")
    pill_cls = getattr(styles, "pill", "") if hasattr(styles, "pill") else styles.get("pill", "")
    action_btn = getattr(styles, "action_button", "") if hasattr(styles, "action_button") else styles.get("action_button", "")
    hx_select = getattr(g, "hx_select_search", "#main-panel")
    cal_slug = getattr(calendar, "slug", "")
    eid = entry.id

    rows_html = ""
    if ticket_types:
        for tt in ticket_types:
            tt_href = url_for(
                "calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.get",
                calendar_slug=cal_slug, year=year, month=month, day=day,
                entry_id=eid, ticket_type_id=tt.id,
            )
            del_url = url_for(
                "calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.delete",
                calendar_slug=cal_slug, year=year, month=month, day=day,
                entry_id=eid, ticket_type_id=tt.id,
            )
            cost = getattr(tt, "cost", None)
            cost_str = f"\u00a3{cost:.2f}" if cost is not None else "\u00a30.00"

            rows_html += sx_call("events-ticket-types-row",
                                tr_cls=tr_cls, tt_href=tt_href,
                                pill_cls=pill_cls, hx_select=hx_select,
                                tt_name=tt.name, cost_str=cost_str,
                                count=str(tt.count), action_btn=action_btn,
                                del_url=del_url,
                                csrf_hdr={"X-CSRFToken": csrf})
    else:
        rows_html = sx_call("events-ticket-types-empty-row")

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

    return sx_call("events-ticket-types-table",
                  list_container=list_container, rows=SxExpr(rows_html),
                  action_btn=action_btn, add_url=add_url)


# ---------------------------------------------------------------------------
# Buy result (ticket purchase confirmation)
# ---------------------------------------------------------------------------

def render_buy_result(entry, created_tickets, remaining, cart_count) -> str:
    """Render buy result card with created tickets + OOB cart icon."""
    from quart import url_for

    cart_html = _cart_icon_oob(cart_count)

    count = len(created_tickets)
    suffix = "s" if count != 1 else ""

    tickets_html = ""
    for ticket in created_tickets:
        href = url_for("defpage_ticket_detail", code=ticket.code)
        tickets_html += sx_call("events-buy-result-ticket",
                               href=href, code_short=ticket.code[:12] + "...")

    remaining_html = ""
    if remaining is not None:
        r_suffix = "s" if remaining != 1 else ""
        remaining_html = sx_call("events-buy-result-remaining",
                                text=f"{remaining} ticket{r_suffix} remaining")

    my_href = url_for("defpage_my_tickets")

    return cart_html + sx_call("events-buy-result",
                              entry_id=str(entry.id),
                              count_label=f"{count} ticket{suffix} reserved",
                              tickets=SxExpr(tickets_html),
                              remaining=SxExpr(remaining_html),
                              my_tickets_href=my_href)


# ---------------------------------------------------------------------------
# Buy form (ticket +/- controls)
# ---------------------------------------------------------------------------

def render_buy_form(entry, ticket_remaining, ticket_sold_count,
                    user_ticket_count, user_ticket_counts_by_type) -> str:
    """Render the ticket buy/adjust form with +/- controls."""
    from quart import url_for
    from shared.browser.app.csrf import generate_csrf_token
    csrf = generate_csrf_token()

    eid = entry.id
    eid_s = str(eid)
    tp = getattr(entry, "ticket_price", None)
    state = getattr(entry, "state", "")
    ticket_types = getattr(entry, "ticket_types", None) or []

    if tp is None:
        return ""

    if state != "confirmed":
        return sx_call("events-buy-not-confirmed", entry_id=eid_s)

    adjust_url = url_for("tickets.adjust_quantity")
    target = f"#ticket-buy-{eid}"

    # Info line
    info_html = ""
    info_items = ""
    if ticket_sold_count:
        info_items += sx_call("events-buy-info-sold",
                             count=str(ticket_sold_count))
    if ticket_remaining is not None:
        info_items += sx_call("events-buy-info-remaining",
                             count=str(ticket_remaining))
    if user_ticket_count:
        info_items += sx_call("events-buy-info-basket",
                             count=str(user_ticket_count))
    if info_items:
        info_html = sx_call("events-buy-info-bar", items=SxExpr(info_items))

    active_types = [tt for tt in ticket_types if getattr(tt, "deleted_at", None) is None]

    body_html = ""
    if active_types:
        type_items = ""
        for tt in active_types:
            type_count = user_ticket_counts_by_type.get(tt.id, 0) if user_ticket_counts_by_type else 0
            cost_str = f"\u00a3{tt.cost:.2f}" if tt.cost is not None else "\u00a30.00"
            type_items += sx_call("events-buy-type-item",
                                 type_name=tt.name, cost_str=cost_str,
                                 adjust_controls=_ticket_adjust_controls(csrf, adjust_url, target, eid, type_count, ticket_type_id=tt.id))
        body_html = sx_call("events-buy-types-wrapper", items=SxExpr(type_items))
    else:
        qty = user_ticket_count or 0
        body_html = sx_call("events-buy-default",
                           price_str=f"\u00a3{tp:.2f}",
                           adjust_controls=_ticket_adjust_controls(csrf, adjust_url, target, eid, qty))

    return sx_call("events-buy-panel",
                  entry_id=eid_s, info=SxExpr(info_html), body=body_html)


def _ticket_adjust_controls(csrf, adjust_url, target, entry_id, count, *, ticket_type_id=None):
    """Render +/- ticket controls for buy form."""
    from quart import url_for

    tt_html = sx_call("events-adjust-tt-hidden",
                     ticket_type_id=str(ticket_type_id)) if ticket_type_id else ""
    eid_s = str(entry_id)

    def _adj_form(count_val, btn_html, *, extra_cls=""):
        return sx_call("events-adjust-form",
                      adjust_url=adjust_url, target=target,
                      extra_cls=extra_cls, csrf=csrf,
                      entry_id=eid_s, tt=tt_html or None,
                      count_val=str(count_val), btn=btn_html)

    if count == 0:
        return _adj_form(1, sx_call("events-adjust-cart-plus"),
                         extra_cls="flex items-center")

    my_tickets_href = url_for("defpage_my_tickets")
    minus = _adj_form(count - 1, sx_call("events-adjust-minus"))
    cart_icon = sx_call("events-adjust-cart-icon",
                       href=my_tickets_href, count=str(count))
    plus = _adj_form(count + 1, sx_call("events-adjust-plus"))

    return sx_call("events-adjust-controls",
                  minus=minus, cart_icon=cart_icon, plus=plus)


# ---------------------------------------------------------------------------
# Adjust response (OOB cart icon + buy form)
# ---------------------------------------------------------------------------

def render_adjust_response(entry, ticket_remaining, ticket_sold_count,
                           user_ticket_count, user_ticket_counts_by_type,
                           cart_count) -> str:
    """Render ticket adjust response: OOB cart icon + buy form."""
    cart_html = _cart_icon_oob(cart_count)
    form_html = render_buy_form(
        entry, ticket_remaining, ticket_sold_count,
        user_ticket_count, user_ticket_counts_by_type,
    )
    return cart_html + form_html


# ---------------------------------------------------------------------------
# Ticket types header rows
# ---------------------------------------------------------------------------

def _ticket_types_header_html(ctx: dict, *, oob: bool = False) -> str:
    """Build the ticket types header row."""
    from quart import url_for

    calendar = ctx.get("calendar")
    entry = ctx.get("entry")
    if not calendar or not entry:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day = ctx.get("day")
    month = ctx.get("month")
    year = ctx.get("year")

    link_href = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.get",
                         calendar_slug=cal_slug, entry_id=entry.id,
                         year=year, month=month, day=day)

    label_html = '<i class="fa fa-ticket"></i><div class="shrink-0">ticket types</div>'

    nav_html = sx_call("events-admin-placeholder-nav")

    return sx_call("menu-row-sx", id="ticket_types-row", level=7,
                  link_href=link_href, link_label_content=SxExpr(label_html),
                  nav=nav_html or None, child_id="ticket_type-header-child", oob=oob)



def _ticket_type_header_html(ctx: dict, *, oob: bool = False) -> str:
    """Build the single ticket type header row."""
    from quart import url_for

    calendar = ctx.get("calendar")
    entry = ctx.get("entry")
    ticket_type = ctx.get("ticket_type")
    if not calendar or not entry or not ticket_type:
        return ""
    cal_slug = getattr(calendar, "slug", "")
    day = ctx.get("day")
    month = ctx.get("month")
    year = ctx.get("year")

    link_href = url_for(
        "calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.get",
        calendar_slug=cal_slug, year=year, month=month, day=day,
        entry_id=entry.id, ticket_type_id=ticket_type.id,
    )

    label_html = (
        f'<div class="flex flex-col md:flex-row md:gap-2 items-center">'
        f'<div class="flex flex-row items-center gap-2">'
        f'<i class="fa fa-ticket"></i>'
        f'<div class="shrink-0">{escape(ticket_type.name)}</div>'
        f'</div></div>'
    )

    nav_html = sx_call("events-admin-placeholder-nav")

    return sx_call("menu-row-sx", id="ticket_type-row", level=8,
                  link_href=link_href, link_label_content=SxExpr(label_html),
                  nav=nav_html or None, child_id="ticket_type-header-child-inner", oob=oob)


# ---------------------------------------------------------------------------
# Ticket type edit form
# ---------------------------------------------------------------------------

def render_ticket_type_edit_form(ticket_type, entry, calendar, day, month, year) -> str:
    """Render ticket type edit form (replaces _types/ticket_type/_edit.html)."""
    from quart import url_for, g
    from shared.browser.app.csrf import generate_csrf_token
    csrf = generate_csrf_token()

    styles = getattr(g, "styles", None) or {}
    list_container = styles.get("list_container", "") if isinstance(styles, dict) else getattr(styles, "list_container", "")
    action_btn = styles.get("action_button", "") if isinstance(styles, dict) else getattr(styles, "action_button", "")
    cancel_btn = styles.get("cancel_button", "") if isinstance(styles, dict) else getattr(styles, "cancel_button", "")
    cal_slug = getattr(calendar, "slug", "")
    tid = ticket_type.id

    put_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.put",
                       calendar_slug=cal_slug, year=year, month=month, day=day,
                       entry_id=entry.id, ticket_type_id=tid)
    cancel_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.ticket_type.get_view",
                          calendar_slug=cal_slug, entry_id=entry.id,
                          year=year, month=month, day=day, ticket_type_id=tid)

    cost = getattr(ticket_type, "cost", None)
    cost_val = f"{cost:.2f}" if cost is not None else ""
    count = getattr(ticket_type, "count", 0)

    return sx_call("events-ticket-type-edit-form",
                  ticket_id=str(tid), list_container=list_container,
                  put_url=put_url, cancel_url=cancel_url, csrf=csrf,
                  name_val=ticket_type.name or "",
                  cost_val=cost_val, count_val=str(count),
                  action_btn=action_btn, cancel_btn=cancel_btn)


# ---------------------------------------------------------------------------
# Ticket type add form / button
# ---------------------------------------------------------------------------

def render_ticket_type_add_form(entry, calendar, day, month, year) -> str:
    """Render ticket type add form (replaces _types/ticket_types/_add.html)."""
    from quart import url_for, g
    from shared.browser.app.csrf import generate_csrf_token
    csrf = generate_csrf_token()

    styles = getattr(g, "styles", None) or {}
    action_btn = styles.get("action_button", "") if isinstance(styles, dict) else getattr(styles, "action_button", "")
    cancel_btn = styles.get("cancel_button", "") if isinstance(styles, dict) else getattr(styles, "cancel_button", "")
    cal_slug = getattr(calendar, "slug", "")

    post_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.post",
                        calendar_slug=cal_slug, entry_id=entry.id,
                        year=year, month=month, day=day)
    cancel_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.add_button",
                          calendar_slug=cal_slug, entry_id=entry.id,
                          year=year, month=month, day=day)
    csrf_hdr = {"X-CSRFToken": csrf}

    return sx_call("events-ticket-type-add-form",
                  post_url=post_url, csrf=csrf_hdr,
                  action_btn=action_btn, cancel_btn=cancel_btn,
                  cancel_url=cancel_url)


def render_ticket_type_add_button(entry, calendar, day, month, year) -> str:
    """Render ticket type add button (replaces _types/ticket_types/_add_button.html)."""
    from quart import url_for, g

    styles = getattr(g, "styles", None) or {}
    action_btn = styles.get("action_button", "") if isinstance(styles, dict) else getattr(styles, "action_button", "")
    cal_slug = getattr(calendar, "slug", "")

    add_url = url_for("calendar.day.calendar_entries.calendar_entry.ticket_types.add_form",
                       calendar_slug=cal_slug, entry_id=entry.id,
                       year=year, month=month, day=day)

    return sx_call("events-ticket-type-add-button",
                  action_btn=action_btn, add_url=add_url)
