from __future__ import annotations

from uuid import uuid4

import pytest
import src.domain.forms.composition_store as composition_store
from src.domain.app_blocks.planner import source_prompt_from_discovery
from src.domain.forms.composition import (
    FormBindingSource,
    build_resolved_runtime,
)


@pytest.mark.asyncio
async def test_runtime_uses_completed_generation_plan_composition(monkeypatch) -> None:
    generation_plan = {
        "composition": {
            "app_block_ids": ["forms.quote_request"],
            "feature_pack_ids": ["contact-capture"],
        },
        "runtime": {},
    }

    async def latest_plan(_db, _project_id):
        return generation_plan

    monkeypatch.setattr(composition_store, "_latest_generation_plan", latest_plan)

    plan = await composition_store._app_block_plan(None, uuid4())

    assert plan is not None
    assert [block.id for block in plan.blocks] == ["forms.quote_request"]
    assert plan.required_feature_packs == ["contact-capture"]


def test_discovery_prompt_falls_back_to_user_messages_after_reset() -> None:
    state = {
        "initial_prompt": "",
        "messages": [
            {"role": "assistant", "content": "What should we build?"},
            {"role": "user", "content": "Use the canonical quote_request form."},
        ],
    }

    assert source_prompt_from_discovery(state) == (
        "Use the canonical quote_request form."
    )


def test_project_form_definition_is_used_by_composition_runtime() -> None:
    source = FormBindingSource(
        form_key="quote_request",
        owner_id="forms.quote_request",
        owner_kind="app_block",
        pack_slug="contact-capture",
        pack_config={
            "form_definitions": {
                "quote_request": {
                    "key": "quote_request",
                    "title": "Request a quote",
                    "fields": [
                        {"key": "name", "type": "text", "required": True},
                        {"key": "email", "type": "email", "required": True},
                        {
                            "key": "project_description",
                            "type": "textarea",
                            "required": True,
                        },
                        {
                            "key": "budget",
                            "type": "select",
                            "options": [
                                {"value": "0-1000", "label": "0 to 1000"},
                                {"value": "1001-5000", "label": "1001 to 5000"},
                                {"value": "5001-25000", "label": "5001 to 25000"},
                                {"value": "25000+", "label": "25000+"},
                            ],
                        },
                        {"key": "attachment", "type": "file"},
                    ],
                }
            }
        },
    )

    runtime = build_resolved_runtime(source)

    assert runtime is not None
    assert {field.key for field in runtime.definition.fields} == {
        "name",
        "email",
        "project_description",
        "budget",
        "attachment",
    }
    budget = next(field for field in runtime.definition.fields if field.key == "budget")
    assert budget.type == "select"


def test_core_form_definition_outside_contact_and_quote_is_callable() -> None:
    from src.domain.forms.composition import (
        InstalledPackView,
        collect_form_binding_sources,
        resolve_form_bindings,
    )

    pack = InstalledPackView(
        slug="contact-capture",
        status="installed",
        config={
            "form_definitions": {
                "student_application": {
                    "key": "student_application",
                    "title": "Student application",
                    "fields": [
                        {"key": "name", "type": "text", "required": True},
                        {"key": "email", "type": "email", "required": True},
                    ],
                }
            }
        },
    )
    resolution = resolve_form_bindings(
        collect_form_binding_sources(planned_block_ids=[], packs=(pack,))
    )

    runtime = resolution.runtimes["student_application"]
    assert runtime.definition.key == "student_application"
    assert runtime.persist_first is True
    assert runtime.plan.actions == ()


def test_invalid_project_form_definition_blocks_runtime() -> None:
    source = FormBindingSource(
        form_key="quote_request",
        owner_id="forms.quote_request",
        owner_kind="app_block",
        pack_slug="contact-capture",
        pack_config={"form_definitions": {"quote_request": {"key": "wrong"}}},
    )

    assert build_resolved_runtime(source) is None
