import logging

from aiogram import Router, Bot, F
from aiogram.filters import CommandStart, CommandObject, Command
from aiogram.types import Message, CallbackQuery, LabeledPrice

import config
import database as db
import keyboards as kb

router = Router(name="user")


# ------------------------------------------------------------- /start ------
@router.message(CommandStart())
async def cmd_start(message: Message, command: CommandObject, bot: Bot):
    user_id = message.from_user.id
    db.register_user(user_id, message.from_user.username)

    payload = command.args  # /start <target_id>

    if payload and payload.isdigit():
        target_id = int(payload)

        if target_id == user_id:
            await message.answer(
                "Bu sizning shaxsiy havolangiz. Uni do'stlaringizga ulashing, "
                "ular orqali sizga anonim xabar yozishsin 🙂"
            )
            return

        if not db.user_exists(target_id):
            await message.answer("Bunday foydalanuvchi topilmadi yoki hali botdan foydalanmagan.")
            return

        if db.is_blocked(target_id, user_id):
            await message.answer("Siz bu foydalanuvchiga xabar yubora olmaysiz.")
            return

        db.set_pending(user_id, target_id, is_reply=False)
        await message.answer(
            "✍️ Endi xabaringizni yozing — u tanlangan shaxsga *anonim* tarzda yetkaziladi.\n"
            "Bekor qilish uchun /cancel buyrug'ini yuboring.\n\n"
            "_Eslatma: agar xabar oluvchi Premium foydalanuvchi bo'lsa, u sizning "
            "kimligingizni bilib olish imkoniyatiga ega bo'ladi._"
        )
        return

    me = await bot.get_me()
    link = f"https://t.me/{me.username}?start={user_id}"
    await message.answer(
        "👋 Anonim xabar botiga xush kelibsiz!\n\n"
        "Quyidagi shaxsiy havolangizni do'stlaringiz bilan ulashing — "
        "ular sizga o'z ismini bildirmasdan xabar yozishlari mumkin:\n\n"
        f"`{link}`\n\n"
        "Kelgan xabarlarga \"Javob berish\" tugmasi orqali anonim javob "
        "berishingiz mumkin.\n\n"
        "⭐ /premium — obuna bo'lib qo'shimcha imkoniyatlarni oching."
    )


@router.message(Command("cancel"))
async def cmd_cancel(message: Message):
    target, _ = db.pop_pending(message.from_user.id)
    await message.answer("Bekor qilindi." if target else "Bekor qilinadigan hech narsa yo'q.")


# --------------------------------------------------------- xabar forward ---
@router.message(F.text | F.photo | F.video | F.voice | F.sticker | F.document | F.animation | F.video_note)
async def forward_anonymously(message: Message, bot: Bot):
    sender_id = message.from_user.id
    db.register_user(sender_id, message.from_user.username)

    target_id, is_reply = db.pop_pending(sender_id)
    if not target_id:
        await message.answer(
            "Xabar kimga yuborilishini bilmayapman 🙂\n"
            "Buning uchun kimningdir shaxsiy havolasi orqali kirishingiz yoki "
            "kelgan xabarga \"Javob berish\" tugmasini bosishingiz kerak."
        )
        return

    if db.is_blocked(target_id, sender_id):
        await message.answer("Siz bu foydalanuvchiga xabar yubora olmaysiz.")
        return

    try:
        header = await bot.send_message(
            target_id, "📩 Sizga yangi anonim javob keldi:" if is_reply else "📩 Sizga yangi anonim xabar keldi:"
        )
        sent = await message.copy_to(chat_id=target_id)

        row_id = db.log_message(
            sender_id=sender_id,
            target_id=target_id,
            header_msg_id=header.message_id,
            content_msg_id=sent.message_id,
            confirm_msg_id=None,
            is_reply=is_reply,
        )

        # Qabul qiluvchiga tugmalarni content xabariga biriktiramiz
        await bot.edit_message_reply_markup(
            chat_id=target_id,
            message_id=sent.message_id,
            reply_markup=kb.incoming_message_kb(sender_id, row_id),
        )

        confirm = await message.answer("✅ Xabaringiz anonim tarzda yuborildi.")
        db_row = db.get_message(row_id)  # noqa: F841 (future use)
        await bot.edit_message_reply_markup(
            chat_id=sender_id,
            message_id=confirm.message_id,
            reply_markup=kb.sent_confirmation_kb(row_id, target_id),
        )
    except Exception:
        logging.exception("Xabar yuborishda xato")
        await message.answer(
            "❌ Xabarni yetkazib bo'lmadi. Ehtimol, qabul qiluvchi botni bloklagan."
        )


@router.callback_query(F.data.startswith("reply:"))
async def cb_reply(callback: CallbackQuery):
    target_id = int(callback.data.split(":", 1)[1])
    db.set_pending(callback.from_user.id, target_id, is_reply=True)
    await callback.message.answer("✍️ Javobingizni yozing, u ham anonim tarzda yuboriladi.")
    await callback.answer()


@router.callback_query(F.data.startswith("block:"))
async def cb_block(callback: CallbackQuery):
    target_id = int(callback.data.split(":", 1)[1])
    db.block_user(callback.from_user.id, target_id)
    await callback.answer("Foydalanuvchi bloklandi.", show_alert=True)


