"""
bot/handlers/admin/users.py
---------------------------
مدیریت کامل کاربران در پنل ادمین Vasl Bot
"""

from __future__ import annotations

from datetime import datetime

from aiogram import Router
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message
from sqlalchemy import func, or_, select
from sqlalchemy.ext.asyncio import AsyncSession

import config

from database.models import (
    Order,
    OrderStatus,
    Referral,
    Subscription,
    SubscriptionStatus,
    SupportTicket,
    SupportTicketStatus,
    TestRequest,
    TestRequestStatus,
    User,
)


router = Router(name="admin_users")


# ============================================================
# States
# ============================================================

class AdminUserStates(StatesGroup):
    waiting_for_search = State()


# ============================================================
# Admin
# ============================================================

def is_admin_user(user_id: int) -> bool:
    return config.is_admin(user_id)


# ============================================================
# Helpers
# ============================================================

def format_datetime(value: datetime | None) -> str:
    if not value:
        return "ثبت نشده"

    return value.strftime("%Y/%m/%d - %H:%M")


def user_display_name(user: User) -> str:
    parts = []

    if user.first_name:
        parts.append(user.first_name)

    if user.last_name:
        parts.append(user.last_name)

    name = " ".join(parts).strip()

    if name:
        return name

    if user.username:
        return f"@{user.username}"

    return str(user.telegram_id)


def username_text(user: User) -> str:
    if user.username:
        return f"@{user.username}"

    return "ندارد"


def blocked_text(user: User) -> str:
    return "🚫 مسدود" if user.is_blocked else "🟢 فعال"


# ============================================================
# Keyboards
# ============================================================

def users_main_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🔎 جستجوی کاربر",
                    callback_data="admin_users_search",
                )
            ],
            [
                InlineKeyboardButton(
                    text="👥 لیست کاربران",
                    callback_data="admin_users_list:0",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🚫 کاربران مسدود",
                    callback_data="admin_users_blocked:0",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 پنل مدیریت",
                    callback_data="admin_panel",
                )
            ],
        ]
    )


def user_detail_keyboard(
    user_id: int,
    is_blocked: bool,
) -> InlineKeyboardMarkup:

    block_text = (
        "🟢 رفع مسدودی"
        if is_blocked
        else "🚫 مسدود کردن"
    )

    block_callback = (
        f"admin_user_unblock:{user_id}"
        if is_blocked
        else f"admin_user_block:{user_id}"
    )

    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🧾 سفارش‌ها",
                    callback_data=f"admin_user_orders:{user_id}:0",
                ),
                InlineKeyboardButton(
                    text="📦 سرویس‌ها",
                    callback_data=f"admin_user_subs:{user_id}:0",
                ),
            ],
            [
                InlineKeyboardButton(
                    text="👥 معرف‌ها",
                    callback_data=f"admin_user_refs:{user_id}",
                ),
                InlineKeyboardButton(
                    text="🎁 تست‌ها",
                    callback_data=f"admin_user_tests:{user_id}:0",
                ),
            ],
            [
                InlineKeyboardButton(
                    text="🎫 تیکت‌ها",
                    callback_data=f"admin_user_tickets:{user_id}:0",
                )
            ],
            [
                InlineKeyboardButton(
                    text=block_text,
                    callback_data=block_callback,
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 کاربران",
                    callback_data="admin_users_list:0",
                ),
            ],
        ]
    )


def pagination_keyboard(
    prefix: str,
    page: int,
    has_next: bool,
    back_callback: str = "admin_users",
) -> InlineKeyboardMarkup:

    buttons = []

    if page > 0:
        buttons.append(
            InlineKeyboardButton(
                text="⬅️ قبلی",
                callback_data=f"{prefix}:{page - 1}",
            )
        )

    if has_next:
        buttons.append(
            InlineKeyboardButton(
                text="➡️ بعدی",
                callback_data=f"{prefix}:{page + 1}",
            )
        )

    rows = []

    if buttons:
        rows.append(buttons)

    rows.append(
        [
            InlineKeyboardButton(
                text="🔙 مدیریت کاربران",
                callback_data=back_callback,
            )
        ]
    )

    return InlineKeyboardMarkup(
        inline_keyboard=rows
    )


