"""6M CRM public BFF runtime truth. No new CRM semantics."""
from __future__ import annotations

from pathlib import Path
from uuid import uuid4

from src.domain.connectors.catalog import get_action, slugs_implementing
from src.domain.connectors.crm_association import resolve_crm_association
from src.domain.connectors.crm_company import resolve_crm_company
from src.domain.connectors.crm_contact import resolve_crm_contact, to_public_crm_contact_result
from src.domain.connectors.crm_deal import resolve_crm_deal
from src.domain.connectors.crm_events import FROZEN_CRM_EVENT_TYPES
from src.domain.connectors.crm_resolve import CRMConnectionSnapshot
from src.domain.connectors.invoke_capabilities import (
    CAPABILITY_CONVERSION_PATTERN,
    CRM_FAMILY_PLAN,
    CRM_PUBLIC_INVOKE_VERBS,
    CRM_PUBLIC_RUNTIME_PHASE_6M,
    INVOKE_CAPABILITIES,
    catalog_consistency_issues,
    capability_surface,
    is_implemented,
)
from src.domain.connectors.public_gateway import (
    BFF_MUST_NOT,
    PHASE_6_STATUS,
    PUBLIC_INVOCABLE_CAPABILITIES,
    is_public_bff_proxy_capability,
    public_capability_invoke_method,
    strip_capability_response,
)
from src.domain.connectors.router import capability_router
from src.main import app

_CAPS = {"integrations.execute"}
_DASH_BFF = (
    Path(__file__).resolve().parents[2]
    / "P2HS-Dash"
    / "server"
    / "api"
    / "projects"
    / "[projectId]"
    / "capabilities"
    / "[capability].post.ts"
)

_EXPECTED_IMPLEMENTS = {
    "hubspot.create_contact": ("crm.contact.create",),
    "hubspot.get_contact": ("crm.contact.get",),
    "hubspot.update_contact": ("crm.contact.update",),
    "hubspot.upsert_contact": ("crm.contact.upsert",),
    "hubspot.search_contacts": ("crm.contact.search",),
    "hubspot.create_company": ("crm.company.create",),
    "hubspot.update_company": ("crm.company.update",),
    "hubspot.get_company": ("crm.company.get",),
    "hubspot.search_companies": ("crm.company.search",),
    "hubspot.create_deal": ("crm.deal.create",),
    "hubspot.update_deal": ("crm.deal.update",),
    "hubspot.get_deal": ("crm.deal.get",),
    "hubspot.search_deals": ("crm.deal.search",),
    "hubspot.associate_objects": ("crm.association.create",),
    "salesforce.create_contact": ("crm.contact.create",),
    "salesforce.get_contact": ("crm.contact.get",),
    "salesforce.update_contact": ("crm.contact.update", "crm.association.create"),
    "salesforce.upsert_contact": ("crm.contact.upsert",),
    "salesforce.search_contacts": ("crm.contact.search",),
    "salesforce.create_account": ("crm.company.create",),
    "salesforce.update_account": ("crm.company.update",),
    "salesforce.get_account": ("crm.company.get",),
    "salesforce.search_accounts": ("crm.company.search",),
    "salesforce.create_opportunity": ("crm.deal.create",),
    "salesforce.update_opportunity": ("crm.deal.update", "crm.association.create"),
    "salesforce.get_opportunity": ("crm.deal.get",),
    "salesforce.search_opportunities": ("crm.deal.search",),
}


def _crm(provider: str, **overrides) -> CRMConnectionSnapshot:
    data = dict(
        connection_id=uuid4(),
        connector_key=provider,
        status="active",
        has_secrets=True,
        permission_mode="allow",
        execution_domain="C",
        requires_secrets=True,
        client_side_only=False,
    )
    data.update(overrides)
    return CRMConnectionSnapshot(**data)


def test_6m_closes_public_runtime_truth() -> None:
    assert PHASE_6_STATUS == "6p_complete"
    assert CAPABILITY_CONVERSION_PATTERN["phase_6_status"] == "6p_complete"
    assert CAPABILITY_CONVERSION_PATTERN["next_program_slice"] == "9_app_block_modernization"
    assert CRM_FAMILY_PLAN["status"] == "6p_complete"
    assert CRM_FAMILY_PLAN["next_slice"] == "forms_first_class_product_domain"
    assert CRM_PUBLIC_RUNTIME_PHASE_6M["status"] == "complete"
    assert CRM_PUBLIC_RUNTIME_PHASE_6M["invoke_count"] == 14
    assert CRM_PUBLIC_RUNTIME_PHASE_6M["codegen_default"] is False
    assert len(CRM_PUBLIC_INVOKE_VERBS) == 14
    assert catalog_consistency_issues() == ()


def test_fourteen_crm_verbs_are_public_default_runtime() -> None:
    paths = {getattr(route, "path", "") for route in capability_router.routes}
    app_paths = {getattr(route, "path", "") for route in app.routes}
    for verb in CRM_PUBLIC_INVOKE_VERBS:
        spec = INVOKE_CAPABILITIES[verb]
        slugs = list(slugs_implementing(verb))
        surface = capability_surface(verb, slugs)
        assert spec["status"] == "implemented"
        assert spec["invocable"] is True
        assert spec["runtime"] == "integration.execute"
        assert spec["method"] == public_capability_invoke_method(verb)
        assert is_implemented(verb) is True
        assert verb in PUBLIC_INVOCABLE_CAPABILITIES
        assert is_public_bff_proxy_capability(verb) is True
        assert surface["role"] == "default"
        assert surface["implemented_by"] == slugs
        assert any(slug.startswith("hubspot.") for slug in slugs)
        assert any(slug.startswith("salesforce.") for slug in slugs)
        expected = f"/api/projects/{{project_id}}/capabilities/{verb}"
        assert expected in paths
        assert expected in app_paths
    assert "crm.search" not in INVOKE_CAPABILITIES
    for event_type in FROZEN_CRM_EVENT_TYPES:
        assert event_type not in INVOKE_CAPABILITIES
        assert event_type not in PUBLIC_INVOCABLE_CAPABILITIES
        assert event_type not in CRM_PUBLIC_INVOKE_VERBS


