"""
bot/handlers/services.py
-------------------------
مدیریت بخش «سرویس‌های من» و «تمدید سرویس»
"""

from datetime import datetime
from html import escape

from aiogram import Router
from aiogram.fsm.context import FSMContext
from aiogram.types import (
    CallbackQuery,
    InlineKeyboardButton,
    InlineKeyboardMarkup,
)

from database import crud

from bot.keyboards.common import BACK_TO_MAIN_MENU
from bot.keyboards.main_menu import (
    CB_MY_SERVICES,
    CB_RENEW_SERVICE,
)
from bot.states.states import RenewalStates


router = Router(name="services")


# ============================================================
# CALLBACK DATA
# ============================================================

CB_SERVICE_DETAILS_PREFIX = "service_details_"
CB_SERVICES_LIST = "services_list"
CB_RENEW_SERVICE_PREFIX = "renew_service_"


# ============================================================
# KEYBOARDS
# ============================================================

def services_list_keyboard(
    subscriptions,
) -> InlineKeyboardMarkup:

    buttons = []

    for subscription in subscriptions:

        service_name = (
            subscription.service_name
            or f"سرویس #{subscription.id}"
        )

        service_name = escape(
            str(service_name)
        )

        buttons.append(
            [
                InlineKeyboardButton(
                    text=f"📦 {service_name}",
                    callback_data=(
                        f"{CB_SERVICE_DETAILS_PREFIX}"
                        f"{subscription.id}"
                    ),
                )
            ]
        )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🔙 بازگشت به منوی اصلی",
                callback_data=BACK_TO_MAIN_MENU,
            )
        ]
    )

    return InlineKeyboardMarkup(
        inline_keyboard=buttons
    )


def service_details_keyboard(
    subscription_id: int,
) -> InlineKeyboardMarkup:

    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🔄 تمدید این سرویس",
                    callback_data=(
                        f"{CB_RENEW_SERVICE_PREFIX}"
                        f"{subscription_id}"
                    ),
                )
            ],
            [
                InlineKeyboardButton(
                    text="🔙 بازگشت به سرویس‌های من",
                    callback_data=CB_SERVICES_LIST,
                )
            ],
            [
                InlineKeyboardButton(
                    text="🏠 منوی اصلی",
                    callback_data=BACK_TO_MAIN_MENU,
                )
            ],
        ]
    )


def empty_services_keyboard() -> InlineKeyboardMarkup:

    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🛒 خرید اشتراک",
                    callback_data="buy_subscription",
                )
            ],
            [
                InlineKeyboardButton(
                    text="🏠 منوی اصلی",
                    callback_data=BACK_TO_MAIN_MENU,
                )
            ],
        ]
    )


def renewal_services_keyboard(
    subscriptions,
) -> InlineKeyboardMarkup:

    buttons = []

    for subscription in subscriptions:

        service_name = (
            subscription.service_name
            or f"سرویس #{subscription.id}"
        )

        service_name = escape(
            str(service_name)
        )

        buttons.append(
            [
                InlineKeyboardButton(
                    text=f"🔄 {service_name}",
                    callback_data=(
                        f"{CB_RENEW_SERVICE_PREFIX}"
                        f"{subscription.id}"
                    ),
                )
            ]
        )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🏠 منوی اصلی",
                callback_data=BACK_TO_MAIN_MENU,
            )
        ]
    )

    return InlineKeyboardMarkup(
        inline_keyboard=buttons
    )


def no_renewal_services_keyboard() -> InlineKeyboardMarkup:

    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="🛒 خرید اشتراک",
                    callback_data="buy_subscription",
                )
            ],
            [
                InlineKeyboardButton(
                    text="📦 سرویس‌های من",
                    callback_data=CB_MY_SERVICES,
                )
            ],
            [
                InlineKeyboardButton(
                    text="🏠 منوی اصلی",
                    callback_data=BACK_TO_MAIN_MENU,
                )
            ],
        ]
    )