def search_result_keyboard(user_id: int) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="👤 مشاهده پروفایل",
                    callback_data=f"admin_user_view:{user_id}",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔎 جستجوی دوباره",
                    callback_data="admin_users_search",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 مدیریت کاربران",
                    callback_data="admin_users",
                )
            ],
        ]
    )


# ============================================================
# User Detail
# ============================================================

async def get_user_statistics(
    session: AsyncSession,
    user: User,
) -> dict:

    orders_count = await session.scalar(
        select(func.count(Order.id)).where(
            Order.user_id == user.id
        )
    )

    paid_orders_count = await session.scalar(
        select(func.count(Order.id)).where(
            Order.user_id == user.id,
            Order.status.in_(
                [
                    OrderStatus.PAID,
                    OrderStatus.WAITING_CONFIG,
                    OrderStatus.WAITING_SUBSCRIPTION,
                    OrderStatus.COMPLETED,
                ]
            ),
        )
    )

    total_purchase = await session.scalar(
        select(func.coalesce(func.sum(Order.amount), 0)).where(
            Order.user_id == user.id,
            Order.status.in_(
                [
                    OrderStatus.PAID,
                    OrderStatus.WAITING_CONFIG,
                    OrderStatus.WAITING_SUBSCRIPTION,
                    OrderStatus.COMPLETED,
                ]
            ),
        )
    )

    active_subscriptions = await session.scalar(
        select(func.count(Subscription.id)).where(
            Subscription.user_id == user.id,
            Subscription.status == SubscriptionStatus.ACTIVE,
        )
    )

    total_subscriptions = await session.scalar(
        select(func.count(Subscription.id)).where(
            Subscription.user_id == user.id
        )
    )

    referrals = await session.scalar(
        select(func.count(Referral.id)).where(
            Referral.referrer_id == user.id
        )
    )

    successful_referrals = await session.scalar(
        select(func.count(Referral.id)).where(
            Referral.referrer_id == user.id,
            Referral.reward_paid.is_(True),
        )
    )

    test_requests = await session.scalar(
        select(func.count(TestRequest.id)).where(
            TestRequest.user_id == user.id
        )
    )

    approved_tests = await session.scalar(
        select(func.count(TestRequest.id)).where(
            TestRequest.user_id == user.id,
            TestRequest.status == TestRequestStatus.APPROVED,
        )
    )

    tickets = await session.scalar(
        select(func.count(SupportTicket.id)).where(
            SupportTicket.user_id == user.id
        )
    )

    open_tickets = await session.scalar(
        select(func.count(SupportTicket.id)).where(
            SupportTicket.user_id == user.id,
            SupportTicket.status == SupportTicketStatus.OPEN,
        )
    )

    referrer = None

    if user.referred_by_id:
        referrer = await session.scalar(
            select(User).where(
                User.id == user.referred_by_id
            )
        )

    return {
        "orders_count": orders_count or 0,
        "paid_orders_count": paid_orders_count or 0,
        "total_purchase": total_purchase or 0,
        "active_subscriptions": active_subscriptions or 0,
        "total_subscriptions": total_subscriptions or 0,
        "referrals": referrals or 0,
        "successful_referrals": successful_referrals or 0,
        "test_requests": test_requests or 0,
        "approved_tests": approved_tests or 0,
        "tickets": tickets or 0,
        "open_tickets": open_tickets or 0,
        "referrer": referrer,
    }


