"""
High-level Waves convenience wrappers.

Usage:
    from smallestai.waves import AsyncWavesClient

    tts = AsyncWavesClient(model="lightning-v3", voice_id="emily", speed=1.1)
    audio = await tts.synthesize("Hello world")
"""

import os
from typing import Any, Dict, Optional

import httpx

DEFAULT_BASE_URL = "https://api.smallest.ai/waves/v1"

_MODEL_ENDPOINTS = {
    "lightning": "/lightning/get_speech",
    "lightning-large": "/lightning-large/get_speech",
    "lightning-v2": "/lightning-v2/get_speech",
    "lightning-v3": "/lightning-v3.1/get_speech",
    "lightning-v3.1": "/lightning-v3.1/get_speech",
}


class AsyncWavesClient:
    """
    High-level async TTS client matching the production SDK interface.

    Wraps the Waves REST API with a simple constructor + synthesize() interface.
    """

    def __init__(
        self,
        model: str = "lightning",
        voice_id: str = "emily",
        speed: float = 1.0,
        language: str = "en",
        sample_rate: int = 24000,
        output_format: str = "wav",
        api_key: Optional[str] = None,
        base_url: Optional[str] = None,
    ):
        self.model = model
        self.voice_id = voice_id
        self.speed = speed
        self.language = language
        self.sample_rate = sample_rate
        self.output_format = output_format
        self.api_key = api_key or os.environ.get("SMALLEST_API_KEY", "")
        self.base_url = base_url or os.environ.get("WAVES_BASE_URL", DEFAULT_BASE_URL)
        self._client: Optional[httpx.AsyncClient] = None

    async def _get_client(self) -> httpx.AsyncClient:
        if self._client is None or self._client.is_closed:
            self._client = httpx.AsyncClient(timeout=60.0)
        return self._client

    async def synthesize(self, text: str, **overrides: Any) -> bytes:
        """Synthesize text to audio bytes."""
        endpoint = _MODEL_ENDPOINTS.get(self.model)
        if endpoint is None:
            raise ValueError(
                f"Unknown model '{self.model}'. "
                f"Supported: {', '.join(_MODEL_ENDPOINTS.keys())}"
            )

        url = f"{self.base_url}{endpoint}"
        payload: Dict[str, Any] = {
            "text": text,
            "voice_id": overrides.get("voice_id", self.voice_id),
            "speed": overrides.get("speed", self.speed),
            "sample_rate": overrides.get("sample_rate", self.sample_rate),
            "language": overrides.get("language", self.language),
            "output_format": overrides.get("output_format", self.output_format),
        }

        client = await self._get_client()
        response = await client.post(
            url,
            json=payload,
            headers={
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
            },
        )
        response.raise_for_status()
        return response.content

    async def close(self) -> None:
        """Close the underlying HTTP client."""
        if self._client and not self._client.is_closed:
            await self._client.aclose()

    async def __aenter__(self) -> "AsyncWavesClient":
        return self

    async def __aexit__(self, *args: Any) -> None:
        await self.close()
