"""
Main client classes. Users interact with these.

Usage:
    import nanorix

    # Sync
    client = nanorix.Client(api_key="nrx_live_...")

    # Async
    client = nanorix.AsyncClient(api_key="nrx_live_...")
"""
from nanorix._constants import DEFAULT_BASE_URL, DEFAULT_TIMEOUT, MAX_RETRIES
from nanorix._http import AsyncHttpTransport, HttpTransport
from nanorix.resources.capsules import AsyncCapsules, Capsules
from nanorix.resources.cdp import AsyncCdpResource, CdpResource
from nanorix.resources.templates import AsyncTemplates, Templates


class Client:
    """
    Synchronous Nanorix API client.

    Usage:
        client = nanorix.Client(api_key="nrx_live_...")
        template = client.templates.create(...)
        result, cdp = client.capsules.run(template=template.id, ...)
    """

    def __init__(
        self,
        api_key: str,
        *,
        base_url: str = DEFAULT_BASE_URL,
        timeout: float = DEFAULT_TIMEOUT,
        max_retries: int = MAX_RETRIES,
    ) -> None:
        if not api_key or not api_key.startswith(("nrx_live_", "nrx_test_")):
            raise ValueError(
                "Invalid API key. Keys must start with 'nrx_live_' or 'nrx_test_'. "
                "Get your key at https://app.nanorix.io/settings/api-keys"
            )

        self._http = HttpTransport(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
        )

        self.templates = Templates(self._http)
        self.capsules = Capsules(self._http)
        self.cdp = CdpResource(self._http)

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

    def __enter__(self) -> "Client":
        return self

    def __exit__(self, *args: object) -> None:
        self.close()


class AsyncClient:
    """
    Asynchronous Nanorix API client.

    Usage:
        async with nanorix.AsyncClient(api_key="nrx_live_...") as client:
            template = await client.templates.create(...)
            result, cdp = await client.capsules.run(template=template.id, ...)
    """

    def __init__(
        self,
        api_key: str,
        *,
        base_url: str = DEFAULT_BASE_URL,
        timeout: float = DEFAULT_TIMEOUT,
        max_retries: int = MAX_RETRIES,
    ) -> None:
        if not api_key or not api_key.startswith(("nrx_live_", "nrx_test_")):
            raise ValueError(
                "Invalid API key. Keys must start with 'nrx_live_' or 'nrx_test_'. "
                "Get your key at https://app.nanorix.io/settings/api-keys"
            )

        self._http = AsyncHttpTransport(
            api_key=api_key,
            base_url=base_url,
            timeout=timeout,
            max_retries=max_retries,
        )

        self.templates = AsyncTemplates(self._http)
        self.capsules = AsyncCapsules(self._http)
        self.cdp = AsyncCdpResource(self._http)

    async def close(self) -> None:
        await self._http.close()

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

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