"""Customer-facing composition copy. No host paths, pack slugs, or Cloud internals."""

from src.domain.app_blocks.compiler import compile_install_plan
from src.domain.app_blocks.planner import product_intent_from_spec
from src.domain.app_blocks.registry import load_default_registry
from src.domain.app_blocks.vertical_recipes import match_recipe_for_intent

_BLOCK_COPY = {
    "forms.contact": "Public contact form",
    "forms.quote_request": "Quote request form",
    "admin.shell": "Staff admin area",
    "admin.record_table": "Staff record list",
    "admin.record_detail": "Staff record detail",
    "auth.sign_in": "Sign-in",
    "auth.profile": "User profile",
    "crm.lead": "Lead pipeline",
    "crm.customer": "Customer records",
    "crm.pipeline": "Sales pipeline",
    "case.management": "Case tracking",
    "workflow.assignment": "Assignment tracking",
    "task.management": "Task tracking",
    "activity.timeline": "Activity timeline",
    "notifications.in_app": "In-app notifications",
    "files.attachments": "File attachments",
    "documents": "Documents",
    "booking.appointment": "Appointment booking",
    "catalog.product": "Product catalog",
    "orders.order": "Orders",
    "billing.invoice": "Invoices",
    "inventory.stock": "Inventory",
    "membership.member": "Membership",
    "support.ticket": "Support tickets",
    "workflow.approval": "Approval requests",
    "payments.checkout": "Checkout",
    "visualization.chart": "Charts",
    "calculation.calculator": "Calculator",
    "content.collection": "Pages & collections",
}

_GAP_COPY = {
    "google_calendar_sync": "Google Calendar sync",
    "public_self_service_booking": "Public self-service booking",
    "checkout_app_block": "Checkout",
}


def customer_composition_lists(payload: dict | None) -> dict:
    """Customer Discovery copy. Planner ids stay off this dict."""
    payload = payload or {}
    return {
        "building": [str(item) for item in payload.get("building") or [] if item],
        "later": [str(item) for item in payload.get("later") or [] if item],
    }


def public_composition(
    spec: dict | None,
    *,
    source_prompt: str = "",
    composition_recipe=None,
) -> dict:
    if not spec:
        return {"building": [], "later": []}
    registry = load_default_registry()
    plan = compile_install_plan(
        spec, source_prompt=source_prompt, composition_recipe=composition_recipe
    )
    recipe = match_recipe_for_intent(
        product_intent_from_spec(spec, source_prompt=source_prompt)
    )
    # YAML public labels belong to that YAML recipe. A pinned DB recipe with a
    # different slug must not borrow them.
    use_yaml_labels = recipe is not None and recipe.id == plan.matched_recipe_id
    building = []
    seen: set[str] = set()
    for block in plan.blocks:
        label = recipe.public_labels.get(block.id) if use_yaml_labels else None
        label = label or _BLOCK_COPY.get(block.id) or (
            registry.get(block.id).title if registry.get(block.id) else None
        )
        if label and label not in seen:
            seen.add(label)
            building.append(label)
    later = []
    for gap in plan.gaps:
        if gap.severity != "build_blocking":
            continue
        label = _GAP_COPY.get(gap.id) or gap.message
        if label and label not in later:
            later.append(label)
    return {"building": building, "later": later}


def customer_composition_for_spec(
    spec: dict | None,
    *,
    source_prompt: str = "",
    composition_recipe=None,
) -> dict:
    return customer_composition_lists(
        public_composition(
            spec, source_prompt=source_prompt, composition_recipe=composition_recipe
        )
    )
