from __future__ import annotations

import pytest
from fastapi.testclient import TestClient

from app.generation.llm_client import ToolCallResult, ToolCompletionResult
from app.models.agent import AgentTurnResponse, ToolCallIntent


@pytest.fixture
def client():
    from app.main import app

    return TestClient(app)


def test_agent_turn_route_returns_tool_intents(client, monkeypatch):
    async def fake_run_turn(body, request_id=None, user_id=None):
        return AgentTurnResponse(
            text_deltas=["Reading README.md…"],
            tool_intents=[
                ToolCallIntent(
                    tool_call_id="call-1",
                    tool_name="read_file",
                    arguments={"path": "README.md"},
                    reason="Model requested read_file",
                    risk_level="low",
                    requires_permission=False,
                )
            ],
            done=False,
            finish_reason="tool_calls",
            summary="",
        )

    monkeypatch.setattr(
        "app.api.routes.agent._agent_turn_service.run_turn",
        fake_run_turn,
    )

    response = client.post(
        "/api/v1/agent/turn/",
        json={
            "task_id": "task-1",
            "messages": [{"role": "user", "content": "summarise README.md"}],
            "local_context_summary": {
                "model": "claude-sonnet-4-6",
                "active_file": "README.md",
                "workspace_root": "/tmp/workspace",
            },
            "budget": {"turn_index": 0, "max_turns": 12},
        },
        headers={"X-User-Id": "user-1", "X-Request-Id": "req-1"},
    )

    assert response.status_code == 200
    body = response.json()
    assert body["done"] is False
    assert body["text_deltas"] == ["Reading README.md…"]
    assert body["tool_intents"][0]["tool_name"] == "read_file"


def test_agent_turn_route_returns_done_response(client, monkeypatch):
    async def fake_run_turn(body, request_id=None, user_id=None):
        return AgentTurnResponse(
            text_deltas=["Done."],
            tool_intents=[],
            done=True,
            finish_reason="stop",
            summary="Done.",
        )

    monkeypatch.setattr(
        "app.api.routes.agent._agent_turn_service.run_turn",
        fake_run_turn,
    )

    response = client.post(
        "/api/v1/agent/turn/",
        json={
            "task_id": "task-2",
            "messages": [{"role": "user", "content": "hello"}],
            "local_context_summary": {"model": "gpt-4o"},
        },
    )

    assert response.status_code == 200
    body = response.json()
    assert body["done"] is True
    assert body["summary"] == "Done."


def test_agent_turn_route_maps_llm_error(client, monkeypatch):
    from app.generation.llm_client import LLMClientError

    async def fake_run_turn(body, request_id=None, user_id=None):
        raise LLMClientError("upstream unavailable", status_code=503)

    monkeypatch.setattr(
        "app.api.routes.agent._agent_turn_service.run_turn",
        fake_run_turn,
    )

    response = client.post(
        "/api/v1/agent/turn/",
        json={
            "task_id": "task-3",
            "messages": [{"role": "user", "content": "hello"}],
        },
    )

    assert response.status_code == 503
