"""Async SDKRouter client."""

from __future__ import annotations

import logging
from typing import Any, Optional, Type, cast

from openai import AsyncOpenAI

from .._config import SDKConfig
from .._constants import DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT
from .._types.parsed import ParsedChatCompletion
from ..utils.parsing import ResponseFormatT, type_to_response_format

from ._base import resolve_init_params
from ._helpers import LazyTool, merge_provider_extra_body, parse_completion
from ._sync import _build_parse_params

# Async tool imports
from ..tools.vision import AsyncVisionResource
from ..tools.cdn import AsyncCDNResource
from ..tools.shortlinks import AsyncShortlinksResource
from ..tools.keys import AsyncKeysResource
from ..tools.cleaner import AsyncCleanerResource
from ..tools.models import AsyncModelsResource
from ..tools.research import AsyncResearchResource
from ..tools.embeddings import AsyncEmbeddingsResource
from ..tools.image_gen import AsyncImageGenResource
from ..tools.audio import AsyncAudioResource
from ..tools.payments import AsyncPaymentsResource
from ..tools.proxies import AsyncProxiesResource
from ..tools.translator import AsyncTranslatorResource
from ..tools.knowbase import AsyncKnowledgeBaseResource
from ..tools.banner import AsyncBannerResource
from ..tools.crawler import AsyncCrawlerResource
from ..tools.email import AsyncEmailResource
from ..tools.telegram import AsyncTelegramResource

logger = logging.getLogger(__name__)


class AsyncSDKRouter(AsyncOpenAI):
    """Async SDK client — OpenAI-compatible with additional tools.

    Example:
        ```python
        from sdkrouter import AsyncSDKRouter

        client = AsyncSDKRouter(api_key="sk_live_...")
        response = await client.chat.completions.create(
            model="openai/gpt-4o",
            messages=[{"role": "user", "content": "Hello!"}],
        )
        ```
    """

    # ── Tool properties (lazy-loaded via descriptor) ─────────────────────
    vision = LazyTool("_vision", AsyncVisionResource, "Vision analysis and OCR")
    cdn = LazyTool("_cdn", AsyncCDNResource, "CDN file storage")
    shortlinks = LazyTool("_shortlinks", AsyncShortlinksResource, "URL shortening")
    keys = LazyTool("_keys", AsyncKeysResource, "API keys management")
    cleaner = LazyTool("_api_cleaner", AsyncCleanerResource, "HTML cleaner")
    llm_models = LazyTool("_models", AsyncModelsResource, "LLM models listing")
    research = LazyTool("_search", AsyncResearchResource, "Web research")
    image_gen = LazyTool("_image_gen", AsyncImageGenResource, "AI image generation")
    payments = LazyTool("_payments", AsyncPaymentsResource, "Crypto payments")
    proxies = LazyTool("_proxies", AsyncProxiesResource, "Proxy management")
    translator = LazyTool("_translator", AsyncTranslatorResource, "Translation")
    knowbase = LazyTool("_knowbase", AsyncKnowledgeBaseResource, "Knowledge base")
    banner = LazyTool("_banner", AsyncBannerResource, "Banner generator")
    crawler = LazyTool("_crawler", AsyncCrawlerResource, "Web scraping")
    email = LazyTool("_email", AsyncEmailResource, "Email gateway")
    telegram = LazyTool("_telegram", AsyncTelegramResource, "Telegram bots + MTProto")

    def __init__(
        self,
        *,
        api_key: Optional[str] = None,
        llm_url: Optional[str] = None,
        api_url: Optional[str] = None,
        audio_url: Optional[str] = None,
        dev: bool = False,
        use_self_hosted: bool = True,
        openrouter_api_key: Optional[str] = None,
        provider: Optional[str] = None,
        timeout: float = DEFAULT_TIMEOUT,
        max_retries: int = DEFAULT_MAX_RETRIES,
        **kwargs,
    ):
        """Initialize async SDKRouter. Same args as SDKRouter."""
        resolved_key, openai_base_url, _, _, config = resolve_init_params(
            api_key=api_key, llm_url=llm_url, api_url=api_url, audio_url=audio_url,
            dev=dev, use_self_hosted=use_self_hosted,
            openrouter_api_key=openrouter_api_key, provider=provider,
            timeout=timeout, max_retries=max_retries,
        )

        kwargs.pop("base_url", None)
        super().__init__(
            api_key=resolved_key,
            base_url=openai_base_url,
            timeout=timeout,
            max_retries=max_retries,
            **kwargs,
        )

        self._provider = provider
        self._sdk_config = config

    @property
    def embeddings(self) -> AsyncEmbeddingsResource:  # type: ignore[override]
        if not hasattr(self, "_embeddings") or self._embeddings is None:
            self._embeddings = AsyncEmbeddingsResource(self._sdk_config)
            self._embeddings._provider = self._provider
        return self._embeddings

    @property
    def audio(self) -> AsyncAudioResource:  # type: ignore[override]
        if not hasattr(self, "_audio") or self._audio is None:
            self._audio = AsyncAudioResource(self._sdk_config)
        return self._audio

    @property
    def config(self) -> SDKConfig:
        return self._sdk_config

    async def parse(
        self,
        *,
        model: str,
        messages: list[dict[str, Any]],
        response_format: Type[ResponseFormatT],
        temperature: Optional[float] = None,
        max_tokens: Optional[int] = None,
        top_p: Optional[float] = None,
        frequency_penalty: Optional[float] = None,
        presence_penalty: Optional[float] = None,
        stop: Optional[list[str]] = None,
        seed: Optional[int] = None,
        **kwargs: Any,
    ) -> ParsedChatCompletion[ResponseFormatT]:
        """Async chat completion with structured output."""
        format_param = type_to_response_format(response_format)
        params = _build_parse_params(
            model, messages, format_param,
            temperature, max_tokens, top_p,
            frequency_penalty, presence_penalty, stop, seed,
            **kwargs,
        )
        merge_provider_extra_body(self._provider, params)
        raw = await self.chat.completions.create(**params)
        return parse_completion(raw, response_format)
