from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4

import pytest
from src.domain.projects.discovery_schemas import DiscoveryResult, DiscoverySpec, ProductDefinition


@pytest.mark.asyncio
async def test_discovery_completion_starts_codegen_without_customer_chat(monkeypatch):
    from src.workers import discovery_apply as worker

    project_id = uuid4()
    owner_id = uuid4()
    run_id = uuid4()
    state = {
        "status": "completed",
        "approved_by": str(owner_id),
        "version": 1,
        "result": DiscoveryResult(
            decision="ready",
            message="Ready",
            spec=DiscoverySpec(
                product=ProductDefinition(
                    name="Portfolio",
                    purpose="A one-page portfolio",
                    first_build_goal="Show projects",
                )
            ),
            project_type="html",
            product_name="Portfolio",
            summary="A one-page portfolio with a Projects section.",
            specification="Show projects",
        ).model_dump(),
    }
    project = SimpleNamespace(discovery_json=state)

    db = MagicMock()
    db.__aenter__ = AsyncMock(return_value=db)
    db.__aexit__ = AsyncMock(return_value=False)
    db.get = AsyncMock(return_value=SimpleNamespace(id=owner_id))
    db.commit = AsyncMock()
    db.rollback = AsyncMock()
    factory = MagicMock(return_value=db)

    monkeypatch.setattr(
        worker,
        "DiscoveryRepository",
        lambda _db: SimpleNamespace(get=AsyncMock(return_value=project)),
    )
    monkeypatch.setattr(worker, "require_discovery_access", AsyncMock())
    monkeypatch.setattr(worker, "assert_discovery_installable", lambda _state: None)

    service = SimpleNamespace(create_run=AsyncMock(return_value=SimpleNamespace(id=run_id)))
    facade = SimpleNamespace(service=service)
    monkeypatch.setattr(
        "src.domain.codegen.agent_facade.AgentCodegenFacade",
        lambda _db: facade,
    )
    enqueue = AsyncMock()
    monkeypatch.setattr("src.workers.enqueue.enqueue_codegen_run", enqueue)

    result = await worker.start_first_build(factory, project_id)

    assert result == {"status": "completed", "run_id": str(run_id)}
    service.create_run.assert_awaited_once()
    kwargs = service.create_run.await_args.kwargs
    assert "app-blocks-plan.json" not in kwargs["user_prompt"]
    assert "starter-contracts.json" not in kwargs["user_prompt"]
    assert "app-block-hosts.json" not in kwargs["user_prompt"]
    assert kwargs["generation_plan"]["metadata"]["schema_version"] == "1"
    assert kwargs["generation_request"]["schema_version"] == "codegen_request.v1"
    assert kwargs["generation_request"]["execution_mode"] == "plan_first_shadow"
    assert kwargs["project_id"] == project_id
    enqueue.assert_awaited_once_with(str(run_id), project_id=str(project_id))
    db.commit.assert_awaited_once()
