"""Tests for the AAL client."""

import uuid
from unittest.mock import AsyncMock

import pytest

from aal_sdk.client import AALClient
from aal_sdk.session import AALSession
from aal_sdk.types import AALClientConfig


@pytest.fixture
def client():
    """Create an AALClient with mocked internals."""
    config: AALClientConfig = {
        "api_url": "https://api.example.com",
        "api_key": "test-key",
        "flush_interval": 10.0,  # Long interval to prevent timer flushes during tests
        "batch_size": 100,
    }
    c = AALClient(config)
    # Stop the timer to avoid background flushes
    c._buffer.stop()
    return c


async def test_start_session_returns_aal_session(client: AALClient):
    """Test that start_session returns an AALSession instance."""
    session = client.start_session({"agent_id": "agent-1"})

    assert isinstance(session, AALSession)
    assert session.agent_id == "agent-1"
    # Session id should be a valid UUID
    uuid.UUID(session.id)  # Raises if not valid
    await client.shutdown()


async def test_start_session_with_custom_session_id(client: AALClient):
    """Test that start_session uses provided session_id."""
    session = client.start_session(
        {"agent_id": "agent-1", "session_id": "custom-session-123"}
    )

    assert session.id == "custom-session-123"
    assert session.agent_id == "agent-1"
    await client.shutdown()


async def test_session_returns_handle_without_api_call(client: AALClient):
    """Test that session() returns a handle without making an API call."""
    client._http = AsyncMock()

    session = client.session("existing-session", "agent-2")

    assert isinstance(session, AALSession)
    assert session.id == "existing-session"
    assert session.agent_id == "agent-2"
    # No HTTP calls should have been made
    client._http.get.assert_not_called()
    client._http.post.assert_not_called()
    await client.shutdown()


async def test_get_events_builds_query_string(client: AALClient):
    """Test that get_events builds the correct query string."""
    client._http = AsyncMock()
    client._http.get = AsyncMock(
        return_value={"data": [], "cursor": None, "has_more": False}
    )

    result = await client.get_events(
        {"session_id": "sess-1", "limit": 10}
    )

    # Check that the GET call included query params
    call_args = client._http.get.call_args[0][0]
    assert "session_id=sess-1" in call_args
    assert "limit=10" in call_args
    assert result["has_more"] is False
    await client.shutdown()


async def test_shutdown_drains_buffer(client: AALClient):
    """Test that shutdown drains the buffer and closes HTTP client."""
    client._http = AsyncMock()
    client._buffer = AsyncMock()

    await client.shutdown()

    client._buffer.drain.assert_called_once()
    client._http.close.assert_called_once()
