"""7Q Forms application fixtures. No new Forms architecture.

Proves the installed composition path:
App Block / Pack → (project_id, form_key) → ResolvedFormRuntime →
generated client envelope → installed-app BFF strip → 7N submit_form.
"""
from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Any

from src.domain.app_blocks.compiler import compile_install_plan
from src.domain.app_blocks.forms_binding import sources_from_plan_and_packs
from src.domain.codegen.forms_adapter import forms_adapter_files
from src.domain.codegen.forms_codegen import (
    classify_form_intent,
    generic_forms_snippet_leaks,
    project_client_form_config,
    select_forms_generation,
)
from src.domain.forms.actions import RecordingCapabilityInvoker
from src.domain.forms.anti_abuse import InMemoryAttemptLimiter, StaticChallengeVerifier
from src.domain.forms.composition import (
    CompositionFormRuntimeStore,
    FormBindingSource,
    InstalledPackView,
    OverlayFormRuntimeStore,
    collect_form_binding_sources,
    publish_form_readiness,
    resolve_form_bindings,
)
from src.domain.forms.email_template import RecordingEmailTemplateRenderer
from src.domain.forms.files import FormFileRecord, InMemoryFormFileDirectory
from src.domain.forms.persistence import InMemoryFormSubmissionStore
from src.domain.forms.public import (
    FormPublicResult,
    InMemoryFormRuntimeStore,
    UnwiredChallengeVerifier,
    parse_public_submit_request,
    submit_form,
)
from src.domain.projects.discovery_schemas import (
    Actor,
    AuthenticationSpec,
    DiscoverySpec,
    Entity,
    ProductDefinition,
    TenancySpec,
    Workflow,
)

CODEGEN_RUNTIME = Path("src/domain/codegen/runtime")
PUBLISH_READINESS_DEPLOY_GAP = "function_exists_core_deploy_does_not_enforce"

FORMS_END_TO_END_PHASE_7Q: dict[str, Any] = {
    "slice_id": "7q_end_to_end_application_tests",
    "status": "frozen",
    "new_architecture": False,
    "schema_migration": False,
    "form_submit_capability": False,
    "publish_form_readiness_deploy": PUBLISH_READINESS_DEPLOY_GAP,
    "live_provider_http": "delegated_to_existing_crm_and_email_runtimes",
    "docs": "docs/audits/FORMS_END_TO_END_7Q.md",
}

BROWSER_LEAK_TOKENS: tuple[str, ...] = (
    "persist_first",
    "post_submit_plan",
    "provider_hint",
    "hubspot.create_contact",
    "salesforce.create_contact",
    "P2HS_CORE_URL",
    "CLOUD_SERVICE_TOKEN",
    "beapipie",
    "/capabilities/crm.contact.upsert",
    "/capabilities/email.send",
    "/capabilities/automation.workflow.trigger",
    "hooks.make.com",
    "api.hubapi.com",
)

CONTACT_VALUES: dict[str, Any] = {
    "name": "Ada Lovelace",
    "email": "ada@example.com",
    "phone": "+1 555 0100",
    "message": "Please call me",
}


def _spec(*, purpose: str, goal: str, archetypes: list[str]) -> DiscoverySpec:
    return DiscoverySpec(
        product=ProductDefinition(
            name="Site",
            name_status="working",
            purpose=purpose,
            first_build_goal=goal,
        ),
        archetypes=archetypes,
        actors=[
            Actor(id="visitor", name="Website visitor"),
            Actor(id="staff", name="Staff"),
        ],
        workflows=[
            Workflow(id="submit", name="Submit", description="Visitor submits a form")
        ],
        entities=[Entity(id="enquiry", name="Enquiry", description="A public enquiry")],
        tenancy=TenancySpec(model="single_workspace"),
        authentication=AuthenticationSpec(required=False),
    )


def contact_pack(**config: Any) -> InstalledPackView:
    return InstalledPackView(slug="contact-capture", status="installed", config=config)


@dataclass
class InstalledFormsApp:
    """One project's composition-backed Forms runtime plus 7N ports."""

    project_id: str
    plan: Any
    packs: tuple[InstalledPackView, ...]
    store: CompositionFormRuntimeStore
    submissions: InMemoryFormSubmissionStore = field(
        default_factory=InMemoryFormSubmissionStore
    )
    files: InMemoryFormFileDirectory = field(default_factory=InMemoryFormFileDirectory)
    limiter: InMemoryAttemptLimiter = field(default_factory=InMemoryAttemptLimiter)
    invoker: RecordingCapabilityInvoker = field(
        default_factory=RecordingCapabilityInvoker
    )
    email_template_renderer: RecordingEmailTemplateRenderer = field(
        default_factory=RecordingEmailTemplateRenderer
    )
    overlay: InMemoryFormRuntimeStore = field(default_factory=InMemoryFormRuntimeStore)
    verifier: Any = field(default_factory=UnwiredChallengeVerifier)

    @property
    def runtimes(self):
        return OverlayFormRuntimeStore(self.overlay, self.store)

    @property
    def resolution(self):
        return self.store.resolution

    def client_config(self, form_key: str) -> dict[str, Any]:
        runtime = self.runtimes.get(self.project_id, form_key)
        assert runtime is not None
        return project_client_form_config(
            runtime.definition,
            conditions=runtime.conditions,
            step_plan=runtime.step_plan,
        )