@router.callback_query(F.data.startswith("whois:"))
async def cb_whois(callback: CallbackQuery):
    row_id = int(callback.data.split(":", 1)[1])
    requester_id = callback.from_user.id

    if not db.is_premium(requester_id):
        await callback.answer(
            "🔒 Bu funksiya faqat Premium foydalanuvchilar uchun.\n"
            "Ochish uchun /premium buyrug'idan foydalaning.",
            show_alert=True,
        )
        return

    row = db.get_message(row_id)
    if not row or row["target_id"] != requester_id:
        await callback.answer("Xabar topilmadi.", show_alert=True)
        return

    sender = db.get_user(row["sender_id"])
    uname = f"@{sender['username']}" if sender and sender["username"] else "(username yo'q)"
    await callback.answer(
        f"Yuboruvchi:\nID: {row['sender_id']}\nUsername: {uname}",
        show_alert=True,
    )


@router.callback_query(F.data.startswith("del:"))
async def cb_delete(callback: CallbackQuery, bot: Bot):
    row_id = int(callback.data.split(":", 1)[1])
    row = db.get_message(row_id)

    if not row or row["sender_id"] != callback.from_user.id:
        await callback.answer("Bu xabar sizga tegishli emas.", show_alert=True)
        return

    if not db.is_premium(callback.from_user.id):
        await callback.answer(
            "🔒 Xabarlarni o'chirish faqat Premium foydalanuvchilar uchun.\n"
            "/premium orqali obuna bo'ling.",
            show_alert=True,
        )
        return

    if row["deleted"]:
        await callback.answer("Bu xabar allaqachon o'chirilgan.", show_alert=True)
        return

    for msg_id in (row["header_msg_id"], row["content_msg_id"]):
        if msg_id:
            try:
                await bot.delete_message(row["target_id"], msg_id)
            except Exception:
                pass

    db.mark_message_deleted(row_id)
    await callback.message.edit_text("🗑 Xabar oluvchidan o'chirildi.")
    await callback.answer("O'chirildi.")


# ------------------------------------------------------------- /premium ----
@router.message(Command("premium"))
async def cmd_premium(message: Message):
    label = db.premium_label(message.from_user.id)
    await message.answer(
        "⭐ *Premium obuna*\n\n"
        f"Joriy holat: *{label}*\n\n"
        "Premium sizga quyidagilarni beradi:\n"
        "• Yuborgan xabar/javoblaringizni o'chirish\n"
        "• Sizga kelgan xabar muallifini bilish\n\n"
        "Rejani tanlang (to'lov Telegram Stars orqali amalga oshadi):",
        reply_markup=kb.premium_plans_kb(),
    )


@router.callback_query(F.data.startswith("buy:"))
async def cb_buy_plan(callback: CallbackQuery, bot: Bot):
    plan_key = callback.data.split(":", 1)[1]
    plan = config.PREMIUM_PLANS.get(plan_key)
    if not plan:
        await callback.answer("Reja topilmadi.", show_alert=True)
        return

    await bot.send_invoice(
        chat_id=callback.from_user.id,
        title=f"Premium — {plan['title']}",
        description="Anonim bot Premium obunasi",
        payload=f"premium:{plan_key}",
        currency="XTR",
        prices=[LabeledPrice(label=plan["title"], amount=plan["stars"])],
        provider_token="",
    )
    await callback.answer()


# --------------------------------------------------------------- sovg'a ----
@router.callback_query(F.data.startswith("gift_open:"))
async def cb_gift_open(callback: CallbackQuery, bot: Bot):
    target_id = int(callback.data.split(":", 1)[1])
    try:
        gifts_resp = await bot.get_available_gifts()
    except Exception:
        logging.exception("Sovg'alar ro'yxatini olishda xato")
        await callback.answer("Sovg'alar hozircha mavjud emas.", show_alert=True)
        return

    gifts = sorted(gifts_resp.gifts, key=lambda g: g.star_count)[:8]
    if not gifts:
        await callback.answer("Hozircha sovg'alar mavjud emas.", show_alert=True)
        return

    await callback.message.answer(
        "🎁 Yuboriladigan sovg'ani tanlang:",
        reply_markup=kb.gift_list_kb(gifts, target_id),
    )
    await callback.answer()


@router.callback_query(F.data == "gift_cancel")
async def cb_gift_cancel(callback: CallbackQuery):
    await callback.message.edit_text("Bekor qilindi.")
    await callback.answer()


@router.callback_query(F.data.startswith("gift_send:"))
async def cb_gift_send(callback: CallbackQuery, bot: Bot):
    _, gift_id, target_id = callback.data.split(":", 2)
    target_id = int(target_id)

    try:
        gifts_resp = await bot.get_available_gifts()
        gift = next((g for g in gifts_resp.gifts if g.id == gift_id), None)
    except Exception:
        gift = None

    if not gift:
        await callback.answer("Bu sovg'a endi mavjud emas.", show_alert=True)
        return

    await bot.send_invoice(
        chat_id=callback.from_user.id,
        title="Anonim sovg'a",
        description="Ushbu sovg'a tanlangan foydalanuvchiga anonim tarzda yuboriladi",
        payload=f"gift:{gift_id}:{target_id}",
        currency="XTR",
        prices=[LabeledPrice(label="Sovg'a", amount=gift.star_count)],
        provider_token="",
    )
    await callback.answer()
