"""Shared fixtures for tests."""

from __future__ import annotations

from collections.abc import AsyncIterator
from typing import Any

from llm_rotator._types import LLMResponse, StreamChunk, Usage
from llm_rotator.clients import AbstractLLMClient
from llm_rotator.exceptions import LLMRotatorError


class FakeLLMClient(AbstractLLMClient):
    """Configurable fake client for testing rotator logic.

    Usage:
        client = FakeLLMClient()
        # Queue responses (FIFO)
        client.enqueue(LLMResponse(...))
        # Or queue errors
        client.enqueue(KeyDeadError(...))
    """

    def __init__(self) -> None:
        self._queue: list[LLMResponse | LLMRotatorError] = []
        self._calls: list[dict[str, Any]] = []

    def enqueue(self, result: LLMResponse | LLMRotatorError) -> None:
        self._queue.append(result)

    @property
    def calls(self) -> list[dict[str, Any]]:
        return self._calls

    async def generate(
        self,
        messages: list[dict],
        model: str,
        api_key: str,
        base_url: str | None = None,
        **kwargs: Any,
    ) -> LLMResponse:
        self._calls.append({
            "messages": messages,
            "model": model,
            "api_key": api_key,
            "base_url": base_url,
            **kwargs,
        })
        if not self._queue:
            return LLMResponse(
                content="default response",
                usage=Usage(prompt_tokens=10, completion_tokens=10, total_tokens=20),
                model=model,
                provider="fake",
                key_alias="unknown",
            )
        result = self._queue.pop(0)
        if isinstance(result, LLMRotatorError):
            raise result
        return result

    async def stream(
        self,
        messages: list[dict],
        model: str,
        api_key: str,
        base_url: str | None = None,
        **kwargs: Any,
    ) -> AsyncIterator[StreamChunk]:
        # Delegate to generate for simplicity in tests
        response = await self.generate(messages, model, api_key, base_url, **kwargs)
        yield StreamChunk(
            delta=response.content or "",
            usage=response.usage,
            done=True,
            tool_calls=response.tool_calls,
        )
