"""Architecture Lane Orders production-path planner smoke.

Exercises the same Core path production Discovery uses after a turn:
customer initial_prompt + paraphrased spec → planner → public_composition.
Does not create production projects or call OpenAI.
Does not invent an Orders recipe family.
"""

from __future__ import annotations

import json
from datetime import UTC, datetime
from pathlib import Path

from src.domain.app_blocks.planner import product_intent_from_spec, select_capabilities
from src.domain.app_blocks.vertical_recipes import load_recipe_catalogs, load_recipes, match_recipe_for_intent
from src.domain.projects.discovery_schemas import (
    Actor,
    AuthenticationSpec,
    DiscoverySpec,
    Entity,
    ProductDefinition,
    TenancySpec,
    Workflow,
)

ROOT = Path(__file__).resolve().parents[1]
RECEIPT = ROOT / "src/domain/app_blocks/recipes/orders_freeze.receipt.txt"

GATED = (
    "payments.checkout",
    "billing.invoice",
    "inventory.stock",
    "membership.portal",
)

SMOKE = (
    ("Staff manage customer orders", None, ("orders.order",)),
    ("Show customer order history", None, ("orders.order",)),
    ("Staff manage customer orders. No checkout, billing, or inventory.", None, ("orders.order",)),
    ("Staff product catalog and customer orders. No checkout.", None, ("catalog.product", "orders.order")),
)

CONTROLS = (
    ("Staff manage a product catalog. No checkout, orders, or billing.", None, ("catalog.product",)),
    ("appointment booking", None, ("booking.appointment",)),
    ("student admissions CRM", "student_admissions", ("crm.customer", "case.management")),
)

NEGATIVES = (
    (
        "Our sales office maintains catalog items in a shared list. "
        "Employees should sign in, add items and correct descriptions. Do not create orders.",
        None,
        "orders.order",
    ),
    (
        "A small catering business needs a quotation page. Visitors enter event details "
        "and our staff review the saved requests. No ordering system yet.",
        None,
        "orders.order",
    ),
    ("Shopify orders and Salesforce order sync", None, "orders.order"),
    ("Paid invoices and refunds", None, "orders.order"),
    ("Build a Stripe checkout", None, "orders.order"),
)


def _spec(prompt: str) -> DiscoverySpec:
    return DiscoverySpec(
        product=ProductDefinition(
            purpose="track records for a consultancy",
            first_build_goal="Staff review submitted records",
        ),
        original_intent=prompt,
        actors=[Actor(id="staff", name="Staff counselor")],
        workflows=[Workflow(id="review", name="Staff review", description="Review records")],
        entities=[Entity(id="record", name="Record", description="A record")],
        tenancy=TenancySpec(model="single_workspace"),
        authentication=AuthenticationSpec(required=False),
    )


def _ids(prompt: str) -> set[str]:
    intent = product_intent_from_spec(_spec(prompt), source_prompt=prompt)
    return {block_id for _cap, block_id, _reason in select_capabilities(intent)}


def _recipe(prompt: str):
    return match_recipe_for_intent(product_intent_from_spec(_spec(prompt), source_prompt=prompt))


def run_smoke() -> dict:
    rows = []
    failures = []
    live = {recipe.id for recipe in load_recipes(composition_ready_only=True)}
    flags = {
        catalog.batch: catalog.ready_for_fast_lane_composition
        for catalog in load_recipe_catalogs()
    }
    on_disk_orders = [
        recipe.id
        for catalog in load_recipe_catalogs()
        for recipe in catalog.recipes
        if catalog.batch != "marketing_coverage"
        and ("order" in recipe.id or catalog.batch.startswith("orders"))
    ]
    for prompt, expected, required in SMOKE:
        recipe = _recipe(prompt)
        ids = _ids(prompt)
        matched = None if recipe is None else recipe.id
        ok = set(required) <= ids and matched == expected
        ok = ok and not (ids & set(GATED))
        if "catalog.product" not in required:
            ok = ok and "catalog.product" not in ids
        if not ok:
            failures.append(prompt)
        rows.append(
            {
                "prompt": prompt,
                "kind": "smoke",
                "matched": matched,
                "expected": expected,
                "ids": sorted(ids),
                "pass": ok,
            }
        )
    for prompt, expected, required in CONTROLS:
        recipe = _recipe(prompt)
        ids = _ids(prompt)
        matched = None if recipe is None else recipe.id
        if expected is None:
            ok = recipe is None and set(required) <= ids
        else:
            ok = matched == expected and set(required) <= ids
        ok = ok and "orders.order" not in ids
        ok = ok and not (ids & set(GATED))
        if not ok:
            failures.append(prompt)
        rows.append(
            {
                "prompt": prompt,
                "kind": "control",
                "matched": matched,
                "expected_recipe": expected,
                "ids": sorted(ids),
                "pass": ok,
            }
        )
    for prompt, expected, stripped in NEGATIVES:
        recipe = _recipe(prompt)
        ids = _ids(prompt)
        matched = None if recipe is None else recipe.id
        ok = matched == expected and stripped not in ids
        if not ok:
            failures.append(prompt)
        rows.append(
            {
                "prompt": prompt,
                "kind": "negative",
                "matched": matched,
                "stripped": stripped,
                "ids": sorted(ids),
                "pass": ok,
            }
        )
    payload = {
        "generated_at": datetime.now(UTC).isoformat(),
        "live_recipes": len(live),
        "booking_selectable": flags.get("booking_03") is True,
        "catalog_selectable": flags.get("catalog_04") is True,
        "on_disk_orders_recipes": on_disk_orders,
        "failures": failures,
        "pass": not failures and on_disk_orders == [],
        "rows": rows,
    }
    if on_disk_orders:
        payload["failures"] = [*failures, "on_disk_orders_recipes"]
        payload["pass"] = False
    return payload


def main() -> int:
    payload = run_smoke()
    print(json.dumps({k: payload[k] for k in payload if k != "rows"}, indent=2))
    for row in payload["rows"]:
        mark = "PASS" if row["pass"] else "FAIL"
        print(f"{mark} {row['kind']:8} {row['prompt']!r} matched={row.get('matched')} ids={row['ids']}")
    if RECEIPT.is_file() and payload["pass"]:
        text = RECEIPT.read_text(encoding="utf-8")
        if "production_proven=pending_this_slice" in text:
            RECEIPT.write_text(
                text.replace("production_proven=pending_this_slice", "production_proven=local_smoke_pass"),
                encoding="utf-8",
            )
    return 0 if payload["pass"] else 1


if __name__ == "__main__":
    raise SystemExit(main())
