from typing import Dict
from aiogram import Router, F
from aiogram.filters import Command, StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, InlineKeyboardButton, CallbackQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
from bot.core.bots import BotInfo
from bot.utils import status_clear
from configs import COMMANDS, ImportantID
from middleware.loggers import log

# user_id -> thread_id (топик пользователя)
user_topic_map: Dict[int, int] = {}
# message_id в топике -> user_id
topic_message_map: Dict[int, int] = {}

__all__ = ("router", "user_topic_map")
CMD: str = "new"
router: Router = Router(name=f"{CMD}_cmd_router")

STATE_WAITING_REQUEST = "waiting_request"


def has_active_topic(user_id: int) -> bool:
    """Проверяет, есть ли у пользователя активный топик"""
    return user_id in user_topic_map


async def send_topic_message(user_id: int, text: str, reply_markup=None):
    """Отправляет сообщение в топик пользователя"""
    thread_id = user_topic_map.get(user_id)
    if not thread_id:
        return False

    try:
        await BotInfo.bot.send_message(
            chat_id=ImportantID.SUPPORT_CHAT_ID,
            message_thread_id=thread_id,
            text=text,
            parse_mode="HTML",
            reply_markup=reply_markup
        )
        return True
    except Exception as e:
        log(level='ERROR', log_type='TOPIC_SEND', text=f"Ошибка отправки в топик: {e}")
        return False


# ===================== Продолжение диалога =====================
@router.callback_query(F.data == "continue_dialog")
async def continue_dialog_callback(callback: CallbackQuery, state: FSMContext) -> None:
    """Обработчик продолжения существующего диалога"""
    user_id = callback.from_user.id

    if not has_active_topic(user_id):
        await callback.answer("❌ Активный диалог не найден", show_alert=True)
        return

    ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
    ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))

    await callback.message.edit_text(
        text="💬 У вас уже есть активный диалог с поддержкой. Просто отправьте ваше сообщение (не через reply) и оно будет переслано администратору.",
        reply_markup=ikb.as_markup()
    )
    await callback.answer()


# ===================== Обработчик callback /new =====================
@router.callback_query(F.data.casefold() == CMD)
@log(level='INFO', log_type=f"{CMD.upper()}_CBD", text=f"использовал команду /{CMD} через кнопку")
async def new_cmd_callback(callback: CallbackQuery, state: FSMContext) -> None:
    """Обработчик команды /new из callback кнопки"""
    user_id = callback.from_user.id

    # Проверяем, есть ли уже активный топик
    if has_active_topic(user_id):
        ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
        ikb.row(InlineKeyboardButton(text="Продолжить диалог💬", callback_data='continue_dialog'))
        ikb.row(InlineKeyboardButton(text="Создать новый📝", callback_data='force_new'))

        await callback.message.edit_text(
            text="⚠️ У вас уже есть активный диалог с поддержкой.\n\n"
                 "• <b>Продолжить текущий</b> - чтобы писать в существующий диалог\n"
                 "• <b>Создать новый</b> - если хотите начать новый запрос (старый диалог будет архивирован)",
            reply_markup=ikb.as_markup(),
            parse_mode="HTML"
        )
        await callback.answer()
        return

    await status_clear(message=callback.message, state=state)
    await state.set_state(STATE_WAITING_REQUEST)

    ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
    ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))

    try:
        await callback.message.edit_text(
            text="Отправьте свой запрос:",
            reply_markup=ikb.as_markup()
        )
    except Exception:
        await callback.message.answer(
            text="Отправьте свой запрос:",
            reply_markup=ikb.as_markup()
        )
    await callback.answer()


# ===================== Принудительное создание нового топика =====================
@router.callback_query(F.data == "force_new")
async def force_new_callback(callback: CallbackQuery, state: FSMContext) -> None:
    """Принудительное создание нового топика (при наличии активного)"""
    user_id = callback.from_user.id

    # Уведомляем в старом топике о создании нового
    if has_active_topic(user_id):
        await send_topic_message(
            user_id,
            f"🔔 <b>Пользователь начал новый запрос</b>\n"
            f"Старый топик будет архивирован."
        )
        # Не удаляем старый топик из мапы сразу - он перезапишется при создании нового

    await status_clear(message=callback.message, state=state)
    await state.set_state(STATE_WAITING_REQUEST)

    ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
    ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))

    await callback.message.edit_text(
        text="📝 <b>Создание нового запроса</b>\n\nОтправьте ваш запрос:",
        reply_markup=ikb.as_markup(),
        parse_mode="HTML"
    )
    await callback.answer()


