import json
import httpx
import pytest
import respx

from anyfast import AnyFast


@pytest.fixture
def client():
    return AnyFast(api_key="test-key")


class TestCompletions:
    @respx.mock
    def test_completions(self, client):
        mock_response = {
            "id": "chatcmpl-abc123",
            "object": "chat.completion",
            "created": 1700000000,
            "model": "gpt-4o",
            "choices": [
                {
                    "index": 0,
                    "message": {"role": "assistant", "content": "Hello!"},
                    "finish_reason": "stop",
                }
            ],
            "usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15},
        }

        route = respx.post("https://www.anyfast.ai/v1/chat/completions").mock(
            return_value=httpx.Response(200, json=mock_response)
        )

        result = client.chat.completions(
            model="gpt-4o",
            messages=[{"role": "user", "content": "Hi"}],
        )

        assert route.called
        assert result["choices"][0]["message"]["content"] == "Hello!"
        assert result["usage"]["total_tokens"] == 15

    @respx.mock
    def test_completions_with_doubao(self, client):
        respx.post("https://www.anyfast.ai/v1/chat/completions").mock(
            return_value=httpx.Response(200, json={
                "id": "chatcmpl-doubao",
                "choices": [{"index": 0, "message": {"role": "assistant", "content": "你好"}, "finish_reason": "stop"}],
            })
        )

        result = client.chat.completions(
            model="doubao-seed-2.0-pro",
            messages=[{"role": "user", "content": "你好"}],
            temperature=0.7,
        )

        assert result["choices"][0]["message"]["content"] == "你好"


class TestMessages:
    @respx.mock
    def test_messages(self, client):
        mock_response = {
            "id": "msg_abc123",
            "type": "message",
            "role": "assistant",
            "content": [{"type": "text", "text": "Hello from Claude!"}],
            "model": "claude-sonnet-4-20250514",
            "stop_reason": "end_turn",
            "stop_sequence": None,
            "usage": {"input_tokens": 10, "output_tokens": 8},
        }

        route = respx.post("https://www.anyfast.ai/v1/messages").mock(
            return_value=httpx.Response(200, json=mock_response)
        )

        result = client.chat.messages(
            model="claude-sonnet-4-20250514",
            messages=[{"role": "user", "content": "Hello"}],
            max_tokens=1024,
        )

        assert route.called
        assert result["content"][0]["text"] == "Hello from Claude!"
        assert result["stop_reason"] == "end_turn"


class TestResponses:
    @respx.mock
    def test_responses(self, client):
        mock_response = {
            "id": "resp_021",
            "object": "response",
            "created_at": 1700000000,
            "model": "doubao-seed-2.0-pro",
            "status": "completed",
            "output": [
                {
                    "type": "message",
                    "role": "assistant",
                    "content": [{"type": "output_text", "text": "你好！"}],
                }
            ],
            "usage": {"input_tokens": 5, "output_tokens": 3, "total_tokens": 8},
        }

        route = respx.post("https://www.anyfast.ai/v1/responses").mock(
            return_value=httpx.Response(200, json=mock_response)
        )

        result = client.chat.responses(
            model="doubao-seed-2.0-pro",
            input="Hello",
        )

        assert route.called
        assert result["output"][0]["content"][0]["text"] == "你好！"

    @respx.mock
    def test_responses_multimodal(self, client):
        respx.post("https://www.anyfast.ai/v1/responses").mock(
            return_value=httpx.Response(200, json={
                "id": "resp_022",
                "status": "completed",
                "output": [{"type": "message", "content": [{"type": "output_text", "text": "I see a cat."}]}],
            })
        )

        result = client.chat.responses(
            model="doubao-seed-1-6-vision-250815",
            input=[
                {
                    "role": "user",
                    "content": [
                        {"type": "input_text", "text": "What is this?"},
                        {"type": "input_image", "image_url": "https://example.com/cat.png"},
                    ],
                }
            ],
        )

        assert result["output"][0]["content"][0]["text"] == "I see a cat."


class TestGemini:
    @respx.mock
    def test_gemini(self, client):
        mock_response = {
            "candidates": [
                {
                    "content": {"parts": [{"text": "Hello from Gemini!"}], "role": "model"},
                    "finishReason": "STOP",
                    "index": 0,
                }
            ],
            "usageMetadata": {
                "promptTokenCount": 5,
                "candidatesTokenCount": 4,
                "totalTokenCount": 9,
            },
        }

        route = respx.post("https://www.anyfast.ai/v1beta/models/gemini-2.0-flash:generateContent").mock(
            return_value=httpx.Response(200, json=mock_response)
        )

        result = client.chat.gemini(
            "gemini-2.0-flash",
            contents=[{"role": "user", "parts": [{"text": "Hello"}]}],
        )

        assert route.called
        assert result["candidates"][0]["content"]["parts"][0]["text"] == "Hello from Gemini!"
