"""Main Melogen client classes."""

from __future__ import annotations

import os
from types import TracebackType
from typing import Any

from melogenai._http import AsyncHttpClient, HttpClient
from melogenai.analysis.client import AnalysisClient, AsyncAnalysisClient
from melogenai.auth import AuthManager
from melogenai.config import Config
from melogenai.music2midi.client import AsyncMusic2MidiClient, Music2MidiClient
from melogenai.sheet2midi.client import AsyncSheet2MidiClient, Sheet2MidiClient


class Melogen:
    """Synchronous Melogen client.

    Usage::

        client = Melogen(api_key="melo_xxx")
        result = client.sheet2midi.convert(file_url="https://...")
        final = client.sheet2midi.wait(result.task_id)
    """

    def __init__(
        self,
        *,
        api_key: str | None = None,
        base_url: str | None = None,
        timeout: float = 30.0,
        poll_interval: float = 2.0,
        poll_timeout: float = 300.0,
    ):
        resolved_key = api_key or os.getenv("MELOGEN_API_KEY", "")
        config_kwargs: dict[str, Any] = {
            "api_key": resolved_key,
            "timeout": timeout,
            "poll_interval": poll_interval,
            "poll_timeout": poll_timeout,
        }
        if base_url is not None:
            config_kwargs["base_url"] = base_url

        self._config = Config(**config_kwargs)
        self._auth = AuthManager(self._config)
        self._http = HttpClient(self._config, self._auth)

        self.sheet2midi = Sheet2MidiClient(self._http)
        self.music2midi = Music2MidiClient(self._http)
        self.analysis = AnalysisClient(self._http)


class AsyncMelogen:
    """Asynchronous Melogen client.

    Usage::

        async with AsyncMelogen(api_key="melo_xxx") as client:
            result = await client.sheet2midi.convert(file_url="https://...")
            final = await client.sheet2midi.wait(result.task_id)
    """

    def __init__(
        self,
        *,
        api_key: str | None = None,
        base_url: str | None = None,
        timeout: float = 30.0,
        poll_interval: float = 2.0,
        poll_timeout: float = 300.0,
    ):
        resolved_key = api_key or os.getenv("MELOGEN_API_KEY", "")
        config_kwargs: dict[str, Any] = {
            "api_key": resolved_key,
            "timeout": timeout,
            "poll_interval": poll_interval,
            "poll_timeout": poll_timeout,
        }
        if base_url is not None:
            config_kwargs["base_url"] = base_url

        self._config = Config(**config_kwargs)
        self._auth = AuthManager(self._config)
        self._http = AsyncHttpClient(self._config, self._auth)

        self.sheet2midi = AsyncSheet2MidiClient(self._http)
        self.music2midi = AsyncMusic2MidiClient(self._http)
        self.analysis = AsyncAnalysisClient(self._http)

    async def __aenter__(self) -> AsyncMelogen:
        return self

    async def __aexit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: TracebackType | None,
    ) -> None:
        pass
