"""aiogram implementation of the Telegram gateway."""

from __future__ import annotations

import logging
from typing import Any

from aiogram import Bot
from aiogram.exceptions import TelegramBadRequest
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, LinkPreviewOptions

from app.gateways.base import BotIdentity, ChatInfo, ChatMemberInfo, MessageRef

logger = logging.getLogger(__name__)


def _keyboard(buttons: list[tuple[str, str]] | None) -> InlineKeyboardMarkup | None:
    if not buttons:
        return None
    rows: list[list[InlineKeyboardButton]] = []
    row: list[InlineKeyboardButton] = []
    for text, url in buttons:
        row.append(InlineKeyboardButton(text=text, url=url))
        if len(row) == 2:
            rows.append(row)
            row = []
    if row:
        rows.append(row)
    return InlineKeyboardMarkup(inline_keyboard=rows)


class AiogramGateway:
    def __init__(self, bot: Bot) -> None:
        self.bot = bot

    async def get_me(self) -> BotIdentity:
        me = await self.bot.get_me()
        return BotIdentity(id=me.id, username=me.username)

    async def get_chat(self, chat_id: int) -> ChatInfo:
        chat = await self.bot.get_chat(chat_id)
        return ChatInfo(
            chat_id=chat.id,
            title=chat.title,
            username=chat.username,
            chat_type=chat.type,
        )

    async def get_chat_member(self, chat_id: int, user_id: int) -> ChatMemberInfo:
        member = await self.bot.get_chat_member(chat_id=chat_id, user_id=user_id)
        return ChatMemberInfo(
            status=member.status,
            is_member=getattr(member, "is_member", None),
        )

    async def send_video(
        self,
        chat_id: int,
        file_id: str,
        *,
        caption: str | None,
        thumbnail_file_id: str | None = None,
        protect_content: bool = False,
        buttons: list[tuple[str, str]] | None = None,
    ) -> MessageRef:
        payload: dict[str, Any] = {
            "chat_id": chat_id,
            "video": file_id,
            "caption": caption or None,
            "protect_content": protect_content,
            "reply_markup": _keyboard(buttons),
        }
        if thumbnail_file_id:
            payload["thumbnail"] = thumbnail_file_id
        try:
            message = await self.bot.send_video(**payload)
        except TelegramBadRequest as exc:
            if thumbnail_file_id and "thumbnail" in str(exc).lower():
                logger.warning("cover thumbnail was rejected; sending video without cover")
                payload.pop("thumbnail", None)
                message = await self.bot.send_video(**payload)
            else:
                raise
        return MessageRef(chat_id=message.chat.id, message_id=message.message_id)

    async def send_message(
        self,
        chat_id: int,
        text: str,
        *,
        protect_content: bool = False,
        buttons: list[tuple[str, str]] | None = None,
    ) -> MessageRef:
        message = await self.bot.send_message(
            chat_id=chat_id,
            text=text,
            protect_content=protect_content,
            reply_markup=_keyboard(buttons),
            link_preview_options=LinkPreviewOptions(is_disabled=True),
        )
        return MessageRef(chat_id=message.chat.id, message_id=message.message_id)

    async def delete_message(self, chat_id: int, message_id: int) -> None:
        await self.bot.delete_message(chat_id=chat_id, message_id=message_id)