# ============================================================
# HELPERS
# ============================================================

def format_remaining_time(
    expire_date: datetime | None,
) -> str:

    if not expire_date:
        return "نامشخص"

    now = datetime.utcnow()

    remaining = expire_date - now

    if remaining.total_seconds() <= 0:
        return "منقضی شده"

    total_seconds = int(
        remaining.total_seconds()
    )

    days = total_seconds // 86400

    hours = (
        total_seconds % 86400
    ) // 3600

    minutes = (
        total_seconds % 3600
    ) // 60

    if days > 0:
        return f"{days} روز و {hours} ساعت"

    if hours > 0:
        return f"{hours} ساعت و {minutes} دقیقه"

    return f"{minutes} دقیقه"


def get_subscription_status_text(
    subscription,
) -> str:

    if (
        subscription.status == "active"
        and subscription.expire_date
        and subscription.expire_date > datetime.utcnow()
    ):
        return "🟢 فعال"

    return "🔴 منقضی شده"


# ============================================================
# MY SERVICES
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data == CB_MY_SERVICES
    )
)
async def show_my_services(
    callback: CallbackQuery,
    session,
    db_user,
):

    if not db_user:

        await callback.answer(
            "❌ اطلاعات کاربری شما پیدا نشد.",
            show_alert=True,
        )

        return

    subscriptions = await crud.list_user_subscriptions(
        session=session,
        user_id=db_user.id,
    )

    if not subscriptions:

        await callback.message.edit_text(
            "📦 <b>سرویس‌های من</b>\n\n"
            "هنوز هیچ سرویسی برای شما ثبت نشده است.\n\n"
            "برای خرید اولین سرویس، از دکمه زیر استفاده کن.",
            reply_markup=empty_services_keyboard(),
        )

        await callback.answer()

        return

    await callback.message.edit_text(
        "📦 <b>سرویس‌های من</b>\n\n"
        "سرویس موردنظر را انتخاب کن:",
        reply_markup=services_list_keyboard(
            subscriptions
        ),
    )

    await callback.answer()


# ============================================================
# DIRECT RENEWAL FROM MAIN MENU
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data == CB_RENEW_SERVICE
    )
)
async def renew_service_from_main_menu(
    callback: CallbackQuery,
    session,
    db_user,
):

    if not db_user:

        await callback.answer(
            "❌ اطلاعات کاربری شما پیدا نشد.",
            show_alert=True,
        )

        return

    subscriptions = await crud.list_user_subscriptions(
        session=session,
        user_id=db_user.id,
    )

    if not subscriptions:

        await callback.message.edit_text(
            "🔄 <b>تمدید سرویس</b>\n\n"
            "❌ شما در حال حاضر هیچ سرویسی برای تمدید ندارید.\n\n"
            "ابتدا یک سرویس خریداری کن.",
            reply_markup=no_renewal_services_keyboard(),
        )

        await callback.answer()

        return

    await callback.message.edit_text(
        "🔄 <b>تمدید سرویس</b>\n\n"
        "سرویسی که می‌خواهی تمدید کنی را انتخاب کن:",
        reply_markup=renewal_services_keyboard(
            subscriptions
        ),
    )

    await callback.answer()


