"""Unit tests for OpenAI client embed()."""

from __future__ import annotations

import httpx
import pytest
import respx

from llm_rotator._types import EmbeddingResponse, EmbeddingUsage
from llm_rotator.clients.openai import OpenAIClient
from llm_rotator.exceptions import KeyDeadError, ServerError

EMBEDDING_RESPONSE = {
    "object": "list",
    "model": "text-embedding-3-small",
    "data": [
        {"object": "embedding", "index": 0, "embedding": [0.1, 0.2, 0.3]},
        {"object": "embedding", "index": 1, "embedding": [0.4, 0.5, 0.6]},
    ],
    "usage": {"prompt_tokens": 8, "total_tokens": 8},
}


class TestOpenAIEmbed:
    @respx.mock
    async def test_successful_embed(self):
        respx.post("https://api.openai.com/v1/embeddings").mock(
            return_value=httpx.Response(200, json=EMBEDDING_RESPONSE)
        )
        client = OpenAIClient()
        result = await client.embed(
            input=["hello", "world"],
            model="text-embedding-3-small",
            api_key="sk-test1234",
        )

        assert isinstance(result, EmbeddingResponse)
        assert len(result.embeddings) == 2
        assert result.embeddings[0] == [0.1, 0.2, 0.3]
        assert result.embeddings[1] == [0.4, 0.5, 0.6]
        assert result.usage == EmbeddingUsage(prompt_tokens=8, total_tokens=8)
        assert result.model == "text-embedding-3-small"
        assert result.provider == "openai"
        assert result.key_alias == "sk-test1..."

    @respx.mock
    async def test_embed_custom_base_url(self):
        respx.post("https://custom.api.com/v1/embeddings").mock(
            return_value=httpx.Response(200, json=EMBEDDING_RESPONSE)
        )
        client = OpenAIClient()
        result = await client.embed(
            input=["test"],
            model="text-embedding-3-small",
            api_key="sk-test1234",
            base_url="https://custom.api.com/v1",
        )

        assert isinstance(result, EmbeddingResponse)

    @respx.mock
    async def test_embed_auth_error(self):
        respx.post("https://api.openai.com/v1/embeddings").mock(
            return_value=httpx.Response(401, json={"error": {"message": "Invalid API key"}})
        )
        client = OpenAIClient()
        with pytest.raises(KeyDeadError):
            await client.embed(
                input=["test"],
                model="text-embedding-3-small",
                api_key="sk-bad12345",
            )

    @respx.mock
    async def test_embed_server_error(self):
        respx.post("https://api.openai.com/v1/embeddings").mock(
            return_value=httpx.Response(500, json={"error": {"message": "Internal"}})
        )
        client = OpenAIClient()
        with pytest.raises(ServerError):
            await client.embed(
                input=["test"],
                model="text-embedding-3-small",
                api_key="sk-test1234",
            )

    @respx.mock
    async def test_embed_single_item(self):
        single_response = {
            "object": "list",
            "model": "text-embedding-3-small",
            "data": [
                {"object": "embedding", "index": 0, "embedding": [0.1, 0.2]},
            ],
            "usage": {"prompt_tokens": 4, "total_tokens": 4},
        }
        respx.post("https://api.openai.com/v1/embeddings").mock(
            return_value=httpx.Response(200, json=single_response)
        )
        client = OpenAIClient()
        result = await client.embed(
            input=["hello"],
            model="text-embedding-3-small",
            api_key="sk-test1234",
        )

        assert len(result.embeddings) == 1
        assert result.usage.prompt_tokens == 4
