"""Price helpers, product detail/meta data builders."""
from __future__ import annotations

from shared.sx.helpers import sx_call


# ---------------------------------------------------------------------------
# Price helpers
# ---------------------------------------------------------------------------

_SYM = {"GBP": "\u00a3", "EUR": "\u20ac", "USD": "$"}


def _price_str(val, raw, cur) -> str:
    if raw:
        return str(raw)
    if isinstance(val, (int, float)):
        return f"{_SYM.get(cur, '')}{val:.2f}"
    return str(val or "")


def _set_prices(item: dict) -> dict:
    """Extract price values from product dict (mirrors prices.html set_prices macro)."""
    oe = item.get("oe_list_price") or {}
    sp_val = item.get("special_price") or (oe.get("special") if oe else None)
    sp_raw = item.get("special_price_raw") or (oe.get("special_raw") if oe else None)
    sp_cur = item.get("special_price_currency") or (oe.get("special_currency") if oe else None)
    rp_val = item.get("regular_price") or item.get("rrp") or (oe.get("rrp") if oe else None)
    rp_raw = item.get("regular_price_raw") or item.get("rrp_raw") or (oe.get("rrp_raw") if oe else None)
    rp_cur = item.get("regular_price_currency") or item.get("rrp_currency") or (oe.get("rrp_currency") if oe else None)
    return dict(sp_val=sp_val, sp_raw=sp_raw, sp_cur=sp_cur,
                rp_val=rp_val, rp_raw=rp_raw, rp_cur=rp_cur)


# ---------------------------------------------------------------------------
# Product detail data extraction
# ---------------------------------------------------------------------------

def _product_detail_data(d: dict, ctx: dict) -> dict:
    """Extract product detail page data for .sx composition."""
    from shared.browser.app.csrf import generate_csrf_token
    from .cards import _like_button_data

    asset_url_fn = ctx.get("asset_url")
    user = ctx.get("user")
    liked_by_current_user = ctx.get("liked_by_current_user", False)
    csrf = generate_csrf_token()

    images = d.get("images", [])
    labels = d.get("labels", [])
    stickers = d.get("stickers", [])
    brand = d.get("brand", "")
    slug = d.get("slug", "")

    # Like button data
    like_data = None
    if user:
        like_data = _like_button_data(slug, liked_by_current_user, csrf, ctx)

    # Label overlay URLs
    label_urls = []
    if callable(asset_url_fn):
        label_urls = [asset_url_fn("labels/" + l + ".svg") for l in labels]

    # Image data
    image_data = [{"src": u, "alt": d.get("title", "")} for u in images] if images else []

    # Thumbnail data
    thumb_data = []
    if len(images) > 1:
        for i, u in enumerate(images):
            thumb_data.append({"title": f"Image {i+1}", "src": u, "alt": f"thumb {i+1}"})

    # Sticker items
    sticker_items = []
    if stickers and callable(asset_url_fn):
        for s in stickers:
            sticker_items.append({"src": asset_url_fn("stickers/" + s + ".svg"), "name": s})

    # Extras (unit price, case size)
    extras = []
    ppu = d.get("price_per_unit") or d.get("price_per_unit_raw")
    if ppu:
        extras.append({
            "type": "unit-price",
            "value": _price_str(d.get("price_per_unit"), d.get("price_per_unit_raw"),
                                d.get("price_per_unit_currency")),
        })
    if d.get("case_size_raw"):
        extras.append({"type": "case-size", "value": d["case_size_raw"]})

    return {
        "images": image_data or None,
        "labels": label_urls or None,
        "brand": brand,
        "like-data": like_data,
        "has-nav-buttons": len(images) > 1,
        "thumbs": thumb_data or None,
        "sticker-items": sticker_items or None,
        "extras": extras or None,
        "desc-short": d.get("description_short") or None,
        "desc-html": d.get("description_html") or None,
        "sections": d.get("sections") or None,
    }


def _product_detail_sx(d: dict, ctx: dict) -> str:
    """Build product detail content — delegates to .sx defcomp."""
    data = _product_detail_data(d, ctx)
    return sx_call("market-product-detail-from-data", **data)


# ---------------------------------------------------------------------------
# Product meta data extraction
# ---------------------------------------------------------------------------

def _product_meta_data(d: dict, ctx: dict) -> dict:
    """Extract product meta/SEO data for .sx composition."""
    import json
    from quart import request

    title = d.get("title", "")
    desc_source = d.get("description_short") or ""
    if not desc_source and d.get("description_html"):
        import re
        desc_source = re.sub(r"<[^>]+>", "", d.get("description_html", ""))
    description = desc_source.strip().replace("\n", " ")[:160]
    image_url = d.get("image") or (d.get("images", [None])[0] if d.get("images") else None)
    canonical = request.url if request else ""
    brand = d.get("brand", "")
    sku = d.get("sku", "")
    price = d.get("special_price") or d.get("regular_price") or d.get("rrp")
    price_currency = (d.get("special_price_currency") or d.get("regular_price_currency")
                      or d.get("rrp_currency"))

    # JSON-LD
    jsonld = {
        "@context": "https://schema.org",
        "@type": "Product",
        "name": title,
        "image": image_url,
        "description": description,
        "sku": sku,
        "url": canonical,
    }
    if brand:
        jsonld["brand"] = {"@type": "Brand", "name": brand}
    if price and price_currency:
        jsonld["offers"] = {
            "@type": "Offer",
            "price": price,
            "priceCurrency": price_currency,
            "url": canonical,
            "availability": "https://schema.org/InStock",
        }

    return {
        "title": title,
        "description": description,
        "canonical": canonical or None,
        "image-url": image_url or None,
        "site-title": ctx.get("base_title", ""),
        "brand": brand or None,
        "price": f"{price:.2f}" if price and price_currency else None,
        "price-currency": price_currency if price else None,
        "jsonld-json": json.dumps(jsonld),
    }


def _product_meta_sx(d: dict, ctx: dict) -> str:
    """Build product meta tags — delegates to .sx defcomp."""
    data = _product_meta_data(d, ctx)
    return sx_call("market-product-meta-from-data", **data)
