"""
bot/handlers/admin/support.py
-----------------------------
مدیریت تیکت‌های پشتیبانی توسط ادمین.
"""

from __future__ import annotations

from aiogram import F, Router
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import (
    CallbackQuery,
    InlineKeyboardButton,
    InlineKeyboardMarkup,
    Message,
)
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession

import config

from bot.states.states import AdminSupportReplyStates
from database import crud
from database.models import (
    SenderRole,
    SupportTicket,
    SupportTicketStatus,
)


router = Router(name="admin_support")


# ============================================================
# ADMIN CHECK
# ============================================================

def is_admin_user(user_id: int) -> bool:
    return config.is_admin(user_id)


# ============================================================
# KEYBOARDS
# ============================================================

def admin_support_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🎫 تیکت‌های باز",
                    callback_data="admin_support_open",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 پنل مدیریت",
                    callback_data="admin_panel",
                )
            ],
        ]
    )


def ticket_list_keyboard(
    tickets: list[SupportTicket],
) -> InlineKeyboardMarkup:

    buttons = []

    for ticket in tickets:

        if ticket.user:
            if ticket.user.username:
                username = f"@{ticket.user.username}"
            else:
                username = (
                    f"ID: {ticket.user.telegram_id}"
                )
        else:
            username = "کاربر نامشخص"

        buttons.append(
            [
                InlineKeyboardButton(
                    text=f"🎫 #{ticket.id} — {username}",
                    callback_data=(
                        f"admin_support_ticket:{ticket.id}"
                    ),
                )
            ]
        )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🔙 پنل مدیریت",
                callback_data="admin_support",
            )
        ]
    )

    return InlineKeyboardMarkup(
        inline_keyboard=buttons
    )


def admin_ticket_keyboard(
    ticket_id: int,
) -> InlineKeyboardMarkup:

    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="💬 پاسخ به کاربر",
                    callback_data=(
                        f"admin_support_reply:{ticket_id}"
                    ),
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔒 بستن تیکت",
                    callback_data=(
                        f"admin_support_close:{ticket_id}"
                    ),
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 تیکت‌های باز",
                    callback_data="admin_support_open",
                )
            ],
        ]
    )


# ============================================================
# ADMIN SUPPORT MENU
# ============================================================

@router.message(Command("admin_support"))
async def admin_support_command(
    message: Message,
    state: FSMContext,
):

    if not is_admin_user(
        message.from_user.id
    ):
        return

    await state.clear()

    await message.answer(
        "🛠 <b>مدیریت پشتیبانی</b>\n\n"
        "از این بخش می‌تونی تیکت‌های کاربران رو بررسی و پاسخ بدی.",
        reply_markup=admin_support_keyboard(),
    )


