"""Layout registration + header data builders."""
from __future__ import annotations

from shared.sx.helpers import sx_call

from .utils import _set_prices, _price_str


# ---------------------------------------------------------------------------
# Header data extraction — pure data, no component references
# ---------------------------------------------------------------------------

def _market_header_data(ctx: dict) -> dict:
    """Extract market header data for .sx composition."""
    from quart import url_for
    from shared.utils import route_prefix

    prefix = route_prefix()
    hx_select = ctx.get("hx_select_search", "#main-panel")
    select_colours = ctx.get("select_colours", "")
    rights = ctx.get("rights", {})
    qs = ctx.get("qs", "")
    categories = ctx.get("categories", {})

    all_href = prefix + url_for("market.browse.browse_all") + qs

    cat_data = []
    for cat, data in categories.items():
        cat_href = prefix + url_for("market.browse.browse_top", top_slug=data["slug"]) + qs
        cat_data.append({
            "href": cat_href,
            "active": cat == ctx.get("category_label", ""),
            "label": cat,
        })

    admin_href = ""
    if rights and rights.get("admin"):
        admin_href = prefix + url_for("defpage_market_admin")

    return {
        "market-title": ctx.get("market_title", ""),
        "top-slug": ctx.get("top_slug", ""),
        "sub-slug": ctx.get("sub_slug", ""),
        "link-href": url_for("defpage_market_home"),
        "categories": cat_data,
        "hx-select": hx_select,
        "select-colours": select_colours,
        "all-href": all_href,
        "all-active": ctx.get("category_label", "") == "All Products",
        "admin-href": admin_href,
    }


def _market_header_sx(ctx: dict, *, oob: bool = False) -> str:
    """Build market header as sx — delegates to .sx defcomp."""
    data = _market_header_data(ctx)
    return sx_call("market-header-from-data", oob=oob, **data)


def _product_header_data(ctx: dict, d: dict) -> dict:
    """Extract product header data for .sx composition."""
    from quart import url_for
    from shared.browser.app.csrf import generate_csrf_token

    slug = d.get("slug", "")
    hx_select = ctx.get("hx_select_search", "#main-panel")
    cart = ctx.get("cart", [])
    rights = ctx.get("rights", {})

    # Price data
    pr = _set_prices(d)
    sp_str = _price_str(pr["sp_val"], pr["sp_raw"], pr["sp_cur"]) if pr["sp_val"] else ""
    rp_str = _price_str(pr["rp_val"], pr["rp_raw"], pr["rp_cur"]) if pr["rp_val"] else ""

    # RRP
    rrp_str = ""
    rrp_raw = d.get("rrp_raw")
    rrp_val = d.get("rrp")
    case_size = d.get("case_size_count") or 1
    if rrp_raw and rrp_val:
        rrp_str = f"{rrp_raw[0]}{rrp_val * case_size:.2f}"

    # Cart state
    csrf = generate_csrf_token()
    cart_action = url_for("market.browse.product.cart", product_slug=slug)
    quantity = sum(ci.quantity for ci in cart if ci.product.slug == slug) if cart else 0
    cart_url_fn = ctx.get("cart_url")
    cart_href = cart_url_fn("/") if callable(cart_url_fn) else "/"

    admin_href = ""
    if rights and rights.get("admin"):
        admin_href = url_for("market.browse.product.admin", product_slug=slug)

    return {
        "title": d.get("title", ""),
        "link-href": url_for("market.browse.product.product_detail", product_slug=slug),
        "hx-select": hx_select,
        "price-data": {
            "cart-id": f"cart-{slug}",
            "cart-action": cart_action,
            "csrf": csrf,
            "quantity": quantity,
            "cart-href": cart_href,
            "sp-val": pr["sp_val"] or "",
            "sp-str": sp_str,
            "rp-val": pr["rp_val"] or "",
            "rp-str": rp_str,
            "rrp-str": rrp_str,
        },
        "admin-href": admin_href,
    }


def _product_header_sx(ctx: dict, d: dict, *, oob: bool = False) -> str:
    """Build product header as sx — delegates to .sx defcomp."""
    data = _product_header_data(ctx, d)
    return sx_call("market-product-header-from-data", oob=oob, **data)


def _product_admin_header_sx(ctx: dict, d: dict, *, oob: bool = False) -> str:
    """Build product admin header as sx — delegates to .sx defcomp."""
    from quart import url_for
    slug = d.get("slug", "")
    link_href = url_for("market.browse.product.admin", product_slug=slug)
    return sx_call("market-product-admin-header-from-data",
                   link_href=link_href, oob=oob)


# ---------------------------------------------------------------------------
# Mobile nav panel data extraction
# ---------------------------------------------------------------------------

def _mobile_nav_data(ctx: dict) -> dict:
    """Extract mobile nav panel data for .sx composition."""
    from quart import url_for
    from shared.utils import route_prefix

    prefix = route_prefix()
    categories = ctx.get("categories", {})
    qs = ctx.get("qs", "")
    top_slug = ctx.get("top_slug", "")
    sub_slug = ctx.get("sub_slug", "")
    hx_select = ctx.get("hx_select_search", "#main-panel")
    select_colours = ctx.get("select_colours", "")

    all_href = prefix + url_for("market.browse.browse_all") + qs

    cat_data = []
    for cat, data in categories.items():
        cat_slug = data.get("slug", "")
        cat_active = top_slug == cat_slug.lower() if top_slug else False
        cat_href = prefix + url_for("market.browse.browse_top", top_slug=cat_slug) + qs

        subs = data.get("subs", [])
        sub_data = []
        if subs:
            for sub in subs:
                sub_href = prefix + url_for("market.browse.browse_sub",
                                            top_slug=cat_slug, sub_slug=sub["slug"]) + qs
                sub_active = cat_active and sub_slug == sub.get("slug")
                sub_label = sub.get("html_label") or sub.get("name", "")
                sub_data.append({
                    "href": sub_href,
                    "active": sub_active,
                    "label": sub_label,
                    "count": sub.get("count", 0),
                })

        cat_data.append({
            "name": cat,
            "href": cat_href,
            "active": cat_active,
            "count": data.get("count", 0),
            "subs": sub_data if sub_data else None,
        })

    return {
        "categories": cat_data,
        "all-href": all_href,
        "all-active": ctx.get("category_label", "") == "All Products",
        "hx-select": hx_select,
        "select-colours": select_colours,
    }


def _mobile_nav_panel_sx(ctx: dict) -> str:
    """Build mobile nav panel as sx — delegates to .sx defcomp."""
    data = _mobile_nav_data(ctx)
    return sx_call("market-mobile-nav-from-data", **data)


# ---------------------------------------------------------------------------
# Layout registration — all layouts delegate to .sx defcomps
# ---------------------------------------------------------------------------

def _register_market_layouts() -> None:
    from shared.sx.layouts import register_sx_layout
    register_sx_layout("market",
                       "market-browse-layout-full", "market-browse-layout-oob",
                       "market-browse-layout-mobile")
    register_sx_layout("market-admin",
                       "market-admin-layout-full", "market-admin-layout-oob")
