from __future__ import annotations

from .http import DEFAULT_BASE_URL, DEFAULT_TIMEOUT_S, HttpClient, AsyncHttpClient, RetryConfig
from .storage import StorageClient, AsyncStorageClient
from .stream import StreamClient, AsyncStreamClient
from .athena import AthenaClient, AsyncAthenaClient
from .messaging import MessagingClient, AsyncMessagingClient
from .geocoding import GeocodeClient, AsyncGeocodeClient
from ._version import __version__


class Lamen:
    """Top-level SDK client (sync)."""

    def __init__(
        self,
        *,
        api_key: str,
        base_url: str = DEFAULT_BASE_URL,
        timeout_s: float = DEFAULT_TIMEOUT_S,
        user_agent: str = f"lamen-python/{__version__}",
        retry: RetryConfig | None = None,
    ):
        self._http = HttpClient(
            api_key=api_key,
            base_url=base_url,
            timeout_s=timeout_s,
            user_agent=user_agent,
            retry=retry,
        )

        self.storage = StorageClient(self._http)
        self.stream = StreamClient(self._http)
        self.athena = AthenaClient(self._http)
        self.messaging = MessagingClient(self._http)
        self.geocode = GeocodeClient(self._http)

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

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

    def __exit__(self, exc_type, exc, tb) -> None:
        self.close()


class AsyncLamen:
    """Top-level SDK client (async)."""

    def __init__(
        self,
        *,
        api_key: str,
        base_url: str = DEFAULT_BASE_URL,
        timeout_s: float = DEFAULT_TIMEOUT_S,
        user_agent: str = f"lamen-python/{__version__}",
        retry: RetryConfig | None = None,
    ):
        self._http = AsyncHttpClient(
            api_key=api_key,
            base_url=base_url,
            timeout_s=timeout_s,
            user_agent=user_agent,
            retry=retry,
        )

        self.storage = AsyncStorageClient(self._http)
        self.stream = AsyncStreamClient(self._http)
        self.athena = AsyncAthenaClient(self._http)
        self.messaging = AsyncMessagingClient(self._http)
        self.geocode = AsyncGeocodeClient(self._http) 

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

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

    async def __aexit__(self, exc_type, exc, tb) -> None:
        await self.aclose()
