"""
bot/handlers/payment.py
-----------------------
سیستم پرداخت، دریافت رسید و ارسال رسید برای ادمین‌ها.
"""

from __future__ import annotations

import logging

from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import (
    CallbackQuery,
    InlineKeyboardButton,
    InlineKeyboardMarkup,
    Message,
)
from sqlalchemy import select

from database.database import AsyncSessionLocal
from database.crud import (
    create_order,
    get_order,
    get_user_by_telegram_id,
    set_order_receipt,
)
from database.models import OrderStatus, Plan

from bot.states.payment import PaymentStates


router = Router()

logger = logging.getLogger(__name__)


# ============================================================
# تنظیمات
# ============================================================

CARD_NUMBER = "6219861431917714"
CARD_OWNER = "بلو علیرضا اناری"

ADMIN_IDS = [
    7060604210,
    438941870,
]


# ============================================================
# قیمت‌های اقتصادی مستقیم
# ============================================================

ECONOMIC_DIRECT_PLANS = {
    "1": 4000,
    "10": 28000,
    "20": 48000,
    "30": 67000,
    "40": 84000,
    "50": 101000,
    "60": 119000,
    "100": 184000,
}


# ============================================================
# تبدیل قیمت
# ============================================================

def format_price(price: int) -> str:
    return f"{price:,}".translate(
        str.maketrans(
            "0123456789",
            "۰۱۲۳۴۵۶۷۸۹",
        )
    )


# ============================================================
# کیبورد پرداخت
# ============================================================

def payment_keyboard(order_id: int) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="📸 ارسال رسید پرداخت",
                    callback_data=f"send_receipt:{order_id}",
                )
            ],
            [
                InlineKeyboardButton(
                    text="❌ لغو سفارش",
                    callback_data=f"cancel_order:{order_id}",
                )
            ],
        ]
    )


# ============================================================
# کیبورد بعد از ارسال رسید
# ============================================================

def admin_payment_keyboard(order_id: int) -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text="✅ تأیید پرداخت",
                    callback_data=f"approve_payment:{order_id}",
                ),
                InlineKeyboardButton(
                    text="❌ رد پرداخت",
                    callback_data=f"reject_payment:{order_id}",
                ),
            ]
        ]
    )


# ============================================================
# انتخاب پلن اقتصادی مستقیم
# ============================================================

@router.callback_query(
    F.data.startswith("economic_direct_")
)
async def create_economic_direct_order(
    callback: CallbackQuery,
    state: FSMContext,
):
    try:

        volume = callback.data.split("_")[-1]

        if volume not in ECONOMIC_DIRECT_PLANS:
            await callback.answer(
                "❌ این پلن پیدا نشد.",
                show_alert=True,
            )
            return

        price = ECONOMIC_DIRECT_PLANS[volume]

        async with AsyncSessionLocal() as session:

            user = await get_user_by_telegram_id(
                session,
                callback.from_user.id,
            )

            if not user:
                await callback.answer(
                    "❌ اطلاعات کاربر پیدا نشد.",
                    show_alert=True,
                )
                return

            result = await session.execute(
                select(Plan)
                .where(
                    Plan.volume_gb == int(volume),
                    Plan.price == price,
                    Plan.is_active.is_(True),
                )
                .order_by(Plan.id.asc())
            )

            plan = result.scalars().first()

            if not plan:
                await callback.answer(
                    "❌ این پلن هنوز در دیتابیس ثبت نشده است.",
                    show_alert=True,
                )

                logger.warning(
                    "Plan not found | volume=%s | price=%s",
                    volume,
                    price,
                )

                return

            order = await create_order(
                session=session,
                user_id=user.id,
                plan_id=plan.id,
                amount=price,
            )

        # ----------------------------------------------------
        # ذخیره سفارش در FSM
        # ----------------------------------------------------

        await state.update_data(
            order_id=order.id
        )

        # ----------------------------------------------------
        # نمایش پرداخت
        # ----------------------------------------------------

        text = (
            "💳 <b>پرداخت سفارش</b>\n\n"
            f"🧾 <b>شماره سفارش:</b> <code>#{order.id}</code>\n"
            f"📦 <b>پلن:</b> {volume} گیگ یک ماهه\n"
            f"💰 <b>مبلغ:</b> {format_price(price)} تومان\n\n"
            "━━━━━━━━━━━━━━━━━━\n\n"
            "💳 <b>شماره کارت:</b>\n"
            f"<code>{CARD_NUMBER}</code>\n\n"
            f"👤 <b>به نام:</b> {CARD_OWNER}\n\n"
            "━━━━━━━━━━━━━━━━━━\n\n"
            "🔹 مبلغ دقیق را واریز کنید.\n"
            "🔹 سپس روی «📸 ارسال رسید پرداخت» بزنید.\n"
        )

        await callback.message.edit_text(
            text,
            reply_markup=payment_keyboard(order.id),
        )

        await callback.answer()

    except Exception:

        logger.exception(
            "Error creating order"
        )

        await callback.answer(
            "❌ هنگام ایجاد سفارش خطایی رخ داد.",
            show_alert=True,
        )


