"""7D form submission runtime. Acceptance envelope only; no persistence."""
from __future__ import annotations

from datetime import UTC, datetime
from pathlib import Path

import pytest
from pydantic import ValidationError
from src.domain.connectors.invoke_capabilities import (
    CAPABILITY_CONVERSION_PATTERN,
    FORMS_FAMILY_PLAN,
    INVOKE_CAPABILITIES,
)
from src.domain.forms.canonical import (
    FORBIDDEN_PROVIDER_TOKENS,
    FormDefinition,
    FormField,
    FormSubmission,
    contact_block_compatible_definition,
    quote_request_block_compatible_definition,
)
from src.domain.forms.runtime import (
    FORMS_SUBMISSION_RUNTIME,
    SUBMISSION_ID_PREFIX,
    accept_form_submission,
)
from src.domain.forms.validation import FormConfigurationError, validate_form_values

_FIXED_AT = datetime(2026, 9, 13, 12, 0, tzinfo=UTC)
_ID_A = "fsb_" + ("a" * 32)
_ID_B = "fsb_" + ("b" * 32)


def test_7d_runtime_frozen_without_public_surface() -> None:
    assert FORMS_SUBMISSION_RUNTIME["status"] == "frozen"
    assert FORMS_SUBMISSION_RUNTIME["persistence"] is False
    assert FORMS_SUBMISSION_RUNTIME["post_submit"] is False
    assert FORMS_SUBMISSION_RUNTIME["anti_abuse"] == "deferred_7g"
    assert FORMS_SUBMISSION_RUNTIME["public_bff"] is False
    assert FORMS_SUBMISSION_RUNTIME["form_submit_capability"] is False
    assert FORMS_SUBMISSION_RUNTIME["idempotency"] == (
        "none_identical_payloads_are_distinct"
    )
    assert FORMS_SUBMISSION_RUNTIME["definition_lookup"] == (
        "caller_supplied_definition"
    )
    assert "form.submit" not in INVOKE_CAPABILITIES
    assert CAPABILITY_CONVERSION_PATTERN["phase_7_status"] == "complete"
    assert CAPABILITY_CONVERSION_PATTERN["next_program_slice"] == (
        "9_app_block_modernization"
    )
    assert FORMS_FAMILY_PLAN["slices"][3] == "7d_submission_runtime"
    assert FORMS_FAMILY_PLAN["runtime_acceptance_frozen"] is True
    assert "submission_id" not in FormSubmission.model_fields