# ===================== Обработчик сообщения /new =====================
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
@log(level='INFO', log_type=CMD.upper(), text=f"использовал команду /{CMD}")
async def new_cmd_message(message: Message, state: FSMContext) -> None:
    """Обработчик команды /new из текстового сообщения"""
    user_id = message.from_user.id

    # Проверяем, есть ли уже активный топик
    if has_active_topic(user_id):
        ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
        ikb.row(InlineKeyboardButton(text="Продолжить диалог💬", callback_data='continue_dialog'))

        await message.answer(
            text="⚠️ У вас уже есть активный диалог с поддержкой.\n\n"
                 "Используйте кнопку ниже чтобы продолжить общение в существующем диалоге.",
            reply_markup=ikb.as_markup(),
            parse_mode="HTML"
        )
        return

    await status_clear(message=message, state=state)
    await state.set_state(STATE_WAITING_REQUEST)

    ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
    ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))

    await message.answer(
        text="Отправьте свой запрос:",
        reply_markup=ikb.as_markup()
    )


# ===================== Создание топика и отправка запроса =====================
@router.message(StateFilter(STATE_WAITING_REQUEST))
async def process_request(message: Message, state: FSMContext) -> None:
    """Создание топика и отправка запроса пользователя"""
    text = message.text.strip()
    if not text:
        await message.reply("⚠️ Пожалуйста, отправьте непустое сообщение.")
        return

    user = message.from_user

    try:
        # Создаем новый топик для пользователя
        topic_name = f"👤 {user.full_name} (ID: {user.id})"
        topic_result = await message.bot.create_forum_topic(
            chat_id=ImportantID.SUPPORT_CHAT_ID,
            name=topic_name
        )

        thread_id = topic_result.message_thread_id

        # Отправляем сообщение пользователя в новый топик
        formatted_text = f"<b>📩 Сообщение от <a href='tg://user?id={user.id}'>{user.full_name}</a>:</b>\n{text}"
        sent_msg = await message.bot.send_message(
            chat_id=ImportantID.SUPPORT_CHAT_ID,
            message_thread_id=thread_id,
            text=formatted_text,
            parse_mode="HTML"
        )

        # Отправляем сообщение с уведомлением (со звуком)
        await message.bot.send_message(
            chat_id=ImportantID.SUPPORT_CHAT_ID,
            message_thread_id=thread_id,
            text="🔔 <b>Новый запрос создан</b>\nАдминистратор уведомлен.",
            parse_mode="HTML"
        )

        # Сохраняем связь пользователя и топика
        user_topic_map[user.id] = thread_id
        topic_message_map[sent_msg.message_id] = user.id

        ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
        ikb.row(InlineKeyboardButton(text="Перейти к диалогу💬", callback_data='continue_dialog'))
        ikb.row(InlineKeyboardButton(text="В меню↩️", callback_data='start'))

        await message.answer(
            text="✅ <b>Запрос отправлен!</b>\n\n"
                 "Администратор ответит в этом боте. Вы можете продолжить общение через меню.",
            reply_markup=ikb.as_markup(),
            parse_mode="HTML"
        )
        await state.clear()

    except Exception as e:
        await message.reply(f"⚠️ Не удалось создать запрос: {e}")