# ============================================================
# درخواست ارسال رسید
# ============================================================

@router.callback_query(
    F.data.startswith("send_receipt:")
)
async def request_receipt(
    callback: CallbackQuery,
    state: FSMContext,
):

    try:

        order_id = int(
            callback.data.split(":")[1]
        )

    except (ValueError, IndexError):

        await callback.answer(
            "❌ سفارش نامعتبر است.",
            show_alert=True,
        )
        return

    async with AsyncSessionLocal() as session:

        order = await get_order(
            session,
            order_id,
        )

    if not order:

        await callback.answer(
            "❌ سفارش پیدا نشد.",
            show_alert=True,
        )

        return

    # --------------------------------------------------------
    # بررسی مالک سفارش
    # --------------------------------------------------------

    if order.user.telegram_id != callback.from_user.id:

        await callback.answer(
            "❌ این سفارش متعلق به شما نیست.",
            show_alert=True,
        )

        return

    # --------------------------------------------------------
    # بررسی وضعیت
    # --------------------------------------------------------

    if order.status != OrderStatus.WAITING_RECEIPT.value:

        await callback.answer(
            "⚠️ این سفارش دیگر منتظر رسید نیست.",
            show_alert=True,
        )

        return

    # --------------------------------------------------------
    # ذخیره order_id در FSM
    # --------------------------------------------------------

    await state.update_data(
        order_id=order_id
    )

    await state.set_state(
        PaymentStates.waiting_receipt
    )

    await callback.message.edit_text(
        "📸 <b>ارسال رسید پرداخت</b>\n\n"
        f"🧾 شماره سفارش: <code>#{order.id}</code>\n\n"
        "لطفاً <b>عکس رسید پرداخت</b> را همینجا ارسال کنید.\n\n"
        "⚠️ فقط عکس رسید را ارسال کنید.",
    )

    await callback.answer()


# ============================================================
# دریافت عکس رسید
# ============================================================