def test_accepts_normalized_7c_values() -> None:
    definition = contact_block_compatible_definition()
    raw = {
        "name": "  Jane  ",
        "email": " Jane@Example.COM ",
        "message": "Hello",
    }
    result = accept_form_submission(
        definition,
        raw,
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.accepted is True
    assert result.errors == ()
    assert result.submission is not None
    assert result.submission.submission_id == _ID_A
    assert result.submission.accepted_at == _FIXED_AT
    assert result.submission.submission.form_key == "contact"
    assert result.submission.submission.values == {
        "name": "Jane",
        "email": "Jane@Example.COM",
        "message": "Hello",
    }
    validated = validate_form_values(definition, raw)
    assert result.submission.submission.values == validated.values


def test_rejection_reuses_7c_errors_and_allocates_no_id() -> None:
    definition = contact_block_compatible_definition()
    raw = {"email": "ada@example.com", "admin": True}
    allocated: list[str] = []

    def factory() -> str:
        allocated.append("called")
        return _ID_A

    result = accept_form_submission(
        definition,
        raw,
        submission_id_factory=factory,
        clock=lambda: _FIXED_AT,
    )
    expected = validate_form_values(definition, raw)
    assert result.accepted is False
    assert result.submission is None
    assert allocated == []
    assert [(error.field, error.code) for error in result.errors] == [
        (error.field, error.code) for error in expected.errors
    ]


def test_unknown_fields_are_not_accepted() -> None:
    definition = contact_block_compatible_definition()
    result = accept_form_submission(
        definition,
        {
            "name": "Ada",
            "email": "ada@example.com",
            "message": "Hi",
            "admin": True,
        },
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.accepted is False
    assert any(error.code == "unknown_field" for error in result.errors)


def test_number_coercion_carried_into_acceptance() -> None:
    definition = FormDefinition(
        key="sample",
        fields=[FormField(key="budget", type="number", required=True)],
    )
    ok = accept_form_submission(
        definition,
        {"budget": "42"},
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert ok.accepted is True
    assert ok.submission is not None
    assert ok.submission.submission.values["budget"] == 42
    bad = accept_form_submission(
        definition,
        {"budget": "42x"},
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert bad.accepted is False
    assert bad.errors[0].code == "invalid_number"


def test_required_checkbox_false_is_accepted() -> None:
    definition = FormDefinition(
        key="sample",
        fields=[FormField(key="subscribe", type="checkbox", required=True)],
    )
    result = accept_form_submission(
        definition,
        {"subscribe": False},
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.accepted is True
    assert result.submission is not None
    assert result.submission.submission.values["subscribe"] is False


def test_file_value_is_not_accepted() -> None:
    definition = quote_request_block_compatible_definition()
    result = accept_form_submission(
        definition,
        {
            "name": "Ada",
            "email": "ada@example.com",
            "message": "Quote",
            "attachment": "file-id",
        },
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.accepted is False
    assert result.submission is None
    assert any(error.code == "invalid_type" for error in result.errors)


def test_defaults_are_not_injected_at_runtime() -> None:
    definition = FormDefinition(
        key="sample",
        fields=[FormField(key="name", type="text", required=False, default="Ada")],
    )
    result = accept_form_submission(
        definition,
        {},
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.accepted is True
    assert result.submission is not None
    assert result.submission.submission.values == {}


def test_duplicate_payloads_get_distinct_ids() -> None:
    definition = contact_block_compatible_definition()
    payload = {
        "name": "Ada",
        "email": "ada@example.com",
        "message": "Hi",
    }
    first = accept_form_submission(
        definition,
        payload,
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    second = accept_form_submission(
        definition,
        payload,
        submission_id_factory=lambda: _ID_B,
        clock=lambda: _FIXED_AT,
    )
    assert first.accepted and second.accepted
    assert first.submission is not None and second.submission is not None
    assert first.submission.submission_id != second.submission.submission_id
    assert first.submission.submission.values == second.submission.submission.values


def test_submission_id_is_not_derived_from_payload() -> None:
    definition = contact_block_compatible_definition()
    result = accept_form_submission(
        definition,
        {
            "name": "Ada",
            "email": "ada@example.com",
            "message": "Hi",
        },
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.submission is not None
    blob = result.submission.model_dump_json()
    assert "ada@example.com" in blob
    assert result.submission.submission_id == _ID_A
    assert not result.submission.submission_id.startswith("contact")
    assert "ada@" not in result.submission.submission_id


def test_accepted_object_is_provider_neutral() -> None:
    definition = contact_block_compatible_definition()
    result = accept_form_submission(
        definition,
        {
            "name": "Ada",
            "email": "ada@example.com",
            "message": "Hi",
        },
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.submission is not None
    dumped = result.submission.model_dump()
    keys = set(dumped) | set(dumped["submission"]["values"])
    for token in FORBIDDEN_PROVIDER_TOKENS:
        assert token not in keys
    assert "webhook_url" not in keys
    assert "provider" not in keys
    assert "ip" not in keys
    assert "user_agent" not in keys
    assert SUBMISSION_ID_PREFIX == "fsb_"


def test_accepted_submission_is_frozen() -> None:
    definition = contact_block_compatible_definition()
    result = accept_form_submission(
        definition,
        {
            "name": "Ada",
            "email": "ada@example.com",
            "message": "Hi",
        },
        submission_id_factory=lambda: _ID_A,
        clock=lambda: _FIXED_AT,
    )
    assert result.submission is not None
    with pytest.raises(ValidationError):
        result.submission.submission_id = _ID_B  # type: ignore[misc]


def test_form_key_mismatch_is_configuration_error() -> None:
    definition = contact_block_compatible_definition()
    try:
        accept_form_submission(
            definition,
            {"name": "Ada"},
            form_key="quote_request",
            submission_id_factory=lambda: _ID_A,
            clock=lambda: _FIXED_AT,
        )
        raise AssertionError("expected FormConfigurationError")
    except FormConfigurationError as exc:
        assert exc.code == "form_key_mismatch"


def test_runtime_module_has_no_infrastructure_imports() -> None:
    source = Path("src/domain/forms/runtime.py").read_text(encoding="utf-8")
    forbidden = (
        "sqlalchemy",
        "src.domain.connectors",
        "src.integrations",
        "src.domain.codegen",
        "src.domain.cloud",
        "turnstile",
    )
    for token in forbidden:
        assert token not in source
    assert "validate_form_values" in source
    assert "FORM_REGISTRY" not in source
