"""Phase 1 tests: LLM client.

Covers:
- Async HTTP-based LLM client for Qwen LLM
- Provider switching via Settings
- Error handling for API failures
- Mocked responses in test mode
"""
import asyncio
import pytest
import httpx
from unittest.mock import AsyncMock
from app.services.llm_client import LLMClient, LLMClientError
from app.core.config import get_settings


class TestLLMClient:
    """LLM client tests (external calls mocked)."""

    @pytest.mark.asyncio
    async def test_llm_call_success(self, monkeypatch):
        """Should return content from mocked LLM API."""
        from unittest.mock import MagicMock, AsyncMock
        settings = get_settings()
        client = LLMClient(settings)

        mock_message = MagicMock()
        mock_message.content = "mock response"
        mock_choice = MagicMock()
        mock_choice.message = mock_message
        mock_usage = MagicMock()
        mock_usage.prompt_tokens = 10
        mock_usage.completion_tokens = 5
        mock_response = MagicMock()
        mock_response.choices = [mock_choice]
        mock_response.usage = mock_usage

        client._client.chat.completions.create = AsyncMock(return_value=mock_response)

        result = await client.complete(prompt="test prompt", temperature=0.7, step_name="TestStep")
        assert isinstance(result, str)
        assert "mock" in result

    def test_llm_provider_switching(self):
        settings = get_settings()
        client = LLMClient(settings)
        assert str(client._client.base_url).rstrip("/") == settings.llm_base_url.rstrip("/")

    @pytest.mark.asyncio
    async def test_llm_api_error_handling(self, monkeypatch):
        settings = get_settings()
        client = LLMClient(settings)

        async def _mock_post(*args, **kwargs):  # type: ignore
            raise httpx.HTTPStatusError("err", request=None, response=None)  # type: ignore

        client._client.post = _mock_post  # type: ignore
        with pytest.raises(LLMClientError):
            await client.complete(prompt="test", temperature=0.7)
