"""Market page helpers — data-only.

All helpers return data values (dicts, lists) — no sx_call().
Markup composition lives entirely in .sx defpage and .sx defcomp files.
"""
from __future__ import annotations

from .cards import _market_card_data


# ---------------------------------------------------------------------------
# Registration
# ---------------------------------------------------------------------------

def _register_market_helpers() -> None:
    from shared.sx.pages import register_page_helpers

    register_page_helpers("market", {
        "all-markets-data": _h_all_markets_data,
        "page-markets-data": _h_page_markets_data,
        "page-admin-data": _h_page_admin_data,
        "market-home-data": _h_market_home_data,
    })


# ---------------------------------------------------------------------------
# All markets (global view)
# ---------------------------------------------------------------------------

async def _h_all_markets_data(**kw) -> dict:
    from quart import g, url_for, request
    from shared.utils import route_prefix
    from shared.services.registry import services
    from shared.infrastructure.data_client import fetch_data
    from shared.contracts.dtos import PostDTO, dto_from_dict

    page = int(request.args.get("page", 1))
    markets, has_more = await services.market.list_marketplaces(
        g.s, page=page, per_page=20,
    )

    page_info = {}
    if markets:
        post_ids = list({m.container_id for m in markets if m.container_type == "page"})
        if post_ids:
            raw_posts = await fetch_data("blog", "posts-by-ids",
                                         params={"ids": ",".join(str(i) for i in post_ids)},
                                         required=False) or []
            for raw_p in raw_posts:
                p = dto_from_dict(PostDTO, raw_p)
                page_info[p.id] = {"title": p.title, "slug": p.slug}

    if not markets:
        return {"no-markets": True}

    prefix = route_prefix()
    next_url = prefix + url_for("all_markets.markets_fragment", page=page + 1)
    market_data = [_market_card_data(m, page_info) for m in markets]

    return {
        "no-markets": False,
        "market-data": market_data,
        "market-page": page,
        "has-more": has_more,
        "next-url": next_url,
    }


# ---------------------------------------------------------------------------
# Page markets (markets for a single page)
# ---------------------------------------------------------------------------

async def _h_page_markets_data(slug=None, **kw) -> dict:
    from quart import g, url_for, request
    from shared.utils import route_prefix
    from shared.services.registry import services

    post = g.post_data["post"]
    page = int(request.args.get("page", 1))
    markets, has_more = await services.market.list_marketplaces(
        g.s, "page", post["id"], page=page, per_page=20,
    )
    post_slug = post.get("slug", "")

    if not markets:
        return {"no-markets": True}

    prefix = route_prefix()
    next_url = prefix + url_for("page_markets.markets_fragment", page=page + 1)
    market_data = [_market_card_data(m, {}, show_page_badge=False,
                                     post_slug=post_slug) for m in markets]

    return {
        "no-markets": False,
        "market-data": market_data,
        "market-page": page,
        "has-more": has_more,
        "next-url": next_url,
    }


# ---------------------------------------------------------------------------
# Page admin (CRUD panel for markets under a page)
# ---------------------------------------------------------------------------

async def _h_page_admin_data(slug=None, **kw) -> dict:
    from quart import g, url_for
    from shared.sx.page import get_template_context
    from shared.services.registry import services
    from shared.browser.app.csrf import generate_csrf_token
    from shared.utils import route_prefix

    ctx = await get_template_context()
    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("page_admin.create_market") if callable(has_access) else is_admin
    csrf = generate_csrf_token()

    post = ctx.get("post") or {}
    post_id = post.get("id")
    post_slug = post.get("slug", "")
    markets_raw = await services.market.marketplaces_for_container(g.s, "page", post_id) if post_id else []

    prefix = route_prefix()
    markets = []
    for m in markets_raw:
        m_slug = getattr(m, "slug", "") or (m.get("slug", "") if isinstance(m, dict) else "")
        m_name = getattr(m, "name", "") or (m.get("name", "") if isinstance(m, dict) else "")
        href = prefix + f"/{post_slug}/{m_slug}/"
        del_url = url_for("page_admin.delete_market", market_slug=m_slug)
        csrf_hdr = {"X-CSRFToken": csrf}
        markets.append({
            "href": href, "name": m_name, "slug": m_slug,
            "del-url": del_url, "csrf-hdr": csrf_hdr,
        })

    return {
        "can-create": can_create,
        "create-url": url_for("page_admin.create_market") if can_create else None,
        "csrf": csrf,
        "admin-markets": markets,
    }


# ---------------------------------------------------------------------------
# Market landing page
# ---------------------------------------------------------------------------

def _h_market_home_data(page_slug=None, market_slug=None, **kw) -> dict:
    from quart import g
    post_data = getattr(g, "post_data", {})
    post = post_data.get("post", {})
    return {
        "excerpt": post.get("custom_excerpt") or None,
        "feature-image": post.get("feature_image") or None,
        "html": post.get("html") or None,
    }
