import pytest
from unittest.mock import MagicMock, AsyncMock, patch

from latch import Latch, AsyncLatch, LatchConfig
from latch.models import ReportRequest, ReportResponse
from latch.exceptions import AuthenticationError


def test_latch_config_defaults():
    config = LatchConfig(api_key="lgk_test")
    assert config.base_url == "https://api.latch.dev"
    assert config.timeout == 30.0
    assert config.mode == "observe"


def test_latch_config_custom():
    config = LatchConfig(
        api_key="lgk_test",
        base_url="http://localhost:8081",
        timeout=60.0,
        mode="enforce",
    )
    assert config.base_url == "http://localhost:8081"
    assert config.timeout == 60.0
    assert config.mode == "enforce"


def test_latch_client_creation():
    client = Latch(api_key="lgk_test", base_url="http://localhost:8081")
    assert client.config.api_key == "lgk_test"
    client.close()


def test_latch_client_context_manager():
    with Latch(api_key="lgk_test", base_url="http://localhost:8081") as client:
        assert client.config.api_key == "lgk_test"


def test_report_request_model():
    """Test ReportRequest model serialization"""
    request = ReportRequest(
        decision_id="dec_123",
        input_tokens=100,
        output_tokens=50,
        llm_latency_ms=250,
        model="gpt-4o-mini",
        success=True,
    )

    data = request.model_dump(by_alias=True, exclude_none=True)
    assert data["decisionId"] == "dec_123"
    assert data["inputTokens"] == 100
    assert data["outputTokens"] == 50
    assert data["llmLatencyMs"] == 250
    assert data["model"] == "gpt-4o-mini"
    assert data["success"] is True


def test_report_response_model():
    """Test ReportResponse model deserialization"""
    response = ReportResponse(
        decision_id="dec_123",
        actual_cost=0.0025,
        total_latency_ms=300,
    )

    assert response.decision_id == "dec_123"
    assert response.actual_cost == 0.0025
    assert response.total_latency_ms == 300


@pytest.mark.asyncio
async def test_async_latch_client_creation():
    """Test AsyncLatch client creation"""
    client = AsyncLatch(api_key="lgk_test", base_url="http://localhost:8081")
    assert client.config.api_key == "lgk_test"
    await client.close()


@pytest.mark.asyncio
async def test_async_latch_context_manager():
    """Test AsyncLatch as context manager"""
    async with AsyncLatch(api_key="lgk_test", base_url="http://localhost:8081") as client:
        assert client.config.api_key == "lgk_test"
