"""Tests for multimodal message and response support."""
from __future__ import annotations

import httpx
import pytest

from logos_adk.agent import Agent
from logos_adk.providers.mock import MockProvider
from logos_adk.providers.openai import _messages_to_openai
from logos_adk.serve import create_app
from logos_adk.types import ContentPart, Message, Response, Usage


async def _request(app, method: str, path: str, **kwargs):
    transport = httpx.ASGITransport(app=app)
    async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client:
        return await client.request(method, path, **kwargs)


@pytest.mark.asyncio
async def test_agent_run_accepts_multimodal_prompt_parts():
    provider = MockProvider(responses=["vision-ok"])
    agent = Agent("vision-bot").model(provider)

    result = await agent.run(
        [
            ContentPart(type="text", text="Describe this image"),
            ContentPart(type="image", uri="https://example.com/cat.png", metadata={"detail": "high"}),
        ]
    )

    assert result.content == "vision-ok"
    sent_messages = provider.call_history[0]["messages"]
    assert sent_messages[-1].role == "user"
    assert sent_messages[-1].content_parts[0].type == "text"
    assert sent_messages[-1].content_parts[1].type == "image"


def test_openai_message_conversion_serializes_image_parts():
    messages = [
        Message(
            role="user",
            content="",
            content_parts=[
                ContentPart(type="text", text="Describe this image"),
                ContentPart(type="image", uri="https://example.com/cat.png", metadata={"detail": "high"}),
                ContentPart(type="video", uri="https://example.com/clip.mp4", name="clip"),
            ],
        )
    ]

    payload = _messages_to_openai(messages)

    assert payload[0]["role"] == "user"
    assert payload[0]["content"][0] == {"type": "text", "text": "Describe this image"}
    assert payload[0]["content"][1]["type"] == "image_url"
    assert payload[0]["content"][1]["image_url"]["url"] == "https://example.com/cat.png"
    assert payload[0]["content"][1]["image_url"]["detail"] == "high"
    assert payload[0]["content"][2]["type"] == "text"
    assert "[video: clip]" in payload[0]["content"][2]["text"]


@pytest.mark.asyncio
async def test_run_endpoint_accepts_prompt_parts_and_returns_content_parts():
    provider = MockProvider(
        responses=[
            Response(
                content="",
                content_parts=[
                    ContentPart(type="image", uri="https://example.com/generated.png", mime_type="image/png", name="generated"),
                ],
                tool_calls=[],
                usage=Usage(input_tokens=12, output_tokens=34),
                raw={},
            )
        ]
    )
    app = create_app([Agent("vision-bot").model(provider)])

    response = await _request(
        app,
        "POST",
        "/run",
        json={
            "prompt_parts": [
                {"type": "text", "text": "What is in this image?"},
                {"type": "image", "uri": "https://example.com/input.png", "metadata": {"detail": "high"}},
            ]
        },
    )

    assert response.status_code == 200
    payload = response.json()
    assert payload["content"] == ""
    assert payload["content_parts"][0]["type"] == "image"
    assert payload["content_parts"][0]["uri"] == "https://example.com/generated.png"
    sent_messages = provider.call_history[0]["messages"]
    assert sent_messages[-1].content_parts[1].uri == "https://example.com/input.png"