async def build_user_detail(
    session: AsyncSession,
    user: User,
) -> str:

    stats = await get_user_statistics(
        session,
        user,
    )

    referrer_text = "ندارد"

    if stats["referrer"]:
        referrer = stats["referrer"]

        referrer_name = user_display_name(referrer)

        referrer_text = (
            f"{referrer_name} "
            f"(ID: {referrer.telegram_id})"
        )

    return (
        "👤 <b>اطلاعات کامل کاربر</b>\n"
        "\n"
        f"🆔 <b>ID دیتابیس:</b> <code>{user.id}</code>\n"
        f"🆔 <b>Telegram ID:</b> <code>{user.telegram_id}</code>\n"
        f"👤 <b>نام:</b> {user_display_name(user)}\n"
        f"🔗 <b>Username:</b> {username_text(user)}\n"
        f"📌 <b>وضعیت:</b> {blocked_text(user)}\n"
        "\n"
        "📅 <b>اطلاعات زمانی</b>\n"
        f"➕ ثبت‌نام: <code>{format_datetime(user.created_at)}</code>\n"
        f"🔄 آخرین بروزرسانی اطلاعات: <code>{format_datetime(user.updated_at)}</code>\n"
        "\n"
        "💰 <b>مالی و سفارش‌ها</b>\n"
        f"🧾 کل سفارش‌ها: <b>{stats['orders_count']}</b>\n"
        f"✅ سفارش‌های موفق: <b>{stats['paid_orders_count']}</b>\n"
        f"💵 مجموع خرید موفق: <b>{stats['total_purchase']:,}</b> تومان\n"
        f"💳 موجودی Referral: <b>{user.referral_balance:,}</b> تومان\n"
        "\n"
        "📦 <b>سرویس‌ها</b>\n"
        f"🟢 سرویس فعال: <b>{stats['active_subscriptions']}</b>\n"
        f"📦 کل سرویس‌ها: <b>{stats['total_subscriptions']}</b>\n"
        "\n"
        "👥 <b>معرف و زیرمجموعه</b>\n"
        f"👤 معرف: {referrer_text}\n"
        f"👥 کل زیرمجموعه‌ها: <b>{stats['referrals']}</b>\n"
        f"✅ زیرمجموعه موفق: <b>{stats['successful_referrals']}</b>\n"
        "\n"
        "🎁 <b>اکانت تست</b>\n"
        f"🔢 تعداد استفاده ثبت‌شده: <b>{user.test_account_used_count}</b>\n"
        f"📨 درخواست‌های تست: <b>{stats['test_requests']}</b>\n"
        f"✅ تست‌های تأییدشده: <b>{stats['approved_tests']}</b>\n"
        "\n"
        "🎫 <b>پشتیبانی</b>\n"
        f"🎫 کل تیکت‌ها: <b>{stats['tickets']}</b>\n"
        f"🟢 تیکت باز: <b>{stats['open_tickets']}</b>\n"
    )


# ============================================================
# Main Admin Users Panel
# ============================================================

@router.message(Command("admin_users"))
async def admin_users_command(
    message: Message,
):

    if not is_admin_user(message.from_user.id):
        return

    await message.answer(
        "👥 <b>مدیریت کاربران</b>\n\n"
        "از گزینه‌های زیر استفاده کن:",
        reply_markup=users_main_keyboard(),
    )


@router.callback_query(
    lambda callback: callback.data == "admin_users"
)
async def admin_users_callback(
    callback: CallbackQuery,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    await callback.message.edit_text(
        "👥 <b>مدیریت کاربران</b>\n\n"
        "از گزینه‌های زیر استفاده کن:",
        reply_markup=users_main_keyboard(),
    )

    await callback.answer()


# ============================================================
# Search
# ============================================================

@router.callback_query(
    lambda callback: callback.data == "admin_users_search"
)
async def admin_users_search_callback(
    callback: CallbackQuery,
    state: FSMContext,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    await state.set_state(
        AdminUserStates.waiting_for_search
    )

    await callback.message.answer(
        "🔎 <b>جستجوی کاربر</b>\n\n"
        "یکی از موارد زیر را ارسال کن:\n"
        "\n"
        "• Telegram ID\n"
        "• Username\n"
        "• نام یا نام خانوادگی\n"
        "\n"
        "مثال:\n"
        "<code>123456789</code>\n"
        "<code>@username</code>"
    )

    await callback.answer()


@router.message(
    AdminUserStates.waiting_for_search
)
async def admin_users_search_message(
    message: Message,
    state: FSMContext,
    session: AsyncSession,
):

    if not is_admin_user(message.from_user.id):
        await state.clear()
        return

    query_text = (message.text or "").strip()

    if not query_text:
        await message.answer(
            "❌ عبارت جستجو خالی است."
        )
        return

    await state.clear()

    clean_username = query_text.lstrip("@")

    users = []

    if query_text.isdigit():
        result = await session.execute(
            select(User)
            .where(
                User.telegram_id == int(query_text)
            )
            .limit(1)
        )

        users = list(result.scalars().all())

    else:
        result = await session.execute(
            select(User)
            .where(
                or_(
                    User.username.ilike(
                        f"%{clean_username}%"
                    ),
                    User.first_name.ilike(
                        f"%{query_text}%"
                    ),
                    User.last_name.ilike(
                        f"%{query_text}%"
                    ),
                )
            )
            .order_by(
                User.created_at.desc()
            )
            .limit(20)
        )

        users = list(result.scalars().all())

    if not users:
        await message.answer(
            "❌ کاربری با این مشخصات پیدا نشد.",
            reply_markup=users_main_keyboard(),
        )
        return

    if len(users) == 1:
        user = users[0]

        text = await build_user_detail(
            session,
            user,
        )

        await message.answer(
            text,
            reply_markup=user_detail_keyboard(
                user.id,
                user.is_blocked,
            ),
        )

        return

    buttons = []

    for user in users:
        buttons.append(
            [
                InlineKeyboardButton(
                    text=(
                        f"{user_display_name(user)} "
                        f"— {user.telegram_id}"
                    ),
                    callback_data=f"admin_user_view:{user.id}",
                )
            ]
        )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🔙 مدیریت کاربران",
                callback_data="admin_users",
            )
        ]
    )

    await message.answer(
        f"🔎 <b>{len(users)} کاربر پیدا شد:</b>",
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=buttons
        ),
    )