# ============================================================
# SERVICE DETAILS
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith(
            CB_SERVICE_DETAILS_PREFIX
        )
    )
)
async def show_service_details(
    callback: CallbackQuery,
    session,
    db_user,
):

    if not db_user:

        await callback.answer(
            "❌ اطلاعات کاربری شما پیدا نشد.",
            show_alert=True,
        )

        return

    try:

        subscription_id = int(
            callback.data[
                len(CB_SERVICE_DETAILS_PREFIX):
            ]
        )

    except (
        ValueError,
        TypeError,
    ):

        await callback.answer(
            "❌ سرویس نامعتبر است.",
            show_alert=True,
        )

        return

    subscription = await crud.get_subscription(
        session=session,
        subscription_id=subscription_id,
    )

    if not subscription:

        await callback.answer(
            "❌ این سرویس پیدا نشد.",
            show_alert=True,
        )

        return

    if subscription.user_id != db_user.id:

        await callback.answer(
            "❌ دسترسی به این سرویس امکان‌پذیر نیست.",
            show_alert=True,
        )

        return

    service_name = (
        subscription.service_name
        or f"سرویس #{subscription.id}"
    )

    service_name = escape(
        str(service_name)
    )

    plan_name = (
        subscription.plan.name
        if subscription.plan
        else "نامشخص"
    )

    plan_name = escape(
        str(plan_name)
    )

    volume = (
        subscription.plan.volume_gb
        if subscription.plan
        else None
    )

    volume_text = (
        f"{volume} گیگ"
        if volume is not None and volume > 0
        else "نامحدود / نامشخص"
    )

    status_text = get_subscription_status_text(
        subscription
    )

    remaining_text = format_remaining_time(
        subscription.expire_date
    )

    if subscription.expire_date:

        expire_text = (
            subscription.expire_date.strftime(
                "%Y/%m/%d %H:%M"
            )
        )

    else:

        expire_text = "نامشخص"

    if subscription.config_text:

        config_text = escape(
            str(subscription.config_text)
        )

    else:

        config_text = (
            "هنوز کانفیگی برای این سرویس ثبت نشده است."
        )

    subscription_text = (
        subscription.subscription_text
    )

    if subscription_text:

        subscription_text = escape(
            str(subscription_text)
        )

        subscription_section = (
            "\n\n"
            "🔗 <b>لینک اشتراک:</b>\n"
            f"<code>{subscription_text}</code>"
        )

    else:

        subscription_section = ""

    text = (
        f"📦 <b>{service_name}</b>\n\n"

        f"🆔 شناسه سرویس: "
        f"<code>{subscription.id}</code>\n"

        f"📋 پلن: "
        f"{plan_name}\n"

        f"💾 حجم: "
        f"{volume_text}\n"

        f"📊 وضعیت: "
        f"{status_text}\n"

        f"⏳ زمان باقی‌مانده: "
        f"{remaining_text}\n"

        f"📅 تاریخ انقضا: "
        f"{expire_text}\n\n"

        f"🔐 <b>کانفیگ سرویس:</b>\n"
        f"<pre>{config_text}</pre>"

        f"{subscription_section}"
    )

    await callback.message.edit_text(
        text,
        reply_markup=service_details_keyboard(
            subscription.id
        ),
    )

    await callback.answer()


