"""Tests for sheet2midi service client."""

from __future__ import annotations

import pytest
import respx
from httpx import Response

from melogenai.client import AsyncMelogen, Melogen

from conftest import TEST_API_KEY, TEST_BASE_URL


class TestSheet2MidiSync:
    def test_convert(self, mock_api: respx.MockRouter) -> None:
        mock_api.post("/api/sheet2midi/convert").respond(
            json={"task_id": "task_001", "status": "pending"}
        )

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL)
        result = client.sheet2midi.convert("https://example.com/score.pdf")

        assert result.task_id == "task_001"
        assert result.status == "pending"

    def test_convert_with_formats(self, mock_api: respx.MockRouter) -> None:
        route = mock_api.post("/api/sheet2midi/convert").respond(
            json={"task_id": "task_002", "status": "pending"}
        )

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL)
        result = client.sheet2midi.convert(
            "https://example.com/score.pdf",
            output_formats=["midi", "musicxml"],
            convert_midi=True,
        )

        assert result.task_id == "task_002"
        import json
        request = route.calls.last.request
        body = json.loads(request.content)
        assert body["output_formats"] == ["midi", "musicxml"]
        assert body["convert_midi"] is True

    def test_get_task(self, mock_api: respx.MockRouter) -> None:
        mock_api.get("/api/sheet2midi/tasks/task_001").respond(
            json={
                "task": {"status": "completed"},
                "download_urls": {"midi": "https://dl.example.com/out.midi"},
            }
        )

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL)
        status = client.sheet2midi.get_task("task_001")

        assert status.status == "completed"
        assert status.download_urls["midi"] == "https://dl.example.com/out.midi"

    def test_wait_completes(self, mock_api: respx.MockRouter) -> None:
        # First poll returns pending, second returns completed
        mock_api.get("/api/sheet2midi/tasks/task_001").mock(
            side_effect=[
                Response(200, json={"task": {"status": "pending"}, "download_urls": {}}),
                Response(
                    200,
                    json={
                        "task": {"status": "completed"},
                        "download_urls": {"midi": "https://dl.example.com/out.midi"},
                    },
                ),
            ]
        )

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL, poll_interval=0.01)
        result = client.sheet2midi.wait("task_001")

        assert result.status == "completed"
        assert "midi" in result.download_urls


class TestSheet2MidiAsync:
    @pytest.mark.asyncio
    async def test_convert(self, mock_api: respx.MockRouter) -> None:
        mock_api.post("/api/sheet2midi/convert").respond(
            json={"task_id": "task_001", "status": "pending"}
        )

        async with AsyncMelogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL) as client:
            result = await client.sheet2midi.convert("https://example.com/score.pdf")

        assert result.task_id == "task_001"

    @pytest.mark.asyncio
    async def test_wait_completes(self, mock_api: respx.MockRouter) -> None:
        mock_api.get("/api/sheet2midi/tasks/task_001").mock(
            side_effect=[
                Response(200, json={"task": {"status": "pending"}, "download_urls": {}}),
                Response(
                    200,
                    json={
                        "task": {"status": "completed"},
                        "download_urls": {"midi": "https://dl.example.com/out.midi"},
                    },
                ),
            ]
        )

        async with AsyncMelogen(
            api_key=TEST_API_KEY, base_url=TEST_BASE_URL, poll_interval=0.01
        ) as client:
            result = await client.sheet2midi.wait("task_001")

        assert result.status == "completed"