def test_provider_implements_match_repository_truth() -> None:
    for slug, capabilities in _EXPECTED_IMPLEMENTS.items():
        pair = get_action(slug)
        assert pair is not None
        assert pair[1].implements == capabilities
    assert get_action("salesforce.associate_objects") is None
    assert "salesforce.associate_record" not in slugs_implementing("crm.association.create")
    assert get_action("salesforce.query_soql")[1].implements == ()
    assert get_action("salesforce.create_lead")[1].implements == ()
    assert get_action("hubspot.upsert_company")[1].implements == ()


def test_bff_proxy_file_allowlists_crm_and_forbids_second_dispatcher() -> None:
    text = _DASH_BFF.read_text(encoding="utf-8")
    for verb in CRM_PUBLIC_INVOKE_VERBS:
        assert f"'{verb}'" in text
    assert "/api/crm/" not in text
    assert "/api/integrations/crm/" not in text
    assert "/api/jobs/crm." not in text
    for item in (
        "stage_map_lookup",
        "pipeline_map_lookup",
        "soql_generation",
        "hubspot_filter_generation",
        "accountid_mapping",
        "association_type_selection",
        "provider_error_translation",
    ):
        assert item in BFF_MUST_NOT
        assert item in CAPABILITY_CONVERSION_PATTERN["bff_must_not"]


def test_public_path_preserves_6c_6i_semantics() -> None:
    hs = _crm("hubspot", config={"stage_map": {"qualified": "appointmentscheduled"}})
    sf = _crm("salesforce")
    upsert = resolve_crm_contact(
        capability="crm.contact.upsert",
        payload={"contact": {"email": "ada@example.com", "first_name": "Ada"}},
        connections=[sf],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    assert upsert.ok
    assert upsert.plan is not None
    assert upsert.plan.action == "salesforce.upsert_contact"
    company = resolve_crm_company(
        capability="crm.company.search",
        payload={"name": "Acme"},
        connections=[hs],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    assert company.ok
    assert company.plan is not None
    assert company.plan.action == "hubspot.search_companies"
    deal = resolve_crm_deal(
        capability="crm.deal.search",
        payload={"name": "Renewal", "stage": "qualified"},
        connections=[hs],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    assert deal.ok
    assert deal.plan is not None
    assert deal.plan.action == "hubspot.search_deals"
    pipeline = resolve_crm_deal(
        capability="crm.deal.create",
        payload={"deal": {"name": "Renewal", "pipeline": "sales"}},
        connections=[sf],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    assert pipeline.ok is False
    assert pipeline.reason_code == "crm_pipeline_unsupported"
    unsupported = resolve_crm_association(
        capability="crm.association.create",
        payload={
            "association": {
                "from": {"object_type": "contact", "external_id": "c1"},
                "to": {"object_type": "deal", "external_id": "d1"},
            }
        },
        connections=[hs],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    assert unsupported.ok is False
    assert unsupported.reason_code in {"crm_association_unsupported", "crm_validation_failed"}


def test_p_owned_records_cannot_satisfy_public_crm() -> None:
    owned = [
        _crm("hubspot", execution_domain="P"),
        _crm("p2hs_records", execution_domain="P"),
        _crm("lead", execution_domain="P"),
    ]
    for capability, payload, resolver in (
        (
            "crm.contact.create",
            {"contact": {"first_name": "Ada"}},
            resolve_crm_contact,
        ),
        (
            "crm.company.create",
            {"company": {"name": "Acme"}},
            resolve_crm_company,
        ),
        (
            "crm.deal.create",
            {"deal": {"name": "Renewal"}},
            resolve_crm_deal,
        ),
    ):
        result = resolver(
            capability=capability,
            payload=payload,
            connections=owned,
            enabled_capabilities=_CAPS,
            enforce_invocable=True,
        )
        assert result.reason_code == "crm_unbound"


def test_public_responses_stay_capability_shaped() -> None:
    hs = _crm("hubspot")
    created = resolve_crm_contact(
        capability="crm.contact.create",
        payload={"contact": {"first_name": "Ada"}},
        connections=[hs],
        enabled_capabilities=_CAPS,
        enforce_invocable=True,
    )
    public = to_public_crm_contact_result(
        created,
        capability="crm.contact.create",
        enqueue={"ok": True},
    )
    stripped = strip_capability_response(public.as_dict())
    assert stripped["capability"] == "crm.contact.create"
    assert stripped["status"] == "queued"
    assert "contact" not in stripped
    assert "hs_object_id" not in stripped
    failed = strip_capability_response(
        {
            "capability": "crm.deal.search",
            "status": "rejected",
            "reason_code": "crm_unbound",
            "filter_groups": [],
            "soql": "SELECT Id FROM Contact",
            "AccountId": "001",
            "dealstage": "appointmentscheduled",
            "StageName": "Prospecting",
        }
    )
    assert failed == {
        "capability": "crm.deal.search",
        "status": "rejected",
        "reason_code": "crm_unbound",
    }
