"""Product/market card data builders."""
from __future__ import annotations

from typing import Any

from shared.sx.helpers import sx_call

from .utils import _set_prices, _price_str
from .filters import _MOBILE_SENTINEL_HS, _DESKTOP_SENTINEL_HS


# ---------------------------------------------------------------------------
# Product card data extraction
# ---------------------------------------------------------------------------

def _product_card_data(p: dict, ctx: dict) -> dict:
    """Extract data for a single product card."""
    from quart import url_for
    from shared.browser.app.csrf import generate_csrf_token
    from shared.utils import route_prefix

    prefix = route_prefix()
    slug = p.get("slug", "")
    item_href = prefix + url_for("market.browse.product.product_detail", product_slug=slug)
    hx_select = ctx.get("hx_select_search", "#main-panel")
    asset_url_fn = ctx.get("asset_url")
    cart = ctx.get("cart", [])
    selected_brands = ctx.get("selected_brands", [])
    selected_stickers = ctx.get("selected_stickers", [])
    search = ctx.get("search", "")
    user = ctx.get("user")
    csrf = generate_csrf_token()

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

    # Image labels as src URLs
    labels = p.get("labels", [])
    label_srcs = []
    if p.get("image") and callable(asset_url_fn):
        label_srcs = [asset_url_fn("labels/" + l + ".svg") for l in labels]

    # Stickers as data
    raw_stickers = p.get("stickers", [])
    sticker_data = []
    if raw_stickers and callable(asset_url_fn):
        for s in raw_stickers:
            ring = " ring-2 ring-emerald-500 rounded" if s in selected_stickers else ""
            sticker_data.append({"src": asset_url_fn(f"stickers/{s}.svg"),
                                 "name": s, "ring-cls": ring})

    # Title highlighting
    title = p.get("title", "")
    has_highlight = False
    search_pre = search_mid = search_post = ""
    if search and search.lower() in title.lower():
        idx = title.lower().index(search.lower())
        has_highlight = True
        search_pre = title[:idx]
        search_mid = title[idx:idx + len(search)]
        search_post = title[idx + len(search):]

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

    brand = p.get("brand", "")
    brand_highlight = " bg-yellow-200" if brand in selected_brands else ""

    d: dict[str, Any] = {
        "href": item_href, "hx-select": hx_select, "slug": slug,
        "image": p.get("image", ""), "brand": brand, "brand-highlight": brand_highlight,
        "special-price": sp_str, "regular-price": rp_str,
        "cart-action": cart_action, "quantity": quantity, "cart-href": cart_href, "csrf": csrf,
        "title": title, "has-like": bool(user),
    }

    if label_srcs:
        d["labels"] = label_srcs
    elif labels:
        d["labels"] = labels

    if user:
        d["liked"] = p.get("is_liked", False)
        d["like-action"] = url_for("market.browse.product.like_toggle", product_slug=slug)

    if sticker_data:
        d["stickers"] = sticker_data

    if has_highlight:
        d["has-highlight"] = True
        d["search-pre"] = search_pre
        d["search-mid"] = search_mid
        d["search-post"] = search_post

    return d


def _product_cards_sx(ctx: dict) -> str:
    """S-expression wire format for product cards — delegates to .sx defcomp."""
    from shared.utils import route_prefix

    prefix = route_prefix()
    products = ctx.get("products", [])
    page = ctx.get("page", 1)
    total_pages = ctx.get("total_pages", 1)
    current_local_href = ctx.get("current_local_href", "/")
    qs_fn = ctx.get("qs_filter")

    product_data = [_product_card_data(p, ctx) for p in products]

    next_url = ""
    if page < total_pages:
        if callable(qs_fn):
            next_qs = qs_fn({"page": page + 1})
        else:
            next_qs = f"?page={page + 1}"
        next_url = prefix + current_local_href + next_qs

    return sx_call("market-product-cards-content",
                   products=product_data,
                   page=page,
                   total_pages=total_pages,
                   next_url=next_url,
                   mobile_sentinel_hs=_MOBILE_SENTINEL_HS,
                   desktop_sentinel_hs=_DESKTOP_SENTINEL_HS)


def _like_button_data(slug: str, liked: bool, csrf: str, ctx: dict) -> dict:
    """Extract like button data."""
    from quart import url_for
    action = url_for("market.browse.product.like_toggle", product_slug=slug)
    icon_cls = "fa-solid fa-heart text-red-500" if liked else "fa-regular fa-heart text-stone-400"
    return {
        "form-id": f"like-{slug}",
        "action": action,
        "slug": slug,
        "csrf": csrf,
        "icon-cls": icon_cls,
    }


# ---------------------------------------------------------------------------
# Market cards data extraction
# ---------------------------------------------------------------------------

def _market_card_data(market: Any, page_info: dict, *, show_page_badge: bool = True,
                      post_slug: str = "") -> dict:
    """Extract data for a single market card."""
    from shared.infrastructure.urls import market_url

    name = getattr(market, "name", "")
    description = getattr(market, "description", "")
    slug = getattr(market, "slug", "")
    container_id = getattr(market, "container_id", None)

    href = ""
    badge_href = ""
    badge_title = ""

    if show_page_badge and page_info:
        pi = page_info.get(container_id, {})
        p_slug = pi.get("slug", "")
        p_title = pi.get("title", "")
        href = market_url(f"/{p_slug}/{slug}/") if p_slug else ""
        if p_title:
            badge_href = market_url(f"/{p_slug}/")
            badge_title = p_title
    else:
        p_slug = post_slug
        href = market_url(f"/{post_slug}/{slug}/") if post_slug else ""

    return {
        "name": name,
        "description": description,
        "href": href,
        "show-badge": show_page_badge,
        "badge-href": badge_href,
        "badge-title": badge_title,
    }


def _market_cards_sx(markets: list, page_info: dict, page: int, has_more: bool,
                     next_url: str, *, show_page_badge: bool = True,
                     post_slug: str = "") -> str:
    """Build market cards as sx — delegates to .sx defcomp."""
    market_data = [_market_card_data(m, page_info, show_page_badge=show_page_badge,
                                     post_slug=post_slug) for m in markets]
    return sx_call("market-cards-content",
                   markets=market_data,
                   page=page,
                   has_more=has_more,
                   next_url=next_url)


def _markets_grid(cards_sx: str) -> str:
    """Wrap market cards in a grid as sx."""
    from shared.sx.parser import SxExpr
    return sx_call("market-markets-grid", cards=SxExpr(cards_sx))


def _no_markets_sx(message: str = "No markets available") -> str:
    """Empty state for markets as sx."""
    return sx_call("empty-state", icon="fa fa-store", message=message,
                   cls="px-3 py-12 text-center text-stone-400")


def _market_landing_content_sx(post: dict) -> str:
    """Build market landing page content — delegates to .sx defcomp."""
    return sx_call("market-landing-from-data",
                   excerpt=post.get("custom_excerpt") or None,
                   feature_image=post.get("feature_image") or None,
                   html=post.get("html") or None)
