from __future__ import annotations

from typing import Callable
from uuid import UUID

from fastapi.testclient import TestClient

from app import app
from v1.agent.dependencies import get_agent_service
from v1.agent.schemas import (
    AgentChatEvent,
    AgentChatRunRequest,
    AgentChatRunResponse,
)
from v1.agent.service import AgentChatService


class FakeAgentChatService:
    async def run(self, payload: AgentChatRunRequest) -> AgentChatRunResponse:
        return AgentChatRunResponse(
            session_id=UUID("00000000-0000-0000-0000-000000000001"),
            output=payload.message,
            events=[
                AgentChatEvent(
                    type="run.started", run_id="00000000-0000-0000-0000-000000000001"
                ),
                AgentChatEvent(
                    type="message.delta", message_id="m1", delta=payload.message
                ),
                AgentChatEvent(
                    type="run.completed",
                    run_id="00000000-0000-0000-0000-000000000001",
                    output=payload.message,
                ),
            ],
        )


def _override_agent_chat_service(
    service: FakeAgentChatService,
) -> Callable[[], AgentChatService]:
    def _get_service() -> AgentChatService:
        return service  # type: ignore[return-value]

    return _get_service


def test_run_route_returns_response() -> None:
    app.dependency_overrides[get_agent_service] = _override_agent_chat_service(
        FakeAgentChatService()
    )

    client = TestClient(app)
    try:
        response = client.post("/api/v1/agent-chat", json={"message": "hello"})
        assert response.status_code == 200
        body = response.json()
        assert body["output"] == "hello"
        assert [event["type"] for event in body["events"]] == [
            "run.started",
            "message.delta",
            "run.completed",
        ]
    finally:
        app.dependency_overrides = {}


def test_run_route_validates_payload() -> None:
    app.dependency_overrides[get_agent_service] = _override_agent_chat_service(
        FakeAgentChatService()
    )

    client = TestClient(app)
    try:
        response = client.post("/api/v1/agent-chat", json={"message": ""})
        assert response.status_code == 422
    finally:
        app.dependency_overrides = {}
