"""Bot API proxy methods (telegram_service).

Uses `self._tg_client` to forward calls to the Telegram Bot API
through the proxy service.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from ._helpers import _sync_request, _async_request
from ._types import TelegramResult

if TYPE_CHECKING:
    import httpx


class ProxyMixin:
    """Sync proxy methods — mixed into TelegramResource."""

    _tg_client: httpx.Client

    def call(self, bot: str, method: str, **params) -> TelegramResult:
        """Call any Telegram Bot API method via the proxy.

        Args:
            bot: Bot alias (registered via register()).
            method: Telegram API method name (e.g. 'sendMessage', 'getMe').
            **params: Method parameters forwarded to Telegram.

        Returns:
            TelegramResult with ok and result fields.

        Example:
            client.telegram.call("my_bot", "sendMessage", chat_id=123, text="Hi")
        """
        data = _sync_request(self._tg_client, "POST", f"/v1/telegram/{bot}/{method}", json=params)
        return TelegramResult.model_validate(data)

    def send_message(
        self, bot: str, chat_id: int | str, text: str, *,
        parse_mode: str = "HTML",
        reply_to_message_id: int | None = None,
        disable_notification: bool = False,
        **kwargs,
    ) -> TelegramResult:
        """Send a text message."""
        return self.call(
            bot, "sendMessage",
            chat_id=chat_id, text=text, parse_mode=parse_mode,
            reply_to_message_id=reply_to_message_id,
            disable_notification=disable_notification,
            **kwargs,
        )

    def send_photo(self, bot: str, chat_id: int | str, photo: str,
                   caption: str = "", **kwargs) -> TelegramResult:
        """Send a photo by URL or file_id."""
        return self.call(bot, "sendPhoto", chat_id=chat_id, photo=photo,
                         caption=caption, **kwargs)

    def send_document(self, bot: str, chat_id: int | str, document: str,
                      caption: str = "", **kwargs) -> TelegramResult:
        """Send a document by URL or file_id."""
        return self.call(bot, "sendDocument", chat_id=chat_id, document=document,
                         caption=caption, **kwargs)

    def get_me(self, bot: str) -> TelegramResult:
        """Get bot info from Telegram."""
        return self.call(bot, "getMe")

    def get_updates(self, bot: str, offset: int | None = None,
                    limit: int = 100, timeout: int = 0) -> list[dict]:
        """Get pending updates via long polling (dev use). Prefer webhooks in prod."""
        result = self.call(bot, "getUpdates",
                           offset=offset, limit=limit, timeout=timeout)
        return result.result or []


class AsyncProxyMixin:
    """Async proxy methods — mixed into AsyncTelegramResource."""

    _tg_client: httpx.AsyncClient

    async def call(self, bot: str, method: str, **params) -> TelegramResult:
        """Call any Telegram Bot API method via the proxy.

        Args:
            bot: Bot alias (registered via register()).
            method: Telegram API method name (e.g. 'sendMessage', 'getMe').
            **params: Method parameters forwarded to Telegram.

        Returns:
            TelegramResult with ok and result fields.

        Example:
            await client.telegram.call("my_bot", "sendMessage", chat_id=123, text="Hi")
        """
        data = await _async_request(
            self._tg_client, "POST", f"/v1/telegram/{bot}/{method}", json=params,
        )
        return TelegramResult.model_validate(data)

    async def send_message(self, bot: str, chat_id: int | str, text: str,
                           **kwargs) -> TelegramResult:
        """Send a text message."""
        return await self.call(bot, "sendMessage", chat_id=chat_id, text=text, **kwargs)

    async def send_photo(self, bot: str, chat_id: int | str, photo: str,
                         **kwargs) -> TelegramResult:
        """Send a photo by URL or file_id."""
        return await self.call(bot, "sendPhoto", chat_id=chat_id, photo=photo, **kwargs)

    async def send_document(self, bot: str, chat_id: int | str, document: str,
                            **kwargs) -> TelegramResult:
        """Send a document by URL or file_id."""
        return await self.call(bot, "sendDocument", chat_id=chat_id, document=document, **kwargs)

    async def get_me(self, bot: str) -> TelegramResult:
        """Get bot info from Telegram."""
        return await self.call(bot, "getMe")

    async def get_updates(self, bot: str, offset: int | None = None,
                          limit: int = 100, timeout: int = 0) -> list[dict]:
        """Get pending updates via long polling (dev use). Prefer webhooks in prod."""
        result = await self.call(bot, "getUpdates",
                                 offset=offset, limit=limit, timeout=timeout)
        return result.result or []
