"""Tests for music2midi service client."""

from __future__ import annotations

import json

import pytest
import respx
from httpx import Response

from melogenai.client import AsyncMelogen, Melogen

from conftest import TEST_API_KEY, TEST_BASE_URL


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

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL)
        result = client.music2midi.convert("https://example.com/song.mp3")

        assert result.task_id == "task_101"

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

        client = Melogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL)
        result = client.music2midi.convert(
            "https://example.com/song.mp3", save_stems=True, quantize=True
        )

        assert result.task_id == "task_102"
        request = route.calls.last.request
        body = json.loads(request.content)
        assert body["save_stems"] is True
        assert body["quantize"] is True

    def test_get_task(self, mock_api: respx.MockRouter) -> None:
        mock_api.get("/api/music2midi/tasks/task_101").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.music2midi.get_task("task_101")

        assert status.status == "completed"

    def test_wait_completes(self, mock_api: respx.MockRouter) -> None:
        mock_api.get("/api/music2midi/tasks/task_101").mock(
            side_effect=[
                Response(200, json={"task": {"status": "processing"}, "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.music2midi.wait("task_101")

        assert result.status == "completed"


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

        async with AsyncMelogen(api_key=TEST_API_KEY, base_url=TEST_BASE_URL) as client:
            result = await client.music2midi.convert("https://example.com/song.mp3")

        assert result.task_id == "task_101"
