"""
Обработчик команды /emoji для извлечения ID премиум эмодзи
"""
from aiogram import Router
from aiogram.filters import Command
from aiogram.types import Message
from aiogram.utils.keyboard import InlineKeyboardBuilder

from bot.filters.admin import IsAdmin
from configs import settings, COMMANDS
from middleware.loggers import logger

__all__ = ("router",)

router: Router = Router(name="emoji_extractor_router")

MAX_MSG_LEN = 3800  # Безопасный лимит (4096 - запас)
SEPARATOR = "\n" + "─" * 30 + "\n\n"


# ================= ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ =================

def _utf16_slice(text: str, offset: int, length: int) -> str:
    """
    Корректно извлекает подстроку с учётом UTF-16 смещений Telegram API.
    Telegram передаёт offset/length в UTF-16 code units, а не в Unicode codepoints.
    """
    encoded = text.encode("utf-16-le")
    return encoded[offset * 2 : (offset + length) * 2].decode("utf-16-le")


def extract_custom_emojis(message: Message) -> list[dict]:
    """
    Извлекает все кастомные эмодзи из сообщения (текст + подпись).

    Returns:
        Список словарей: {"char": str, "id": str, "offset": int}
    """
    text = message.text or message.caption
    entities = message.entities or message.caption_entities

    if not text or not entities:
        return []

    custom_emojis = []
    for entity in entities:
        if entity.type == "custom_emoji":
            emoji_char = _utf16_slice(text, entity.offset, entity.length)
            custom_emojis.append({
                "char": emoji_char,
                "id": entity.custom_emoji_id,
                "offset": entity.offset,
            })

    return custom_emojis


def format_emoji_html(emoji_char: str, emoji_id: str) -> str:
    return f'<tg-emoji emoji-id="{emoji_id}">{emoji_char}</tg-emoji>'


def escape_html(text: str) -> str:
    return (
        text.replace("&", "&amp;")
            .replace("<", "&lt;")
            .replace(">", "&gt;")
    )


def _build_emoji_block(idx: int, emoji_data: dict, is_last: bool) -> str:
    """Формирует текстовый блок для одного эмодзи."""
    emoji_char = emoji_data["char"]
    emoji_id = emoji_data["id"]
    html_code = format_emoji_html(emoji_char, emoji_id)
    html_escaped = escape_html(html_code)

    block = (
        f"<b>{idx}.</b> Эмодзи: {emoji_char}\n"
        f"📋 <b>ID:</b> <code>{emoji_id}</code>\n\n"
        f"📝 <b>HTML-код:</b>\n"
        f"<code>{html_escaped}</code>\n\n"
        f"🎨 <b>Превью:</b> {html_code}\n"
    )

    if not is_last:
        block += SEPARATOR

    return block


def build_pages(custom_emojis: list[dict]) -> list[str]:
    """
    Разбивает список эмодзи на страницы, каждая не длиннее MAX_MSG_LEN.
    Возвращает список готовых HTML-строк для отправки.
    """
    total = len(custom_emojis)
    pages: list[str] = []
    current_page = ""

    for idx, emoji_data in enumerate(custom_emojis, 1):
        is_last = (idx == total)
        block = _build_emoji_block(idx, emoji_data, is_last)

        if current_page and len(current_page) + len(block) > MAX_MSG_LEN:
            pages.append(current_page)
            current_page = block
        else:
            current_page += block

    if current_page:
        pages.append(current_page)

    return pages


# ================= КОМАНДА /EMOJI =================

