"""8I leftover contact generation lifecycle."""
from __future__ import annotations

import json
import tempfile
from pathlib import Path

from src.domain.codegen.forms_codegen import (
    FORMS_CODEGEN_POLICY,
    classify_form_intent,
    select_forms_generation,
)
from src.domain.codegen.legacy_contact_generation import (
    ARTIFACT_CLASSIFICATION,
    CANONICAL_CONTACT_NL_PROMPTS,
    GENERATION_SOURCE_MATRIX,
    LEGACY_CONTACT_GENERATION,
    duplicate_contact_notify_generated,
    repo_has_legacy_contact_submit,
)
from src.domain.codegen.port_adapter import (
    LOCK_PATH,
    catalog_adapter_files,
    install_catalog_adapters,
)
from src.domain.codegen.prompt_wrapper import _P2HS_CLOUD_CONTRACT, _app_recipes
from src.domain.connectors.invoke_capabilities import (
    CAPABILITY_CONVERSION_PATTERN,
    FORMS_FAMILY_PLAN,
)
from src.domain.forms.composition import _contact_plan
from src.domain.forms.contact_notifications import forms_contact_notification_actions


def test_8i_tracker_and_lifecycle_contract() -> None:
    assert LEGACY_CONTACT_GENERATION["slice_id"] == "8i_legacy_contact_generation_cleanup"
    assert LEGACY_CONTACT_GENERATION["status"] == "complete"
    assert LEGACY_CONTACT_GENERATION["new_project_generation"] == "canonical_only"
    assert LEGACY_CONTACT_GENERATION["legacy_generation"] == "deprecated_for_new_projects"
    assert LEGACY_CONTACT_GENERATION["legacy_runtime"] == "compatibility_only"
    assert LEGACY_CONTACT_GENERATION["redeploy_policy"] == "preserved"
    assert LEGACY_CONTACT_GENERATION["database_schema_change_required"] is False
    assert CAPABILITY_CONVERSION_PATTERN["phase_8i_status"] == "complete"
    assert CAPABILITY_CONVERSION_PATTERN["next_program_slice"] == (
        "9_app_block_modernization"
    )
    assert FORMS_FAMILY_PLAN["next_slice"] == "9_app_block_modernization"
    assert GENERATION_SOURCE_MATRIX
    assert ARTIFACT_CLASSIFICATION["POST /api/contact"] == "supported_existing_only"


def test_new_catalog_omits_legacy_submit_and_preserves_existing() -> None:
    files = catalog_adapter_files("html")
    assert "functions/api/contact.js" not in files
    assert "functions/api/forms/[formKey]/submissions.js" in files
    with tempfile.TemporaryDirectory() as raw:
        tmp_path = Path(raw)
        install_catalog_adapters(str(tmp_path), "html", {"legacy_contact_submit": False})
        assert not (tmp_path / "functions/api/contact.js").is_file()
        assert (tmp_path / "functions/_lib/p2hs-contact.mjs").is_file()
        lock = json.loads((tmp_path / LOCK_PATH).read_text(encoding="utf-8"))
        assert lock["legacy_contact_submit"] is False
        assert repo_has_legacy_contact_submit(str(tmp_path)) is False

    with tempfile.TemporaryDirectory() as raw:
        leftover = Path(raw)
        contact = leftover / "functions" / "api" / "contact.js"
        contact.parent.mkdir(parents=True)
        contact.write_text("// existing leftover submit\n", encoding="utf-8")
        assert repo_has_legacy_contact_submit(str(leftover)) is True
        install_catalog_adapters(str(leftover), "html")
        assert (leftover / "functions/api/contact.js").is_file()
        leftover_lock = json.loads((leftover / LOCK_PATH).read_text(encoding="utf-8"))
        assert leftover_lock["legacy_contact_submit"] is True
        assert "/api/contact" in leftover_lock["routes"]


def test_nl_prompts_generate_canonical_not_legacy_contact() -> None:
    for prompt in CANONICAL_CONTACT_NL_PROMPTS:
        decision = select_forms_generation(prompt)
        assert decision.intent == "public_submission_form", prompt
        assert decision.runtime == "canonical_forms"
        assert decision.route and decision.route.startswith("POST /api/forms/")
        assert classify_form_intent(prompt) != "legacy_contact_block"
    keep = select_forms_generation("keep /api/contact for old apps")
    assert keep.runtime == "legacy_contact_adapter"
    assert "deprecated_for_new_projects" in keep.notes


def test_prompts_no_longer_recommend_legacy_as_default() -> None:
    recipes = _app_recipes()
    assert "Do not wire new UI to `submitContact`" in recipes or "Do not wire new UI" in (
        Path("src/domain/codegen/prompt_wrapper.py").read_text(encoding="utf-8")
    )
    wrapper = Path("src/domain/codegen/prompt_wrapper.py").read_text(encoding="utf-8")
    assert "Contact forms POST to `/api/contact`" not in wrapper
    assert "Wire the UI to `submitContact`" not in wrapper
    assert "Public contact forms POST /api/contact" not in wrapper
    assert "Do not generate POST /api/contact" in FORMS_CODEGEN_POLICY
    assert "Do not generate POST /api/contact" in _P2HS_CLOUD_CONTRACT
    recipe = json.loads(
        Path("src/domain/codegen/runtime/app-recipe.json").read_text(encoding="utf-8")
    )
    assert recipe["recipes"]["submit_form"]["use"].startswith("submitGeneratedForm")
    assert recipe["recipes"]["submit_form_legacy"]["status"] == "compatibility_only"


def test_new_contact_plan_does_not_duplicate_legacy_notify() -> None:
    plan = _contact_plan({"notify_to_email": "ops@example.com", "send_confirmation_email": True})
    dumped = " ".join(action.model_dump_json() for action in plan.actions)
    assert "contact_capture.admin_notify" in dumped
    assert "submitContact" not in dumped
    assert "/api/contact" not in dumped
    actions = forms_contact_notification_actions(
        {"notify_to_email": "ops@example.com", "send_confirmation_email": True}
    )
    assert len(actions) == 2
    canonical = Path("src/domain/codegen/runtime/app-recipe.json").read_text(encoding="utf-8")
    default_form = json.loads(canonical)["recipes"]["submit_form"]["use"]
    assert not duplicate_contact_notify_generated(default_form)
    assert duplicate_contact_notify_generated(
        "submitGeneratedForm({ formKey: 'contact' }); submitContact({ name: 'Ada' });"
    )


def test_starter_library_has_no_legacy_contact_route() -> None:
    root = Path("src/domain/starter_library")
    hits = []
    for path in root.rglob("*"):
        if not path.is_file():
            continue
        if path.suffix.lower() not in {".py", ".json", ".yaml", ".yml", ".md"}:
            continue
        text = path.read_text(encoding="utf-8")
        if "/api/contact" in text or "submitContact" in text or "p2hs-contact" in text:
            hits.append(path.as_posix())
    assert hits == []
