"""Tests for Chat API routes."""

import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from fastapi.testclient import TestClient

from agentkit.session.manager import SessionManager
from agentkit.session.store import InMemorySessionStore
from agentkit.session.models import SessionStatus


@pytest.fixture
def app_with_chat():
    """Create a FastAPI app with Chat routes and mocked dependencies."""
    from fastapi import FastAPI
    from agentkit.server.routes.chat import router

    app = FastAPI()
    app.include_router(router, prefix="/api/v1")

    # Mock app.state dependencies
    app.state.session_manager = SessionManager(store=InMemorySessionStore())
    app.state.llm_gateway = MagicMock()
    app.state.agent_pool = MagicMock()
    app.state.server_config = MagicMock()
    app.state.server_config.api_key = None

    return app


@pytest.fixture
def client(app_with_chat):
    return TestClient(app_with_chat)


class TestChatSessionCRUD:
    def test_create_session(self, client):
        resp = client.post("/api/v1/chat/sessions", json={"agent_name": "test-agent"})
        assert resp.status_code == 200
        data = resp.json()
        assert data["agent_name"] == "test-agent"
        assert data["status"] == "active"
        assert "session_id" in data

    def test_get_session(self, client):
        create_resp = client.post("/api/v1/chat/sessions", json={"agent_name": "test-agent"})
        session_id = create_resp.json()["session_id"]

        get_resp = client.get(f"/api/v1/chat/sessions/{session_id}")
        assert get_resp.status_code == 200
        assert get_resp.json()["session_id"] == session_id

    def test_get_nonexistent_session(self, client):
        resp = client.get("/api/v1/chat/sessions/nonexistent")
        assert resp.status_code == 404

    def test_close_session(self, client):
        create_resp = client.post("/api/v1/chat/sessions", json={"agent_name": "test-agent"})
        session_id = create_resp.json()["session_id"]

        close_resp = client.delete(f"/api/v1/chat/sessions/{session_id}")
        assert close_resp.status_code == 200
        assert close_resp.json()["status"] == "closed"

    def test_close_nonexistent_session(self, client):
        resp = client.delete("/api/v1/chat/sessions/nonexistent")
        assert resp.status_code == 404

    def test_get_messages_empty(self, client):
        create_resp = client.post("/api/v1/chat/sessions", json={"agent_name": "test-agent"})
        session_id = create_resp.json()["session_id"]

        msgs_resp = client.get(f"/api/v1/chat/sessions/{session_id}/messages")
        assert msgs_resp.status_code == 200
        assert msgs_resp.json() == []

    def test_get_messages_nonexistent_session(self, client):
        resp = client.get("/api/v1/chat/sessions/nonexistent/messages")
        assert resp.status_code == 404

    def test_send_message_closed_session(self, client):
        create_resp = client.post("/api/v1/chat/sessions", json={"agent_name": "test-agent"})
        session_id = create_resp.json()["session_id"]

        client.delete(f"/api/v1/chat/sessions/{session_id}")

        msg_resp = client.post(
            f"/api/v1/chat/sessions/{session_id}/messages",
            json={"content": "Hello"},
        )
        assert msg_resp.status_code == 400

    def test_send_message_nonexistent_session(self, client):
        resp = client.post(
            "/api/v1/chat/sessions/nonexistent/messages",
            json={"content": "Hello"},
        )
        assert resp.status_code == 404