def install_forms_app(
    *,
    project_id: str,
    purpose: str,
    goal: str,
    archetypes: list[str],
    pack: InstalledPackView | None = None,
) -> InstalledFormsApp:
    plan = compile_install_plan(_spec(purpose=purpose, goal=goal, archetypes=archetypes))
    packs = (pack or contact_pack(),)
    sources = sources_from_plan_and_packs(plan, packs)
    resolution = resolve_form_bindings(sources)
    return InstalledFormsApp(
        project_id=project_id,
        plan=plan,
        packs=packs,
        store=CompositionFormRuntimeStore(project_id, resolution),
    )


def install_contact_app(project_id: str = "prj_contact", **pack_config: Any) -> InstalledFormsApp:
    return install_forms_app(
        project_id=project_id,
        purpose="Marketing site contact form",
        goal="contact form",
        archetypes=["website"],
        pack=contact_pack(**pack_config),
    )


def install_quote_app(project_id: str = "prj_quote", **pack_config: Any) -> InstalledFormsApp:
    return install_forms_app(
        project_id=project_id,
        purpose="Roofing quotes",
        goal="quote form",
        archetypes=["website"],
        pack=contact_pack(**pack_config),
    )


def rebind(app: InstalledFormsApp, packs: tuple[InstalledPackView, ...]) -> None:
    sources = sources_from_plan_and_packs(app.plan, packs)
    app.packs = packs
    app.store = CompositionFormRuntimeStore(
        app.project_id, resolve_form_bindings(sources)
    )


def installed_app_submit(
    app: InstalledFormsApp,
    *,
    form_key: str,
    body: dict[str, Any],
    client_identity: str = "203.0.113.10",
    verifier=None,
    invoker=None,
    submissions=None,
) -> FormPublicResult:
    """Installed-app BFF + Core Forms. Project comes from deployment, not body."""
    parsed = parse_public_submit_request(body)
    if isinstance(parsed, FormPublicResult):
        return parsed
    return submit_form(
        project_id=app.project_id,
        form_key=form_key,
        values=parsed.values,
        challenge=parsed.challenge,
        client_identity=client_identity,
        runtimes=app.runtimes,
        invoker=invoker or app.invoker,
        submissions=submissions or app.submissions,
        files=app.files,
        verifier=verifier if verifier is not None else app.verifier,
        limiter=app.limiter,
        email_template_renderer=app.email_template_renderer,
    )


def browser_submit(
    app: InstalledFormsApp,
    *,
    form_key: str,
    values: dict[str, Any],
    challenge: str | None = None,
    extra: dict[str, Any] | None = None,
    **kwargs: Any,
) -> FormPublicResult:
    body: dict[str, Any] = {"values": dict(values)}
    if challenge is not None:
        body["challenge"] = challenge
    if extra:
        body.update(extra)
    return installed_app_submit(app, form_key=form_key, body=body, **kwargs)


def generated_browser_sources() -> str:
    files = [
        CODEGEN_RUNTIME / "p2hs-forms-runtime.mjs",
        CODEGEN_RUNTIME / "p2hs-app-client.js",
    ]
    adapter = forms_adapter_files("nuxt_app")
    return "\n".join(path.read_text(encoding="utf-8") for path in files) + "\n" + "\n".join(
        adapter.values()
    )


def browser_leak_hits(source: str | None = None) -> tuple[str, ...]:
    blob = source if source is not None else generated_browser_sources()
    hits = [token for token in BROWSER_LEAK_TOKENS if token.lower() in blob.lower()]
    hits.extend(generic_forms_snippet_leaks(blob))
    return tuple(dict.fromkeys(hits))


def new_install_uses_canonical_forms(requirement: str) -> bool:
    decision = select_forms_generation(requirement)
    return (
        classify_form_intent(requirement) == "public_submission_form"
        and decision.runtime == "canonical_forms"
        and decision.route == "POST /api/forms/{form_key}/submissions"
    )


def passing_verifier():
    from src.domain.forms.anti_abuse import ChallengeVerificationResult

    return StaticChallengeVerifier(ChallengeVerificationResult(passed=True))


def failing_verifier():
    from src.domain.forms.anti_abuse import ChallengeVerificationResult

    return StaticChallengeVerifier(
        ChallengeVerificationResult(passed=False, failure_code="challenge_failed")
    )


def put_platform_file(app: InstalledFormsApp, file_id: str, project_id: str | None = None) -> None:
    app.files.put(
        FormFileRecord(file_id=file_id, project_id=project_id or app.project_id)
    )


def conflict_sources(form_key: str = "contact") -> tuple[FormBindingSource, ...]:
    pack = contact_pack()
    return collect_form_binding_sources(
        planned_block_ids=("forms.contact",),
        packs=(pack,),
    ) + (
        FormBindingSource(
            form_key=form_key,
            owner_id="other.contact",
            owner_kind="app_block",
            pack_slug="contact-capture",
            pack_config={},
        ),
    )


def readiness_for(app: InstalledFormsApp, *keys: str) -> tuple[str, ...]:
    return publish_form_readiness(
        generated_form_keys=keys, resolution=app.resolution
    )
