"""
Утилиты навигационных переходов.

Логика:
  - Если кнопка нажата на последнем навигационном сообщении (nav_mid в контексте),
    редактируем его на месте (edit-in-place).
  - Иначе удаляем триггерное сообщение и отправляем новое в конец чата.

nav_mid сохраняется в контексте и обновляется при каждом nav_finish.
"""
from __future__ import annotations

from maxapi.context import BaseContext
from maxapi.types.updates.message_callback import MessageCallback

from bot.send_helper import bot_send


async def nav_prepare(
    event: MessageCallback,
    context: BaseContext,
    loading_text: str,
    chat_id: int | None,
    user_id: int,
) -> str | None:
    """
    Начать навигационный переход: показать индикатор загрузки.

    Возвращает mid, который нужно передать в nav_finish.
    """
    trigger_mid = event.message.body.mid if (event.message and event.message.body) else None
    data = await context.get_data()
    nav_mid = data.get("nav_mid")

    if trigger_mid and trigger_mid == nav_mid:
        # Это последнее навигационное сообщение — редактируем на месте
        try:
            await event.bot.edit_message(
                message_id=trigger_mid,
                text=loading_text,
                attachments=[],
            )
            return trigger_mid
        except Exception:
            pass  # fallthrough: отправим новое

    # Старое сообщение (или nav_mid не совпадает) → удаляем и отправляем новое
    if trigger_mid:
        try:
            await event.bot.delete_message(message_id=trigger_mid)
        except Exception:
            pass

    return await bot_send(
        event.bot,
        chat_id=chat_id,
        user_id=user_id,
        text=loading_text,
        attachments=[],
    )


async def nav_finish(
    bot,
    context: BaseContext,
    mid: str | None,
    chat_id: int | None,
    user_id: int,
    text: str,
    attachments: list,
) -> str | None:
    """
    Завершить навигационный переход: вставить финальный контент в mid.
    При неудаче редактирования — отправляет новое сообщение.
    Всегда обновляет nav_mid в контексте.
    """
    result_mid: str | None = None

    if mid:
        try:
            await bot.edit_message(
                message_id=mid,
                text=text,
                attachments=attachments or [],
            )
            result_mid = mid
        except Exception:
            pass

    if not result_mid:
        result_mid = await bot_send(
            bot,
            chat_id=chat_id,
            user_id=user_id,
            text=text,
            attachments=attachments,
        )

    # Обновляем nav_mid, сохраняя остальные данные контекста
    data = await context.get_data()
    data["nav_mid"] = result_mid
    await context.set_data(data)
    return result_mid


async def nav_set(context: BaseContext, mid: str | None) -> None:
    """Сохранить nav_mid после ручной отправки навигационного сообщения."""
    data = await context.get_data()
    data["nav_mid"] = mid
    await context.set_data(data)
