"""Main Fish Audio client classes."""

from typing import Optional

import httpx

from .core import AsyncClientWrapper, ClientWrapper
from .resources import (
    ASRClient,
    AccountClient,
    AsyncAccountClient,
    AsyncASRClient,
    AsyncTTSClient,
    AsyncVoicesClient,
    TTSClient,
    VoicesClient,
)


class FishAudio:
    """
    Synchronous Fish Audio API client.

    Example:
        ```python
        from fishaudio import FishAudio

        client = FishAudio(api_key="your_api_key")

        # Generate speech
        audio = client.tts.convert(text="Hello world")
        with open("output.mp3", "wb") as f:
            for chunk in audio:
                f.write(chunk)

        # List voices
        voices = client.voices.list(page_size=20)
        print(f"Found {voices.total} voices")
        ```
    """

    def __init__(
        self,
        *,
        api_key: Optional[str] = None,
        base_url: str = "https://api.fish.audio",
        timeout: float = 240.0,
        httpx_client: Optional[httpx.Client] = None,
    ):
        """
        Initialize Fish Audio client.

        Args:
            api_key: API key (can also use FISH_API_KEY env var)
            base_url: API base URL
            timeout: Request timeout in seconds
            httpx_client: Optional custom HTTP client
        """
        self._client_wrapper = ClientWrapper(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            httpx_client=httpx_client,
        )

        # Lazy-loaded namespace clients
        self._tts: Optional[TTSClient] = None
        self._asr: Optional[ASRClient] = None
        self._voices: Optional[VoicesClient] = None
        self._account: Optional[AccountClient] = None

    @property
    def tts(self) -> TTSClient:
        """Access TTS (text-to-speech) operations."""
        if self._tts is None:
            self._tts = TTSClient(self._client_wrapper)
        return self._tts

    @property
    def asr(self) -> ASRClient:
        """Access ASR (speech-to-text) operations."""
        if self._asr is None:
            self._asr = ASRClient(self._client_wrapper)
        return self._asr

    @property
    def voices(self) -> VoicesClient:
        """Access voice management operations."""
        if self._voices is None:
            self._voices = VoicesClient(self._client_wrapper)
        return self._voices

    @property
    def account(self) -> AccountClient:
        """Access account/billing operations."""
        if self._account is None:
            self._account = AccountClient(self._client_wrapper)
        return self._account

    def close(self) -> None:
        """Close the HTTP client."""
        self._client_wrapper.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()


class AsyncFishAudio:
    """
    Asynchronous Fish Audio API client.

    Example:
        ```python
        from fishaudio import AsyncFishAudio

        async def main():
            client = AsyncFishAudio(api_key="your_api_key")

            # Generate speech
            audio = client.tts.convert(text="Hello world")
            async with aiofiles.open("output.mp3", "wb") as f:
                async for chunk in audio:
                    await f.write(chunk)

            # List voices
            voices = await client.voices.list(page_size=20)
            print(f"Found {voices.total} voices")

        asyncio.run(main())
        ```
    """

    def __init__(
        self,
        *,
        api_key: Optional[str] = None,
        base_url: str = "https://api.fish.audio",
        timeout: float = 240.0,
        httpx_client: Optional[httpx.AsyncClient] = None,
    ):
        """
        Initialize async Fish Audio client.

        Args:
            api_key: API key (can also use FISH_API_KEY env var)
            base_url: API base URL
            timeout: Request timeout in seconds
            httpx_client: Optional custom async HTTP client
        """
        self._client_wrapper = AsyncClientWrapper(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            httpx_client=httpx_client,
        )

        # Lazy-loaded namespace clients
        self._tts: Optional[AsyncTTSClient] = None
        self._asr: Optional[AsyncASRClient] = None
        self._voices: Optional[AsyncVoicesClient] = None
        self._account: Optional[AsyncAccountClient] = None

    @property
    def tts(self) -> AsyncTTSClient:
        """Access TTS (text-to-speech) operations."""
        if self._tts is None:
            self._tts = AsyncTTSClient(self._client_wrapper)
        return self._tts

    @property
    def asr(self) -> AsyncASRClient:
        """Access ASR (speech-to-text) operations."""
        if self._asr is None:
            self._asr = AsyncASRClient(self._client_wrapper)
        return self._asr

    @property
    def voices(self) -> AsyncVoicesClient:
        """Access voice management operations."""
        if self._voices is None:
            self._voices = AsyncVoicesClient(self._client_wrapper)
        return self._voices

    @property
    def account(self) -> AsyncAccountClient:
        """Access account/billing operations."""
        if self._account is None:
            self._account = AsyncAccountClient(self._client_wrapper)
        return self._account

    async def close(self) -> None:
        """Close the HTTP client."""
        await self._client_wrapper.close()

    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.close()