@router.message(
    PaymentStates.waiting_receipt,
    F.photo,
)
async def receive_receipt(
    message: Message,
    state: FSMContext,
):

    data = await state.get_data()

    order_id = data.get("order_id")

    if not order_id:

        await state.clear()

        await message.answer(
            "❌ سفارش مربوط به این رسید پیدا نشد."
        )

        return

    # --------------------------------------------------------
    # دریافت بزرگ‌ترین سایز عکس
    # --------------------------------------------------------

    photo = message.photo[-1]

    file_id = photo.file_id

    # --------------------------------------------------------
    # ثبت رسید در دیتابیس
    # --------------------------------------------------------

    async with AsyncSessionLocal() as session:

        order = await get_order(
            session,
            order_id,
        )

        if not order:

            await state.clear()

            await message.answer(
                "❌ سفارش پیدا نشد."
            )

            return

        if order.user.telegram_id != message.from_user.id:

            await state.clear()

            await message.answer(
                "❌ این سفارش متعلق به شما نیست."
            )

            return

        if order.status != OrderStatus.WAITING_RECEIPT.value:

            await state.clear()

            await message.answer(
                "⚠️ این سفارش قبلاً رسید دریافت کرده است."
            )

            return

        updated_order = await set_order_receipt(
            session=session,
            order_id=order_id,
            file_id=file_id,
        )

    # --------------------------------------------------------
    # پاک کردن FSM
    # --------------------------------------------------------

    await state.clear()

    # --------------------------------------------------------
    # اطلاع به کاربر
    # --------------------------------------------------------

    await message.answer(
        "✅ <b>رسید شما با موفقیت دریافت شد.</b>\n\n"
        f"🧾 شماره سفارش: <code>#{order_id}</code>\n\n"
        "⏳ رسید شما برای پشتیبانی ارسال شد.\n"
        "لطفاً تا بررسی پرداخت منتظر بمانید.",
    )

    # --------------------------------------------------------
    # ارسال رسید برای ادمین‌ها
    # --------------------------------------------------------

    admin_text = (
        "💰 <b>رسید پرداخت جدید</b>\n\n"
        f"🧾 <b>سفارش:</b> #{order_id}\n"
        f"👤 <b>کاربر:</b> {message.from_user.full_name}\n"
        f"🆔 <b>Telegram ID:</b> <code>{message.from_user.id}</code>\n"
    )

    if message.from_user.username:
        admin_text += (
            f"📱 <b>Username:</b> @{message.from_user.username}\n"
        )

    admin_text += (
        f"\n💰 <b>مبلغ:</b> "
        f"{format_price(updated_order.amount)} تومان\n"
    )

    for admin_id in ADMIN_IDS:

        try:

            await message.bot.send_photo(
                chat_id=admin_id,
                photo=file_id,
                caption=admin_text,
                reply_markup=admin_payment_keyboard(
                    order_id
                ),
            )

        except Exception:

            logger.exception(
                "Could not send receipt to admin %s",
                admin_id,
            )


# ============================================================
# اگر کاربر به جای عکس، متن فرستاد
# ============================================================

@router.message(
    PaymentStates.waiting_receipt,
)
async def receipt_wrong_format(
    message: Message,
):

    await message.answer(
        "⚠️ لطفاً <b>عکس رسید پرداخت</b> را ارسال کنید.\n\n"
        "اگر رسید را ندارید، ابتدا پرداخت را انجام دهید."
    )


# ============================================================
# لغو سفارش
# ============================================================

@router.callback_query(
    F.data.startswith("cancel_order:")
)
async def cancel_order(
    callback: CallbackQuery,
    state: FSMContext,
):

    try:

        order_id = int(
            callback.data.split(":")[1]
        )

    except (ValueError, IndexError):

        await callback.answer(
            "❌ سفارش نامعتبر است.",
            show_alert=True,
        )

        return

    async with AsyncSessionLocal() as session:

        order = await get_order(
            session,
            order_id,
        )

        if not order:

            await callback.answer(
                "❌ سفارش پیدا نشد.",
                show_alert=True,
            )

            return

        if order.user.telegram_id != callback.from_user.id:

            await callback.answer(
                "❌ این سفارش متعلق به شما نیست.",
                show_alert=True,
            )

            return

        if order.status != OrderStatus.WAITING_RECEIPT.value:

            await callback.answer(
                "⚠️ این سفارش قابل لغو نیست.",
                show_alert=True,
            )

            return

        order.status = OrderStatus.REJECTED.value

        await session.commit()

    await state.clear()

    await callback.message.edit_text(
        "❌ <b>سفارش لغو شد.</b>\n\n"
        f"شماره سفارش: <code>#{order_id}</code>"
    )

    await callback.answer(
        "سفارش لغو شد."
    )