# ============================================================
# User List
# ============================================================

async def show_users_list(
    callback: CallbackQuery,
    session: AsyncSession,
    page: int,
    blocked_only: bool = False,
):

    page_size = 10
    offset = page * page_size

    conditions = []

    if blocked_only:
        conditions.append(
            User.is_blocked.is_(True)
        )

    total = await session.scalar(
        select(func.count(User.id)).where(
            *conditions
        )
    )

    result = await session.execute(
        select(User)
        .where(*conditions)
        .order_by(
            User.created_at.desc()
        )
        .offset(offset)
        .limit(page_size)
    )

    users = list(result.scalars().all())

    if not users:
        text = (
            "🚫 <b>کاربر مسدودی وجود ندارد.</b>"
            if blocked_only
            else "👥 <b>کاربری ثبت نشده است.</b>"
        )

        await callback.message.edit_text(
            text,
            reply_markup=users_main_keyboard(),
        )

        return

    buttons = []

    for user in users:
        status = "🚫" if user.is_blocked else "🟢"

        buttons.append(
            [
                InlineKeyboardButton(
                    text=(
                        f"{status} "
                        f"{user_display_name(user)} "
                        f"— {user.telegram_id}"
                    ),
                    callback_data=f"admin_user_view:{user.id}",
                )
            ]
        )

    max_page = (
        (total - 1) // page_size
        if total
        else 0
    )

    prefix = (
        "admin_users_blocked"
        if blocked_only
        else "admin_users_list"
    )

    buttons.append(
        [
            InlineKeyboardButton(
                text="⬅️ قبلی" if page > 0 else " ",
                callback_data=(
                    f"{prefix}:{page - 1}"
                    if page > 0
                    else "admin_users"
                ),
            ),
            InlineKeyboardButton(
                text=f"صفحه {page + 1}/{max_page + 1}",
                callback_data="admin_users",
            ),
            InlineKeyboardButton(
                text="➡️ بعدی" if page < max_page else " ",
                callback_data=(
                    f"{prefix}:{page + 1}"
                    if page < max_page
                    else "admin_users"
                ),
            ),
        ]
    )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🔙 مدیریت کاربران",
                callback_data="admin_users",
            )
        ]
    )

    title = (
        "🚫 <b>کاربران مسدود</b>"
        if blocked_only
        else "👥 <b>لیست کاربران</b>"
    )

    await callback.message.edit_text(
        f"{title}\n\n"
        f"تعداد کل: <b>{total}</b>\n"
        f"صفحه: <b>{page + 1}</b>",
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=buttons
        ),
    )


