"""
Tests für LLM Gateway Pydantic Models.
"""

import pytest
from llm_gateway.models.chat import (
    ChatMessage,
    ChatCompletionRequest,
    ChatCompletionResponse,
    ChatCompletionChunk,
    ChatChoice,
    StreamChoice,
    ChatChoiceDelta,
    Usage,
    ModelInfo,
    ModelListResponse,
    RequestMetadata,
)


class TestChatMessage:
    """Tests für ChatMessage Model."""

    def test_user_message(self):
        """Test User Message erstellen."""
        msg = ChatMessage(role="user", content="Hello")
        assert msg.role == "user"
        assert msg.content == "Hello"
        assert msg.name is None

    def test_assistant_message(self):
        """Test Assistant Message erstellen."""
        msg = ChatMessage(role="assistant", content="Hi there!")
        assert msg.role == "assistant"
        assert msg.content == "Hi there!"

    def test_system_message(self):
        """Test System Message erstellen."""
        msg = ChatMessage(role="system", content="You are a helpful assistant.")
        assert msg.role == "system"

    def test_tool_message(self):
        """Test Tool Message erstellen."""
        msg = ChatMessage(role="tool", content='{"result": "success"}', tool_call_id="call_123")
        assert msg.role == "tool"
        assert msg.tool_call_id == "call_123"


class TestChatCompletionRequest:
    """Tests für ChatCompletionRequest Model."""

    def test_minimal_request(self):
        """Test minimale Request."""
        req = ChatCompletionRequest(
            model="breakpilot-teacher-8b",
            messages=[ChatMessage(role="user", content="Hello")],
        )
        assert req.model == "breakpilot-teacher-8b"
        assert len(req.messages) == 1
        assert req.stream is False
        assert req.temperature == 0.7

    def test_full_request(self):
        """Test vollständige Request."""
        req = ChatCompletionRequest(
            model="breakpilot-teacher-70b",
            messages=[
                ChatMessage(role="system", content="Du bist ein Assistent."),
                ChatMessage(role="user", content="Schreibe einen Brief."),
            ],
            stream=True,
            temperature=0.5,
            max_tokens=1000,
            metadata=RequestMetadata(playbook_id="pb_elternbrief"),
        )
        assert req.stream is True
        assert req.temperature == 0.5
        assert req.max_tokens == 1000
        assert req.metadata.playbook_id == "pb_elternbrief"

    def test_temperature_bounds(self):
        """Test Temperature Grenzen."""
        # Gültige Werte
        req = ChatCompletionRequest(
            model="test",
            messages=[ChatMessage(role="user", content="test")],
            temperature=0.0,
        )
        assert req.temperature == 0.0

        req = ChatCompletionRequest(
            model="test",
            messages=[ChatMessage(role="user", content="test")],
            temperature=2.0,
        )
        assert req.temperature == 2.0

        # Ungültige Werte
        with pytest.raises(ValueError):
            ChatCompletionRequest(
                model="test",
                messages=[ChatMessage(role="user", content="test")],
                temperature=2.5,
            )


class TestChatCompletionResponse:
    """Tests für ChatCompletionResponse Model."""

    def test_response_creation(self):
        """Test Response erstellen."""
        response = ChatCompletionResponse(
            model="breakpilot-teacher-8b",
            choices=[
                ChatChoice(
                    index=0,
                    message=ChatMessage(role="assistant", content="Hello!"),
                    finish_reason="stop",
                )
            ],
            usage=Usage(prompt_tokens=10, completion_tokens=5, total_tokens=15),
        )
        assert response.object == "chat.completion"
        assert response.model == "breakpilot-teacher-8b"
        assert len(response.choices) == 1
        assert response.choices[0].message.content == "Hello!"
        assert response.usage.total_tokens == 15

    def test_response_has_id(self):
        """Test dass Response eine ID hat."""
        response = ChatCompletionResponse(
            model="test",
            choices=[
                ChatChoice(
                    message=ChatMessage(role="assistant", content="test"),
                )
            ],
        )
        assert response.id.startswith("chatcmpl-")
        assert len(response.id) > 10


class TestChatCompletionChunk:
    """Tests für Streaming Chunks."""

    def test_chunk_creation(self):
        """Test Chunk erstellen."""
        chunk = ChatCompletionChunk(
            model="breakpilot-teacher-8b",
            choices=[
                StreamChoice(
                    index=0,
                    delta=ChatChoiceDelta(content="Hello"),
                    finish_reason=None,
                )
            ],
        )
        assert chunk.object == "chat.completion.chunk"
        assert chunk.choices[0].delta.content == "Hello"

    def test_final_chunk(self):
        """Test Final Chunk mit finish_reason."""
        chunk = ChatCompletionChunk(
            model="test",
            choices=[
                StreamChoice(
                    index=0,
                    delta=ChatChoiceDelta(),
                    finish_reason="stop",
                )
            ],
        )
        assert chunk.choices[0].finish_reason == "stop"


class TestModelInfo:
    """Tests für ModelInfo."""

    def test_model_info(self):
        """Test ModelInfo erstellen."""
        model = ModelInfo(
            id="breakpilot-teacher-8b",
            owned_by="breakpilot",
            description="Test model",
            context_length=8192,
        )
        assert model.id == "breakpilot-teacher-8b"
        assert model.object == "model"
        assert model.context_length == 8192


class TestModelListResponse:
    """Tests für ModelListResponse."""

    def test_model_list(self):
        """Test Model List erstellen."""
        response = ModelListResponse(
            data=[
                ModelInfo(id="model-1", owned_by="test"),
                ModelInfo(id="model-2", owned_by="test"),
            ]
        )
        assert response.object == "list"
        assert len(response.data) == 2
