"""Architecture Lane Orders: admit order_record independently of checkout.

No new kernel, checkout binding, cart, or Stripe fields on order_record.
"""

from pathlib import Path

import pytest
import yaml
from src.domain.app_blocks.canonical import CANONICAL_BLOCK_IDS, feature_pack_only_aliases
from src.domain.app_blocks.catalogs import FEATURE_PACK_ALIASES, default_known_packs
from src.domain.app_blocks.execution import assert_install_plan_installable
from src.domain.app_blocks.generated_product_conformance_12h import (
    KernelDeniedError,
    PlatformKernel,
)
from src.domain.app_blocks.planner import ProductIntent, select_capabilities
from src.domain.app_blocks.registry import load_default_registry
from src.domain.app_blocks.vertical_recipes import match_vertical_recipe
from src.domain.starter_library.catalog import known_contract_ids
from tests.test_phase11_pack_migration_materialization import _captured_composition

ROOT = Path(__file__).resolve().parents[1]
RECEIPT = ROOT / "src/domain/app_blocks/recipes/orders_freeze.receipt.txt"
AUDIT = ROOT / "src/domain/app_blocks/recipes/orders_architecture_audit.receipt.txt"
REGISTRY = ROOT / "src/domain/app_blocks/platform_coverage_registry.v1.yaml"
GATED_COMMERCE = (
    "payments.checkout",
    "membership.portal",
)
STARTER_SLOTS = {
    "list": "record.table",
    "detail": "record.detail",
    "create": "record.create",
    "edit": "record.edit",
    "empty": "state.empty",
}


def orders_composition():
    return _captured_composition("alembic/versions/146_order_management_pack.py", "order-management")


def _ids(intent: ProductIntent) -> set[str]:
    return {block_id for _cap, block_id, _reason in select_capabilities(intent)}


def test_orders_runtime_is_canonical_without_new_kernel():
    registry = load_default_registry()
    block = registry.require("orders.order")
    canonical = registry.canonical.require("orders.order")
    assert block.status == "implemented"
    assert "orders.order" in CANONICAL_BLOCK_IDS
    assert "orders.order" not in FEATURE_PACK_ALIASES
    assert "orders.order" not in feature_pack_only_aliases()
    assert canonical.installation.feature_packs == ("order-management",)
    primitives = {dep.id for dep in canonical.requires if dep.kind == "primitive"}
    assert primitives == {"data.entity"}
    assert "payment-checkout" not in canonical.installation.feature_packs
    assert "order-management" in default_known_packs()
    composition = orders_composition()
    entity = composition["entities"][0]
    assert entity["entity_key"] == "order_record"
    keys = {field["key"] for field in entity["schema"]["fields"]}
    assert keys == {
        "reference",
        "customer_name",
        "customer_email",
        "notes",
        "amount",
        "currency",
        "status",
    }
    assert "stripe_checkout_session_id" not in keys
    assert "stripe_payment_intent_id" not in keys
    assert "source_job_id" not in keys


def test_orders_install_plan_does_not_bind_checkout(monkeypatch):
    from src.domain.app_blocks import compiler

    registry = load_default_registry()
    monkeypatch.setattr(
        compiler,
        "select_capabilities",
        lambda _intent: [("orders_order", "orders.order", "Selected.")],
    )
    plan = compiler.compile_install_plan(None, registry=registry)
    assert_install_plan_installable(plan)
    assert "order-management" in plan.required_feature_packs
    assert "payment-checkout" not in plan.required_feature_packs
    assert "data.entity" in plan.required_primitives


def test_orders_do_not_imply_checkout_billing_or_inventory():
    ids = _ids(
        ProductIntent(
            purpose="Staff manage customer orders. No checkout, billing, or inventory.",
            source_prompt="Staff manage customer orders. No checkout, billing, or inventory.",
            staff_review=True,
        )
    )
    assert "orders.order" in ids
    assert "catalog.product" not in ids
    assert "booking.appointment" not in ids
    assert "billing.invoice" not in ids
    assert "inventory.stock" not in ids
    assert not (ids & set(GATED_COMMERCE))