@router.callback_query(F.data == "admin_support")
async def admin_support_menu(
    callback: CallbackQuery,
    state: FSMContext,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    await state.clear()

    await callback.message.edit_text(
        "🛠 <b>مدیریت پشتیبانی</b>\n\n"
        "از این بخش می‌تونی تیکت‌های کاربران رو بررسی و پاسخ بدی.",
        reply_markup=admin_support_keyboard(),
    )

    await callback.answer()


# ============================================================
# OPEN TICKETS
# ============================================================

@router.callback_query(F.data == "admin_support_open")
async def admin_open_tickets(
    callback: CallbackQuery,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    await state.clear()

    result = await session.execute(
        select(SupportTicket)
        .options(
            selectinload(SupportTicket.user)
        )
        .where(
            SupportTicket.status
            == SupportTicketStatus.OPEN.value
        )
        .order_by(
            SupportTicket.id.desc()
        )
    )

    tickets = list(
        result.scalars().all()
    )

    if not tickets:
        await callback.message.edit_text(
            "🎫 <b>تیکت‌های باز</b>\n\n"
            "در حال حاضر تیکت بازی وجود ندارد.",
            reply_markup=admin_support_keyboard(),
        )

        await callback.answer()
        return

    await callback.message.edit_text(
        "🎫 <b>تیکت‌های باز</b>\n\n"
        f"تعداد تیکت‌های باز: <b>{len(tickets)}</b>\n\n"
        "تیکت موردنظر را انتخاب کن:",
        reply_markup=ticket_list_keyboard(
            tickets
        ),
    )

    await callback.answer()


# ============================================================
# SHOW TICKET
# ============================================================

@router.callback_query(
    F.data.startswith("admin_support_ticket:")
)
async def admin_show_ticket(
    callback: CallbackQuery,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    await state.clear()

    try:
        ticket_id = int(
            callback.data.split(":", 1)[1]
        )
    except (ValueError, IndexError):
        await callback.answer(
            "تیکت نامعتبر است.",
            show_alert=True,
        )
        return

    result = await session.execute(
        select(SupportTicket)
        .options(
            selectinload(SupportTicket.user),
            selectinload(SupportTicket.messages),
        )
        .where(
            SupportTicket.id == ticket_id
        )
    )

    ticket = result.scalar_one_or_none()

    if not ticket:
        await callback.answer(
            "تیکت پیدا نشد.",
            show_alert=True,
        )
        return

    if ticket.user:
        user_name = (
            f"{ticket.user.first_name or ''} "
            f"{ticket.user.last_name or ''}"
        ).strip()

        username = (
            f"@{ticket.user.username}"
            if ticket.user.username
            else "بدون یوزرنیم"
        )

        user_info = (
            f"👤 <b>کاربر:</b> "
            f"{user_name or 'بدون نام'}\n"
            f"🆔 <b>Telegram ID:</b> "
            f"<code>{ticket.user.telegram_id}</code>\n"
            f"🔗 <b>Username:</b> "
            f"{username}\n"
        )
    else:
        user_info = (
            "👤 اطلاعات کاربر موجود نیست\n"
        )

    status_text = (
        "🟢 باز"
        if ticket.status
        == SupportTicketStatus.OPEN.value
        else "⚪ بسته"
    )

    text = (
        f"🎫 <b>تیکت #{ticket.id}</b>\n\n"
        f"{user_info}"
        f"📌 <b>وضعیت:</b> {status_text}\n\n"
        "━━━━━━━━━━━━━━\n"
        "💬 <b>پیام‌ها</b>\n"
    )

    if not ticket.messages:
        text += "\nپیامی وجود ندارد."
    else:
        for item in ticket.messages[-15:]:

            if item.sender_role == SenderRole.USER.value:
                sender = "👤 کاربر"
            else:
                sender = "🛠 ادمین"

            text += (
                f"\n<b>{sender}</b>\n"
            )

            if item.text:
                text += (
                    f"{item.text}\n"
                )

            if item.photo_file_id:
                text += (
                    "📷 تصویر ارسال شده\n"
                )

            text += (
                "────────────\n"
            )

    await callback.message.edit_text(
        text,
        reply_markup=admin_ticket_keyboard(
            ticket.id
        ),
    )

    # ارسال تصاویر به صورت جداگانه
    for item in ticket.messages[-15:]:
        if item.photo_file_id:
            try:
                await callback.message.answer_photo(
                    photo=item.photo_file_id,
                    caption="📷 تصویر ارسال‌شده در این تیکت",
                )
            except Exception:
                pass

    await callback.answer()


# ============================================================
# ADMIN REPLY
# ============================================================

@router.callback_query(
    F.data.startswith("admin_support_reply:")
)
async def admin_start_reply(
    callback: CallbackQuery,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    try:
        ticket_id = int(
            callback.data.split(":", 1)[1]
        )
    except (ValueError, IndexError):
        await callback.answer(
            "تیکت نامعتبر است.",
            show_alert=True,
        )
        return

    result = await session.execute(
        select(SupportTicket)
        .where(
            SupportTicket.id == ticket_id
        )
    )

    ticket = result.scalar_one_or_none()

    if not ticket:
        await callback.answer(
            "تیکت پیدا نشد.",
            show_alert=True,
        )
        return

    if ticket.status != SupportTicketStatus.OPEN.value:
        await callback.answer(
            "این تیکت بسته شده است.",
            show_alert=True,
        )
        return

    await state.update_data(
        support_ticket_id=ticket.id
    )

    await state.set_state(
        AdminSupportReplyStates.WAITING_FOR_REPLY
    )

    await callback.message.edit_text(
        f"💬 <b>پاسخ به تیکت #{ticket.id}</b>\n\n"
        "پیام پاسخ را ارسال کن.\n\n"
        "می‌تونی متن یا عکس ارسال کنی.",
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=[
                [
                    InlineKeyboardButton(
                        text="❌ لغو",
                        callback_data=(
                            "admin_support_cancel_reply"
                        ),
                    )
                ]
            ]
        ),
    )

    await callback.answer()


# ============================================================
# ADMIN TEXT REPLY
# ============================================================

@router.message(
    AdminSupportReplyStates.WAITING_FOR_REPLY,
    F.text,
)
async def admin_send_text_reply(
    message: Message,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        message.from_user.id
    ):
        return

    data = await state.get_data()

    ticket_id = data.get(
        "support_ticket_id"
    )

    if not ticket_id:
        await state.clear()

        await message.answer(
            "❌ تیکت مشخص نیست."
        )
        return

    result = await session.execute(
        select(SupportTicket)
        .options(
            selectinload(SupportTicket.user)
        )
        .where(
            SupportTicket.id == int(ticket_id)
        )
    )

    ticket = result.scalar_one_or_none()

    if not ticket:
        await state.clear()

        await message.answer(
            "❌ تیکت پیدا نشد."
        )
        return

    if not ticket.user:
        await state.clear()

        await message.answer(
            "❌ اطلاعات کاربر پیدا نشد."
        )
        return

    if ticket.status != SupportTicketStatus.OPEN.value:
        await state.clear()

        await message.answer(
            "⚠️ این تیکت قبلاً بسته شده است."
        )
        return

    support_message = await crud.add_support_message(
        session,
        ticket.id,
        SenderRole.ADMIN.value,
        text=message.text,
    )

    if not support_message:
        await message.answer(
            "❌ ثبت پاسخ انجام نشد."
        )
        return

    try:
        await message.bot.send_message(
            chat_id=ticket.user.telegram_id,
            text=(
                "📩 <b>پاسخ پشتیبانی</b>\n\n"
                f"🎫 <b>تیکت:</b> "
                f"<code>#{ticket.id}</code>\n\n"
                f"{message.text}\n\n"
                "برای پاسخ دادن، وارد بخش "
                "«تیکت‌های من» شو."
            ),
        )

    except Exception:
        await message.answer(
            "⚠️ پاسخ در تیکت ثبت شد، "
            "اما ارسال پیام برای کاربر انجام نشد."
        )

        await state.clear()
        return

    await state.clear()

    await message.answer(
        f"✅ پاسخ تیکت <code>#{ticket.id}</code> "
        "برای کاربر ارسال شد.",
        reply_markup=admin_support_keyboard(),
    )


# ============================================================
# ADMIN PHOTO REPLY
# ============================================================

@router.message(
    AdminSupportReplyStates.WAITING_FOR_REPLY,
    F.photo,
)
async def admin_send_photo_reply(
    message: Message,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        message.from_user.id
    ):
        return

    data = await state.get_data()

    ticket_id = data.get(
        "support_ticket_id"
    )

    if not ticket_id:
        await state.clear()

        await message.answer(
            "❌ تیکت مشخص نیست."
        )
        return

    result = await session.execute(
        select(SupportTicket)
        .options(
            selectinload(SupportTicket.user)
        )
        .where(
            SupportTicket.id == int(ticket_id)
        )
    )

    ticket = result.scalar_one_or_none()

    if not ticket or not ticket.user:
        await state.clear()

        await message.answer(
            "❌ تیکت یا کاربر پیدا نشد."
        )
        return

    if ticket.status != SupportTicketStatus.OPEN.value:
        await state.clear()

        await message.answer(
            "⚠️ این تیکت قبلاً بسته شده است."
        )
        return

    support_message = await crud.add_support_message(
        session,
        ticket.id,
        SenderRole.ADMIN.value,
        text=message.caption,
        photo_file_id=message.photo[-1].file_id,
    )

    if not support_message:
        await message.answer(
            "❌ ثبت پاسخ انجام نشد."
        )
        return

    try:
        await message.bot.send_photo(
            chat_id=ticket.user.telegram_id,
            photo=message.photo[-1].file_id,
            caption=(
                "📩 <b>پاسخ پشتیبانی</b>\n\n"
                f"🎫 <b>تیکت:</b> "
                f"<code>#{ticket.id}</code>\n\n"
                f"{message.caption or ''}"
            ),
        )

    except Exception:
        await message.answer(
            "⚠️ پاسخ در تیکت ثبت شد، "
            "اما ارسال تصویر برای کاربر انجام نشد."
        )

        await state.clear()
        return

    await state.clear()

    await message.answer(
        f"✅ پاسخ تیکت <code>#{ticket.id}</code> "
        "برای کاربر ارسال شد.",
        reply_markup=admin_support_keyboard(),
    )


# ============================================================
# CANCEL ADMIN REPLY
# ============================================================

@router.callback_query(
    F.data == "admin_support_cancel_reply"
)
async def admin_cancel_reply(
    callback: CallbackQuery,
    state: FSMContext,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    await state.clear()

    await callback.message.edit_text(
        "🛠 <b>مدیریت پشتیبانی</b>\n\n"
        "پاسخ لغو شد.",
        reply_markup=admin_support_keyboard(),
    )

    await callback.answer()


# ============================================================
# CLOSE TICKET
# ============================================================

@router.callback_query(
    F.data.startswith("admin_support_close:")
)
async def admin_close_ticket(
    callback: CallbackQuery,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(
        callback.from_user.id
    ):
        await callback.answer(
            "دسترسی غیرمجاز.",
            show_alert=True,
        )
        return

    try:
        ticket_id = int(
            callback.data.split(":", 1)[1]
        )
    except (ValueError, IndexError):
        await callback.answer(
            "تیکت نامعتبر است.",
            show_alert=True,
        )
        return

    result = await session.execute(
        select(SupportTicket)
        .options(
            selectinload(SupportTicket.user)
        )
        .where(
            SupportTicket.id == ticket_id
        )
    )

    ticket = result.scalar_one_or_none()

    if not ticket:
        await callback.answer(
            "تیکت پیدا نشد.",
            show_alert=True,
        )
        return

    ticket.status = (
        SupportTicketStatus.CLOSED.value
    )

    await session.commit()

    await state.clear()

    if ticket.user:
        try:
            await callback.bot.send_message(
                chat_id=ticket.user.telegram_id,
                text=(
                    "🔒 <b>تیکت پشتیبانی بسته شد.</b>\n\n"
                    f"🎫 شماره تیکت: "
                    f"<code>#{ticket.id}</code>\n\n"
                    "اگر دوباره مشکلی داشتی، "
                    "می‌تونی یک درخواست پشتیبانی جدید ثبت کنی."
                ),
            )
        except Exception:
            pass

    await callback.message.edit_text(
        f"✅ تیکت <code>#{ticket.id}</code> بسته شد.",
        reply_markup=admin_support_keyboard(),
    )

    await callback.answer()