@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_users_list:")
    )
)
async def admin_users_list_callback(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    page = int(
        callback.data.split(":")[1]
    )

    await show_users_list(
        callback,
        session,
        page,
        blocked_only=False,
    )

    await callback.answer()


@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_users_blocked:")
    )
)
async def admin_users_blocked_callback(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    page = int(
        callback.data.split(":")[1]
    )

    await show_users_list(
        callback,
        session,
        page,
        blocked_only=True,
    )

    await callback.answer()


# ============================================================
# View User
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_view:")
    )
)
async def admin_user_view(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    user_id = int(
        callback.data.split(":")[1]
    )

    user = await session.scalar(
        select(User).where(
            User.id == user_id
        )
    )

    if not user:
        await callback.answer(
            "کاربر پیدا نشد.",
            show_alert=True,
        )
        return

    text = await build_user_detail(
        session,
        user,
    )

    await callback.message.edit_text(
        text,
        reply_markup=user_detail_keyboard(
            user.id,
            user.is_blocked,
        ),
    )

    await callback.answer()


# ============================================================
# Block / Unblock
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_block:")
    )
)
async def admin_user_block(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    user_id = int(
        callback.data.split(":")[1]
    )

    user = await session.scalar(
        select(User).where(
            User.id == user_id
        )
    )

    if not user:
        await callback.answer(
            "کاربر پیدا نشد.",
            show_alert=True,
        )
        return

    user.is_blocked = True
    user.updated_at = datetime.utcnow()

    await session.commit()

    await callback.answer(
        "کاربر مسدود شد.",
        show_alert=True,
    )

    text = await build_user_detail(
        session,
        user,
    )

    await callback.message.edit_text(
        text,
        reply_markup=user_detail_keyboard(
            user.id,
            user.is_blocked,
        ),
    )


@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_unblock:")
    )
)
async def admin_user_unblock(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    user_id = int(
        callback.data.split(":")[1]
    )

    user = await session.scalar(
        select(User).where(
            User.id == user_id
        )
    )

    if not user:
        await callback.answer(
            "کاربر پیدا نشد.",
            show_alert=True,
        )
        return

    user.is_blocked = False
    user.updated_at = datetime.utcnow()

    await session.commit()

    await callback.answer(
        "مسدودی کاربر برداشته شد.",
        show_alert=True,
    )

    text = await build_user_detail(
        session,
        user,
    )

    await callback.message.edit_text(
        text,
        reply_markup=user_detail_keyboard(
            user.id,
            user.is_blocked,
        ),
    )


# ============================================================
# Orders
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_orders:")
    )
)
async def admin_user_orders(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    _, user_id, page = callback.data.split(":")

    user_id = int(user_id)
    page = int(page)

    page_size = 8

    result = await session.execute(
        select(Order)
        .where(
            Order.user_id == user_id
        )
        .order_by(
            Order.created_at.desc()
        )
        .offset(page * page_size)
        .limit(page_size + 1)
    )

    orders = list(result.scalars().all())

    has_next = len(orders) > page_size

    if has_next:
        orders = orders[:page_size]

    if not orders:
        await callback.message.edit_text(
            "🧾 <b>سفارشی برای این کاربر ثبت نشده است.</b>",
            reply_markup=InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(
                            text="🔙 پروفایل کاربر",
                            callback_data=f"admin_user_view:{user_id}",
                        )
                    ]
                ]
            ),
        )

        await callback.answer()
        return

    lines = [
        "🧾 <b>سفارش‌های کاربر</b>",
        "",
    ]

    for order in orders:
        lines.append(
            f"🆔 سفارش: <code>{order.id}</code>\n"
            f"💰 مبلغ: <b>{order.amount:,}</b> تومان\n"
            f"📌 وضعیت: <b>{order.status}</b>\n"
            f"🔧 نوع: <b>{order.order_type}</b>\n"
            f"🛠 سرویس: <b>{order.service_name or 'ثبت نشده'}</b>\n"
            f"📅 تاریخ: <code>{format_datetime(order.created_at)}</code>\n"
        )
        lines.append("────────────")

    buttons = []

    if page > 0:
        buttons.append(
            InlineKeyboardButton(
                text="⬅️ قبلی",
                callback_data=f"admin_user_orders:{user_id}:{page - 1}",
            )
        )

    if has_next:
        buttons.append(
            InlineKeyboardButton(
                text="➡️ بعدی",
                callback_data=f"admin_user_orders:{user_id}:{page + 1}",
            )
        )

    rows = []

    if buttons:
        rows.append(buttons)

    rows.append(
        [
            InlineKeyboardButton(
                text="🔙 پروفایل کاربر",
                callback_data=f"admin_user_view:{user_id}",
            )
        ]
    )

    await callback.message.edit_text(
        "\n".join(lines),
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=rows
        ),
    )

    await callback.answer()


