"""Main asynchronous client for sed.sh API."""

from typing import Optional
import aiohttp
from sed_sh.config import Config
from sed_sh.services.async_links import AsyncLinksService
from sed_sh.services.async_malware import AsyncMalwareService
from sed_sh.services.async_inbox import AsyncInboxService
from sed_sh.services.async_routes import AsyncRoutesService
from sed_sh.services.async_reports import AsyncReportsService


class AsyncSedSH:
    """Main asynchronous client for sed.sh API.

    This client provides async access to all sed.sh services through a unified interface.

    Authentication:
        API key can be provided in three ways (in order of priority):
        1. Directly in constructor: AsyncSedSH(api_key="your-key")
        2. Environment variable: SEDSH_API_KEY
        3. Config file: ~/.sedsh/config.json

    Example:
        >>> import asyncio
        >>> from sed_sh import AsyncSedSH
        >>>
        >>> async def main():
        ...     # Context manager automatically handles session lifecycle
        ...     async with AsyncSedSH(api_key="your-key") as client:
        ...         # Use services with await
        ...         link = await client.links.create("https://example.com")
        ...         inbox = await client.inbox.create()
        ...         print(f"Link: {link['shortUrl']}")
        ...         print(f"Inbox: {inbox['email']}")
        >>>
        >>> asyncio.run(main())

    Attributes:
        links: Async links/URL shortener service
        malware: Async malware scanning service
        inbox: Async disposable email inbox service
        routes: Async mock API/Routes service
        reports: Async PDF reports service
    """

    def __init__(
        self,
        api_key: Optional[str] = None,
        base_url: Optional[str] = None,
        timeout: Optional[int] = None,
    ):
        """Initialize the async sed.sh client.

        Args:
            api_key: API key (optional if set via env var or config file)
            base_url: API base URL (default: https://api.sed.sh)
            timeout: Request timeout in seconds (default: 30)

        Raises:
            ValueError: If API key cannot be found
        """
        # Load configuration
        config = Config.load(api_key=api_key, base_url=base_url, timeout=timeout)

        self.api_key = config["api_key"]
        self.base_url = config["base_url"]
        self.timeout = config["timeout"]

        if not self.api_key:
            raise ValueError(
                "API key not found. Provide it via:\n"
                "1. Constructor: AsyncSedSH(api_key='your-key')\n"
                "2. Environment: export SEDSH_API_KEY='your-key'\n"
                "3. Config file: ~/.sedsh/config.json"
            )

        # Session will be created in __aenter__
        self.session: Optional[aiohttp.ClientSession] = None

        # Services will be initialized in __aenter__
        self.links: Optional[AsyncLinksService] = None
        self.malware: Optional[AsyncMalwareService] = None
        self.inbox: Optional[AsyncInboxService] = None
        self.routes: Optional[AsyncRoutesService] = None
        self.reports: Optional[AsyncReportsService] = None

    async def __aenter__(self):
        """Async context manager entry."""
        # Create aiohttp session
        self.session = aiohttp.ClientSession(
            headers={"Authorization": f"Bearer {self.api_key}"},
            timeout=aiohttp.ClientTimeout(total=self.timeout),
        )

        # Initialize services with shared session
        self.links = AsyncLinksService(
            base_url=self.base_url,
            api_key=self.api_key,
            timeout=self.timeout,
            session=self.session,
        )
        self.malware = AsyncMalwareService(
            base_url=self.base_url,
            api_key=self.api_key,
            timeout=self.timeout,
            session=self.session,
        )
        self.inbox = AsyncInboxService(
            base_url=self.base_url,
            api_key=self.api_key,
            timeout=self.timeout,
            session=self.session,
        )
        self.routes = AsyncRoutesService(
            base_url=self.base_url,
            api_key=self.api_key,
            timeout=self.timeout,
            session=self.session,
        )
        self.reports = AsyncReportsService(
            base_url=self.base_url,
            api_key=self.api_key,
            timeout=self.timeout,
            session=self.session,
        )

        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """Async context manager exit."""
        await self.close()

    async def close(self):
        """Close the HTTP session."""
        if self.session:
            await self.session.close()
