"""Обёртки над bot.send_message / bot.edit_message с автоматическим логированием."""
from database.queries.message_log import log_message


async def bot_send(
    bot,
    *,
    chat_id: int,
    user_id: int | None,
    text: str,
    attachments=None,
) -> str | None:
    """Отправить новое сообщение. Возвращает message_id (mid) или None."""
    kw: dict = {"chat_id": chat_id, "text": text}
    if attachments is not None:
        kw["attachments"] = attachments
    result = await bot.send_message(**kw)
    mid: str | None = None
    if result and result.message and result.message.body:
        mid = result.message.body.mid
    await log_message(
        direction="out",
        max_user_id=user_id,
        max_chat_id=chat_id,
        message_id=mid,
        text=text,
    )
    return mid


async def bot_edit(
    event,
    *,
    text: str,
    attachments=None,
) -> bool:
    """
    Редактировать сообщение, на которое нажата callback-кнопка.

    Возвращает True при успехе. При ошибке (сообщение удалено, слишком старое)
    возвращает False — вызывающий код должен откатиться на bot_send.
    """
    if event.message is None or event.message.body is None:
        return False
    mid = event.message.body.mid
    chat_id = event.message.recipient.chat_id
    user_id: int | None = getattr(event.callback, "user", None)
    if user_id is not None:
        user_id = getattr(user_id, "user_id", None)
    try:
        await event.bot.edit_message(
            message_id=mid,
            text=text,
            attachments=attachments if attachments is not None else [],
        )
        await log_message(
            direction="out",
            max_user_id=user_id,
            max_chat_id=chat_id,
            message_id=mid,
            text=text,
        )
        return True
    except Exception:
        return False


async def bot_reply(
    event,
    *,
    text: str,
    attachments=None,
    user_id: int | None = None,
    chat_id: int | None = None,
) -> None:
    """
    Для callback-событий: пробует отредактировать текущее сообщение.
    При неудаче отправляет новое.

    Использование в callback-обработчиках вместо bot_send — не создаёт спам.
    """
    edited = await bot_edit(event, text=text, attachments=attachments)
    if not edited:
        _chat_id = chat_id
        if _chat_id is None and event.message is not None:
            _chat_id = event.message.recipient.chat_id
        if _chat_id is not None:
            await bot_send(
                event.bot,
                chat_id=_chat_id,
                user_id=user_id,
                text=text,
                attachments=attachments,
            )