# ============================================================
# Subscriptions
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_subs:")
    )
)
async def admin_user_subscriptions(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    _, user_id, page = callback.data.split(":")

    user_id = int(user_id)
    page = int(page)

    page_size = 6

    result = await session.execute(
        select(Subscription)
        .where(
            Subscription.user_id == user_id
        )
        .order_by(
            Subscription.created_at.desc()
        )
        .offset(page * page_size)
        .limit(page_size + 1)
    )

    subscriptions = list(result.scalars().all())

    has_next = len(subscriptions) > page_size

    if has_next:
        subscriptions = subscriptions[:page_size]

    if not subscriptions:
        await callback.message.edit_text(
            "📦 <b>سرویسی برای این کاربر ثبت نشده است.</b>",
            reply_markup=InlineKeyboardMarkup(
                inline_keyboard=[
                    [
                        InlineKeyboardButton(
                            text="🔙 پروفایل کاربر",
                            callback_data=f"admin_user_view:{user_id}",
                        )
                    ]
                ]
            ),
        )

        await callback.answer()
        return

    lines = [
        "📦 <b>سرویس‌های کاربر</b>",
        "",
    ]

    for subscription in subscriptions:
        lines.append(
            f"🆔 سرویس: <code>{subscription.id}</code>\n"
            f"🛠 نام سرویس: <b>{subscription.service_name}</b>\n"
            f"📌 وضعیت: <b>{subscription.status}</b>\n"
            f"▶️ شروع: <code>{format_datetime(subscription.start_date)}</code>\n"
            f"⏰ پایان: <code>{format_datetime(subscription.expire_date)}</code>\n"
        )
        lines.append("────────────")

    buttons = []

    if page > 0:
        buttons.append(
            InlineKeyboardButton(
                text="⬅️ قبلی",
                callback_data=f"admin_user_subs:{user_id}:{page - 1}",
            )
        )

    if has_next:
        buttons.append(
            InlineKeyboardButton(
                text="➡️ بعدی",
                callback_data=f"admin_user_subs:{user_id}:{page + 1}",
            )
        )

    rows = []

    if buttons:
        rows.append(buttons)

    rows.append(
        [
            InlineKeyboardButton(
                text="🔙 پروفایل کاربر",
                callback_data=f"admin_user_view:{user_id}",
            )
        ]
    )

    await callback.message.edit_text(
        "\n".join(lines),
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=rows
        ),
    )

    await callback.answer()


# ============================================================
# Referrals
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_refs:")
    )
)
async def admin_user_referrals(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    user_id = int(
        callback.data.split(":")[1]
    )

    result = await session.execute(
        select(
            Referral,
            User,
        )
        .join(
            User,
            User.id == Referral.referred_user_id,
        )
        .where(
            Referral.referrer_id == user_id
        )
        .order_by(
            Referral.created_at.desc()
        )
        .limit(50)
    )

    rows = result.all()

    if not rows:
        text = (
            "👥 <b>زیرمجموعه‌ای برای این کاربر ثبت نشده است.</b>"
        )

    else:
        lines = [
            "👥 <b>زیرمجموعه‌های کاربر</b>",
            "",
        ]

        for referral, referred_user in rows:
            paid = (
                "✅ موفق"
                if referral.reward_paid
                else "⏳ در انتظار"
            )

            lines.append(
                f"👤 {user_display_name(referred_user)}\n"
                f"🆔 <code>{referred_user.telegram_id}</code>\n"
                f"💰 پاداش: <b>{referral.reward_amount:,}</b>\n"
                f"📌 وضعیت: {paid}\n"
                f"📅 {format_datetime(referral.created_at)}"
            )

            lines.append("────────────")

        text = "\n".join(lines)

    await callback.message.edit_text(
        text,
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=[
                [
                    InlineKeyboardButton(
                        text="🔙 پروفایل کاربر",
                        callback_data=f"admin_user_view:{user_id}",
                    )
                ]
            ]
        ),
    )

    await callback.answer()


