"""Sheet music to MIDI conversion client."""

from __future__ import annotations

from typing import Any

from melogenai._http import AsyncHttpClient, HttpClient
from melogenai.types import TaskResult, TaskStatus


class Sheet2MidiClient:
    """Synchronous client for sheet music to MIDI conversion."""

    def __init__(self, http: HttpClient):
        self._http = http

    def convert(
        self,
        file_url: str,
        *,
        output_formats: list[str] | None = None,
        convert_midi: bool = True,
    ) -> TaskResult:
        """Submit a sheet music file for conversion.

        Args:
            file_url: URL of the sheet music file (PDF, PNG, or JPG).
            output_formats: Desired output formats, e.g. ["midi", "musicxml"].
            convert_midi: Whether to generate MIDI output.

        Returns:
            TaskResult with task_id and initial status.
        """
        payload: dict[str, Any] = {
            "file_url": file_url,
            "convert_midi": convert_midi,
        }
        if output_formats is not None:
            payload["output_formats"] = output_formats

        data = self._http.post("/api/sheet2midi/convert", payload, timeout=60)
        return TaskResult(task_id=data["task_id"], status=data.get("status", "pending"))

    def get_task(self, task_id: str) -> TaskStatus:
        """Get the current status of a conversion task."""
        data = self._http.get(f"/api/sheet2midi/tasks/{task_id}")
        task = data.get("task", data)
        return TaskStatus(
            task_id=task_id,
            status=task.get("status", "unknown"),
            download_urls=data.get("download_urls", {}),
            error=task.get("error"),
            task=task,
        )

    def wait(
        self,
        task_id: str,
        *,
        poll_interval: float | None = None,
        timeout: float | None = None,
    ) -> TaskStatus:
        """Poll until the task completes and return the final status."""
        data = self._http.poll_task(
            f"/api/sheet2midi/tasks/{task_id}",
            task_id,
            interval=poll_interval,
            timeout=timeout,
        )
        task = data.get("task", data)
        return TaskStatus(
            task_id=task_id,
            status=task.get("status", "completed"),
            download_urls=data.get("download_urls", {}),
            task=task,
        )


class AsyncSheet2MidiClient:
    """Asynchronous client for sheet music to MIDI conversion."""

    def __init__(self, http: AsyncHttpClient):
        self._http = http

    async def convert(
        self,
        file_url: str,
        *,
        output_formats: list[str] | None = None,
        convert_midi: bool = True,
    ) -> TaskResult:
        """Submit a sheet music file for conversion."""
        payload: dict[str, Any] = {
            "file_url": file_url,
            "convert_midi": convert_midi,
        }
        if output_formats is not None:
            payload["output_formats"] = output_formats

        data = await self._http.post("/api/sheet2midi/convert", payload, timeout=60)
        return TaskResult(task_id=data["task_id"], status=data.get("status", "pending"))

    async def get_task(self, task_id: str) -> TaskStatus:
        """Get the current status of a conversion task."""
        data = await self._http.get(f"/api/sheet2midi/tasks/{task_id}")
        task = data.get("task", data)
        return TaskStatus(
            task_id=task_id,
            status=task.get("status", "unknown"),
            download_urls=data.get("download_urls", {}),
            error=task.get("error"),
            task=task,
        )

    async def wait(
        self,
        task_id: str,
        *,
        poll_interval: float | None = None,
        timeout: float | None = None,
    ) -> TaskStatus:
        """Poll until the task completes and return the final status."""
        data = await self._http.poll_task(
            f"/api/sheet2midi/tasks/{task_id}",
            task_id,
            interval=poll_interval,
            timeout=timeout,
        )
        task = data.get("task", data)
        return TaskStatus(
            task_id=task_id,
            status=task.get("status", "completed"),
            download_urls=data.get("download_urls", {}),
            task=task,
        )
