"""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),
        }
        # aiogram 3.x requires an InputFile for thumbnail uploads.
        # A Telegram file_id string is not a valid thumbnail InputFile.
        # Skip the thumbnail and send the video normally.
        if thumbnail_file_id:
            logger.info("Skipping thumbnail file_id; sending video without cover")
        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)