def test_catalog_and_orders_compose_without_merging_stores():
    prompt = "Staff product catalog and customer orders. No checkout."
    ids = _ids(ProductIntent(purpose=prompt, source_prompt=prompt, staff_review=True))
    assert {"catalog.product", "orders.order"} <= ids
    assert "inventory.stock" not in ids
    assert not (ids & set(GATED_COMMERCE))


def test_13a_do_not_create_orders_does_not_select_orders():
    prompt = (
        "Our sales office maintains catalog items in a shared list. "
        "Employees should sign in, add items and correct descriptions. Do not create orders."
    )
    assert match_vertical_recipe(prompt) is None
    ids = _ids(ProductIntent(purpose=prompt, source_prompt=prompt, staff_review=True))
    assert "catalog.product" in ids
    assert "orders.order" not in ids


def test_orders_reuses_record_starter_contracts():
    registry = load_default_registry()
    block = registry.require("orders.order")
    contracts = {
        slot.id: slot.component_contract
        for slot in block.slots
        if slot.component_contract
    }
    assert STARTER_SLOTS.items() <= contracts.items()
    assert "order.list" not in known_contract_ids()


def test_orders_runtime_crud_is_staff_managed_records():
    kernel = PlatformKernel(namespace="orders-freeze")
    kernel.as_anonymous()
    with pytest.raises(KernelDeniedError):
        kernel.create_record("order_record", {"reference": "WO-1"})
    kernel.as_staff()
    created = kernel.create_record(
        "order_record",
        {
            "reference": "WO-1",
            "customer_name": "Ada",
            "customer_email": "ada@example.com",
            "amount": 120,
            "currency": "USD",
            "status": "open",
        },
    )
    listed = kernel.list_records("order_record")
    assert listed[0]["id"] == created["id"]
    kernel.patch_record("order_record", created["id"], {"status": "fulfilled"})
    read = kernel.get_record("order_record", created["id"])
    assert read["status"] == "fulfilled"
    assert read["reference"] == "WO-1"
    assert "stripe_checkout_session_id" not in read


def test_materialized_order_hosts_use_records_not_checkout():
    import json
    from src.domain.app_blocks.hosts import merge_host_map

    for framework in ("html", "nuxt_app", "react_app"):
        root = ROOT / "boilerplates" / framework
        hosts = merge_host_map(json.loads((root / "p2hs/app-block-hosts.json").read_text()))
        orders = {h["slot"]: h for h in hosts["hosts"] if h["block"] == "orders.order"}
        assert {"list", "detail", "create", "edit", "empty"} <= set(orders)
        for slot in ("list", "detail", "create", "edit"):
            path = orders[slot]["implementation"].partition("#")[0]
            source = (root / path).read_text(encoding="utf-8")
            assert "order_record" in source
            assert "stripe_checkout_session_id" not in source
            assert "createCheckout" not in source
            assert "/api/checkout" not in source


def test_orders_freeze_receipts_and_coverage_next_family():
    receipt = RECEIPT.read_text(encoding="utf-8")
    audit = AUDIT.read_text(encoding="utf-8")
    for required in (
        "orders_admitted=yes",
        "canonical_app_block=orders.order",
        "canonical_feature_pack=order-management",
        "orders_without_stripe=yes",
        "family_frozen=yes",
        "next_architecture_family=billing",
        "checkout_write_path_changed=no",
    ):
        assert required in receipt, required
        assert required in audit
    registry = yaml.safe_load(REGISTRY.read_text(encoding="utf-8"))
    by_id = {row["id"]: row for row in registry["capabilities"]}
    assert by_id["orders.order"]["status"] == "frozen"
    assert by_id["orders"]["status"] == "frozen"
    assert registry["family_just_frozen"] == "visualization_calculation"
    assert registry["next_architecture_family"] == "not_yet_selected"


def test_orders_production_smoke_script():
    from scripts.architecture_lane_orders_smoke import run_smoke

    payload = run_smoke()
    assert payload["pass"] is True, payload["failures"]
    assert payload["booking_selectable"] is True
    assert payload["catalog_selectable"] is True
    assert payload["on_disk_orders_recipes"] == []