# ============================================================
# START SERVICE RENEWAL
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data
        and callback.data.startswith(
            CB_RENEW_SERVICE_PREFIX
        )
    )
)
async def start_service_renewal(
    callback: CallbackQuery,
    state: FSMContext,
    session,
    db_user,
):

    if not db_user:

        await callback.answer(
            "❌ اطلاعات کاربری شما پیدا نشد.",
            show_alert=True,
        )

        return

    try:

        subscription_id = int(
            callback.data[
                len(CB_RENEW_SERVICE_PREFIX):
            ]
        )

    except (
        ValueError,
        TypeError,
    ):

        await callback.answer(
            "❌ سرویس نامعتبر است.",
            show_alert=True,
        )

        return

    subscription = await crud.get_subscription(
        session=session,
        subscription_id=subscription_id,
    )

    if not subscription:

        await callback.answer(
            "❌ این سرویس پیدا نشد.",
            show_alert=True,
        )

        return

    # ========================================================
    # SECURITY
    # ========================================================

    if subscription.user_id != db_user.id:

        await callback.answer(
            "❌ دسترسی به این سرویس امکان‌پذیر نیست.",
            show_alert=True,
        )

        return

    # ========================================================
    # FIND PLANS
    # ========================================================

    current_plan = subscription.plan

    plans = []

    # --------------------------------------------------------
    # روش اصلی:
    # service_type + region
    # --------------------------------------------------------

    if (
        current_plan
        and current_plan.service_type
    ):

        plans = await crud.list_active_plans_for_service(
            session=session,
            service_type=current_plan.service_type,
            region=current_plan.region,
        )

    # --------------------------------------------------------
    # Fallback برای Planهای قدیمی
    # --------------------------------------------------------

    if not plans and current_plan:

        current_plan_name = (
            current_plan.name
            or ""
        )

        name_parts = [
            part.strip()
            for part in current_plan_name.split("—")
        ]

        if len(name_parts) >= 2:

            service_prefix = (
                f"{name_parts[0]} — "
                f"{name_parts[1]} —"
            )

            all_plans = await crud.list_active_plans(
                session=session,
            )

            plans = [
                plan
                for plan in all_plans
                if (
                    plan.name
                    and str(plan.name).startswith(
                        service_prefix
                    )
                )
            ]

    # --------------------------------------------------------
    # اگر هنوز پلنی پیدا نشد
    # --------------------------------------------------------

    if not plans:

        await callback.answer(
            "❌ در حال حاضر پلن مناسبی برای تمدید این سرویس وجود ندارد.",
            show_alert=True,
        )

        return

    # ========================================================
    # RENEWAL STATE
    # ========================================================

    await state.clear()

    await state.update_data(
        renewal_subscription_id=subscription.id
    )

    await state.set_state(
        RenewalStates.CHOOSING_PLAN
    )

    # ========================================================
    # PLAN KEYBOARD
    # ========================================================

    buttons = []

    for plan in plans:

        plan_name = escape(
            str(plan.name)
        )

        price = f"{plan.price:,}"

        duration = (
            plan.duration_days
            or 30
        )

        buttons.append(
            [
                InlineKeyboardButton(
                    text=(
                        f"🔄 {plan_name} | "
                        f"{price} تومان"
                    ),
                    callback_data=(
                        f"renewplan_"
                        f"{subscription.id}_"
                        f"{plan.id}"
                    ),
                )
            ]
        )

    buttons.append(
        [
            InlineKeyboardButton(
                text="🔙 بازگشت به سرویس",
                callback_data=(
                    f"{CB_SERVICE_DETAILS_PREFIX}"
                    f"{subscription.id}"
                ),
            )
        ]
    )

    service_name = (
        subscription.service_name
        or f"سرویس #{subscription.id}"
    )

    await callback.message.edit_text(
        "🔄 <b>تمدید سرویس</b>\n\n"
        f"📦 <b>سرویس:</b> "
        f"{escape(str(service_name))}\n\n"
        "پلن موردنظر برای تمدید را انتخاب کن:",
        reply_markup=InlineKeyboardMarkup(
            inline_keyboard=buttons
        ),
    )

    await callback.answer()


# ============================================================
# BACK TO SERVICES LIST
# ============================================================

@router.callback_query(
    lambda callback: (
        callback.data == CB_SERVICES_LIST
    )
)
async def back_to_services_list(
    callback: CallbackQuery,
    session,
    db_user,
):

    if not db_user:

        await callback.answer(
            "❌ اطلاعات کاربری شما پیدا نشد.",
            show_alert=True,
        )

        return

    subscriptions = await crud.list_user_subscriptions(
        session=session,
        user_id=db_user.id,
    )

    if not subscriptions:

        await callback.message.edit_text(
            "📦 <b>سرویس‌های من</b>\n\n"
            "هنوز هیچ سرویسی برای شما ثبت نشده است.",
            reply_markup=empty_services_keyboard(),
        )

        await callback.answer()

        return

    await callback.message.edit_text(
        "📦 <b>سرویس‌های من</b>\n\n"
        "سرویس موردنظر را انتخاب کن:",
        reply_markup=services_list_keyboard(
            subscriptions
        ),
    )

    await callback.answer()