# ===================== Пересылка сообщений пользователя в топик =====================
@router.message(F.chat.type == "private", ~F.reply_to_message)
async def forward_user_to_admin(message: Message) -> None:
    """Пересылает сообщения пользователя в топик (если есть активный диалог)"""
    if message.from_user.is_bot:
        return

    user_id = message.from_user.id

    # Проверяем, есть ли активный топик
    if not has_active_topic(user_id):
        return  # Нет активного топика - игнорируем

    # Получаем топик пользователя
    thread_id = user_topic_map.get(user_id)
    if not thread_id:
        return

    try:
        # Отправляем сообщение пользователя в топик
        if message.text:
            formatted_text = f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}"
            sent_msg = await message.bot.send_message(
                chat_id=ImportantID.SUPPORT_CHAT_ID,
                message_thread_id=thread_id,
                text=formatted_text,
                parse_mode="HTML"
            )
            topic_message_map[sent_msg.message_id] = user_id

        elif message.photo:
            caption = f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}" if message.caption else f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>"
            sent_msg = await message.bot.send_photo(
                chat_id=ImportantID.SUPPORT_CHAT_ID,
                message_thread_id=thread_id,
                photo=message.photo[-1].file_id,
                caption=caption,
                parse_mode="HTML"
            )
            topic_message_map[sent_msg.message_id] = user_id

        await message.answer("✅ Сообщение отправлено администратору")

    except Exception as e:
        await message.answer(f"⚠️ Не удалось отправить сообщение: {e}")


# ===================== Пересылка ответов админа пользователю =====================
@router.message(F.chat.id == ImportantID.SUPPORT_CHAT_ID, F.message_thread_id)
async def forward_admin_to_user(message: Message) -> None:
    """Пересылает сообщения админа из топика пользователю"""
    if message.from_user.is_bot:
        return

    thread_id = message.message_thread_id

    # Ищем пользователя по thread_id топика
    user_id = None
    for uid, tid in user_topic_map.items():
        if tid == thread_id:
            user_id = uid
            break

    if not user_id:
        return  # Не наш топик

    try:
        # Пересылаем сообщение админа пользователю
        if message.text:
            text = f"<b>👨‍💼 Ответ администратора:</b>\n{message.html_text}"
            sent_msg = await message.bot.send_message(
                chat_id=user_id,
                text=text,
                parse_mode="HTML"
            )
            # Сохраняем связь для возможного ответа пользователя
            topic_message_map[sent_msg.message_id] = user_id

        elif message.photo:
            caption = f"<b>👨‍💼 Ответ администратора:</b>\n{message.html_text}" if message.caption else "<b>👨‍💼 Ответ администратора:</b>"
            await message.bot.send_photo(
                chat_id=user_id,
                photo=message.photo[-1].file_id,
                caption=caption,
                parse_mode="HTML"
            )

    except Exception as e:
        log(level='ERROR', log_type='FORWARD', text=f"Ошибка пересылки админ->пользователь: {e}")


# ===================== Пересылка ответов пользователя в топик =====================
@router.message(F.chat.type == "private", F.reply_to_message)
async def forward_user_reply_to_admin(message: Message) -> None:
    """Пересылает ответы пользователя (reply) в топик"""
    if message.from_user.is_bot:
        return

    user_id = message.from_user.id
    reply_to_id = message.reply_to_message.message_id

    # Проверяем, является ли это ответом на сообщение из топика
    original_user_id = topic_message_map.get(reply_to_id)
    if not original_user_id or original_user_id != user_id:
        return

    # Получаем топик пользователя
    thread_id = user_topic_map.get(user_id)
    if not thread_id:
        await message.reply("⚠️ Не найден активный диалог. Используйте /new для нового запроса.")
        return

    try:
        # Отправляем ответ пользователя в топик
        if message.text:
            formatted_text = f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}"
            sent_msg = await message.bot.send_message(
                chat_id=ImportantID.SUPPORT_CHAT_ID,
                message_thread_id=thread_id,
                text=formatted_text,
                parse_mode="HTML"
            )
            topic_message_map[sent_msg.message_id] = user_id

        elif message.photo:
            caption = f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}" if message.caption else f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>"
            sent_msg = await message.bot.send_photo(
                chat_id=ImportantID.SUPPORT_CHAT_ID,
                message_thread_id=thread_id,
                photo=message.photo[-1].file_id,
                caption=caption,
                parse_mode="HTML"
            )
            topic_message_map[sent_msg.message_id] = user_id

        await message.reply("✅ Ответ отправлен администратору.")

    except Exception as e:
        await message.reply(f"⚠️ Не удалось отправить ответ: {e}")
