"""Тесты для клиента."""

import pytest
from unittest.mock import AsyncMock, patch
from amnezio import AmnezioClient
from amnezio.exceptions import AuthenticationError, APIError


@pytest.mark.asyncio
async def test_client_initialization():
    """Тест инициализации клиента."""
    client = AmnezioClient(
        base_url="https://test.com",
        username="admin",
        password="secret"
    )
    
    assert client.base_url == "https://test.com"
    assert client.username == "admin"
    assert client.password == "secret"
    assert client.timeout == 30.0


@pytest.mark.asyncio
async def test_authentication_success(mock_response):
    """Тест успешной аутентификации."""
    client = AmnezioClient(
        base_url="https://test.com",
        username="admin",
        password="secret"
    )
    
    with patch.object(client, '_get_http_client') as mock_get_client:
        mock_http = AsyncMock()
        mock_http.post.return_value = mock_response(200, {"access_token": "test_token"})
        mock_get_client.return_value = mock_http
        
        token = await client._authenticate()
        
        assert token == "test_token"
        mock_http.post.assert_called_once_with(
            "/api/auth/login",
            json={"username": "admin", "password": "secret"}
        )


@pytest.mark.asyncio
async def test_authentication_failure(mock_response):
    """Тест ошибки аутентификации."""
    client = AmnezioClient(
        base_url="https://test.com",
        username="admin",
        password="wrong"
    )
    
    with patch.object(client, '_get_http_client') as mock_get_client:
        mock_http = AsyncMock()
        mock_http.post.return_value = mock_response(401)
        mock_get_client.return_value = mock_http
        
        with pytest.raises(AuthenticationError):
            await client._authenticate()


@pytest.mark.asyncio
async def test_request_with_auto_auth(mock_response):
    """Тест автоматической аутентификации при запросе."""
    client = AmnezioClient(
        base_url="https://test.com",
        username="admin",
        password="secret"
    )
    
    with patch.object(client, '_get_http_client') as mock_get_client:
        mock_http = AsyncMock()
        # Первый запрос - аутентификация
        mock_http.post.return_value = mock_response(200, {"access_token": "test_token"})
        # Второй запрос - API запрос
        mock_http.request.return_value = mock_response(200, {"status": "ok"})
        mock_get_client.return_value = mock_http
        
        response = await client.request("GET", "/api/test")
        
        assert response.status_code == 200
        assert client._token == "test_token"


@pytest.mark.asyncio
async def test_context_manager():
    """Тест использования клиента как контекстного менеджера."""
    with patch('amnezio.client.httpx.AsyncClient') as mock_client_class:
        mock_http = AsyncMock()
        mock_http.post.return_value = AsyncMock(
            status_code=200,
            json=lambda: {"access_token": "test_token"}
        )
        mock_client_class.return_value = mock_http
        
        async with AmnezioClient(
            base_url="https://test.com",
            username="admin",
            password="secret"
        ) as client:
            assert client._token == "test_token"
        
        mock_http.aclose.assert_called_once()