@router.message(
    Command(*COMMANDS.get("emoji", ["emoji"]), prefix=settings.PREFIX, ignore_case=True),
    IsAdmin()
)
async def emoji_extractor_cmd(message: Message) -> None:
    if not message.reply_to_message:
        await message.answer(
            "❌ <b>Используйте команду в ответ на сообщение</b>\n\n"
            "📝 Как использовать:\n"
            "1. Ответьте на сообщение с премиум эмодзи\n"
            "2. Напишите <code>/emoji</code>\n\n"
            "💡 <i>Бот извлечёт все кастомные эмодзи и покажет HTML-код</i>",
            parse_mode="HTML",
        )
        return

    replied_message = message.reply_to_message
    custom_emojis = extract_custom_emojis(replied_message)

    if not custom_emojis:
        await message.answer(
            "⚠️ <b>Кастомные эмодзи не найдены</b>\n\n"
            "В этом сообщении нет премиум эмодзи.\n\n"
            "💡 <i>Попробуйте ответить на сообщение с анимированными эмодзи</i>",
            parse_mode="HTML",
        )
        return

    total = len(custom_emojis)
    pages = build_pages(custom_emojis)
    total_pages = len(pages)

    ikb = InlineKeyboardBuilder()
    ikb.button(text="✖️ Закрыть", callback_data="emoji_close")

    try:
        for page_num, page_content in enumerate(pages, 1):
            # Заголовок только на первой странице
            if page_num == 1:
                header = f"✨ <b>НАЙДЕНО ЭМОДЗИ: {total}</b>\n\n"
            else:
                header = f"✨ <b>ПРОДОЛЖЕНИЕ ({page_num}/{total_pages})</b>\n\n"

            # Подвал только на последней странице
            footer = (
                "\n\n💡 <i>Скопируйте HTML-код и используйте в своих сообщениях</i>"
                if page_num == total_pages
                else ""
            )

            # Кнопка закрытия только на последней странице
            markup = ikb.as_markup() if page_num == total_pages else None

            await message.answer(
                text=header + page_content + footer,
                parse_mode="HTML",
                reply_markup=markup,
            )

        logger.info(
            f"Извлечено {total} кастомных эмодзи ({total_pages} стр.) "
            f"админом {message.from_user.id}",
            log_type="EMOJI_EXTRACT",
        )

    except Exception as e:
        logger.error(f"Ошибка отправки эмодзи: {e}", log_type="ERROR")
        await message.answer(
            "❌ <b>Ошибка извлечения эмодзи</b>\n\n"
            "Попробуйте позже или обратитесь к разработчику.",
            parse_mode="HTML",
        )


# ================= ОБРАБОТЧИК КНОПКИ ЗАКРЫТИЯ =================

@router.callback_query(lambda c: c.data == "emoji_close", IsAdmin())
async def emoji_close_callback(callback) -> None:
    try:
        await callback.message.delete()
        await callback.answer("✅ Закрыто")
    except Exception as e:
        logger.error(f"Ошибка удаления сообщения с эмодзи: {e}", log_type="ERROR")
        await callback.answer("❌ Не удалось удалить", show_alert=True)


# ================= ДОПОЛНИТЕЛЬНАЯ КОМАНДА /EMOJIHELP =================

@router.message(
    Command(*COMMANDS.get("emojihelp", ["emojihelp"]), prefix=settings.PREFIX, ignore_case=True),
    IsAdmin()
)
async def emoji_help_cmd(message: Message) -> None:
    text = (
        "🎨 <b>РАБОТА С КАСТОМНЫМИ ЭМОДЗИ</b>\n\n"
        "📝 <b>Команда /emoji</b>\n"
        "Извлекает ID премиум эмодзи из сообщения\n\n"
        "🔧 <b>Как использовать:</b>\n"
        "1️⃣ Ответьте на сообщение с эмодзи\n"
        "2️⃣ Напишите <code>/emoji</code>\n"
        "3️⃣ Скопируйте HTML-код\n\n"
        "💻 <b>Формат HTML-кода:</b>\n"
        '<code>&lt;tg-emoji emoji-id="ID"&gt;fallback&lt;/tg-emoji&gt;</code>\n\n'
        "⚠️ <b>Важно:</b>\n"
        '├─ Используйте <code>parse_mode="HTML"</code>\n'
        "├─ Пользователи без Premium видят fallback\n"
        "└─ Работает только с кастомными эмодзи\n\n"
        "💡 <i>Попробуйте отправить эмодзи и ответить командой /emoji</i>"
    )
    await message.answer(text, parse_mode="HTML")