# ============================================================
# Test Requests
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_tests:")
    )
)
async def admin_user_tests(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    _, user_id, page = callback.data.split(":")

    user_id = int(user_id)
    page = int(page)

    page_size = 8

    result = await session.execute(
        select(TestRequest)
        .where(
            TestRequest.user_id == user_id
        )
        .order_by(
            TestRequest.created_at.desc()
        )
        .offset(page * page_size)
        .limit(page_size + 1)
    )

    tests = list(result.scalars().all())

    has_next = len(tests) > page_size

    if has_next:
        tests = tests[:page_size]

    if not tests:
        text = "🎁 <b>درخواست تستی برای این کاربر ثبت نشده است.</b>"

    else:
        lines = [
            "🎁 <b>درخواست‌های تست کاربر</b>",
            "",
        ]

        for test in tests:
            lines.append(
                f"🆔 درخواست: <code>{test.id}</code>\n"
                f"📌 وضعیت: <b>{test.status}</b>\n"
                f"📅 ایجاد: <code>{format_datetime(test.created_at)}</code>\n"
                f"🔄 بروزرسانی: <code>{format_datetime(test.updated_at)}</code>"
            )

            lines.append("────────────")

        text = "\n".join(lines)

    buttons = []

    if page > 0:
        buttons.append(
            InlineKeyboardButton(
                text="⬅️ قبلی",
                callback_data=f"admin_user_tests:{user_id}:{page - 1}",
            )
        )

    if has_next:
        buttons.append(
            InlineKeyboardButton(
                text="➡️ بعدی",
                callback_data=f"admin_user_tests:{user_id}:{page + 1}",
            )
        )

    rows = []

    if buttons:
        rows.append(buttons)

    rows.append(
        [
            InlineKeyboardButton(
                text="🔙 پروفایل کاربر",
                callback_data=f"admin_user_view:{user_id}",
            )
        ]
    )

    await callback.message.edit_text(
        text,
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=rows
        ),
    )

    await callback.answer()


# ============================================================
# Support Tickets
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith("admin_user_tickets:")
    )
)
async def admin_user_tickets(
    callback: CallbackQuery,
    session: AsyncSession,
):

    if not is_admin_user(callback.from_user.id):
        await callback.answer(
            "دسترسی ندارید.",
            show_alert=True,
        )
        return

    _, user_id, page = callback.data.split(":")

    user_id = int(user_id)
    page = int(page)

    page_size = 6

    result = await session.execute(
        select(SupportTicket)
        .where(
            SupportTicket.user_id == user_id
        )
        .order_by(
            SupportTicket.created_at.desc()
        )
        .offset(page * page_size)
        .limit(page_size + 1)
    )

    tickets = list(result.scalars().all())

    has_next = len(tickets) > page_size

    if has_next:
        tickets = tickets[:page_size]

    if not tickets:
        text = "🎫 <b>تیکتی برای این کاربر ثبت نشده است.</b>"

    else:
        lines = [
            "🎫 <b>تیکت‌های کاربر</b>",
            "",
        ]

        for ticket in tickets:
            lines.append(
                f"🆔 تیکت: <code>{ticket.id}</code>\n"
                f"📌 وضعیت: <b>{ticket.status.value}</b>\n"
                f"📅 ایجاد: <code>{format_datetime(ticket.created_at)}</code>\n"
                f"🔄 بروزرسانی: <code>{format_datetime(ticket.updated_at)}</code>"
            )

            lines.append("────────────")

        text = "\n".join(lines)

    buttons = []

    if page > 0:
        buttons.append(
            InlineKeyboardButton(
                text="⬅️ قبلی",
                callback_data=f"admin_user_tickets:{user_id}:{page - 1}",
            )
        )

    if has_next:
        buttons.append(
            InlineKeyboardButton(
                text="➡️ بعدی",
                callback_data=f"admin_user_tickets:{user_id}:{page + 1}",
            )
        )

    rows = []

    if buttons:
        rows.append(buttons)

    rows.append(
        [
            InlineKeyboardButton(
                text="🔙 پروفایل کاربر",
                callback_data=f"admin_user_view:{user_id}",
            )
        ]
    )

    await callback.message.edit_text(
        text,
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=rows
        ),
    )

    await callback.answer()
