# -*- coding: utf-8 -*-
"""
هندلر خرید کوین (کارت به کارت)
===================================
مراحل:
1) کاربر روی «💳 خرید کوین» میزنه
2) تعداد کوین مورد نظرش رو وارد میکنه (حداقل = min_purchase_coins)
3) ربات شماره کارت رو نشون میده و ازش عکس فیش واریزی میخواد
4) رسید برای همه‌ی ادمین‌ها فوروارد میشه تا تایید/رد کنن
5) با تایید ادمین، کوین به حساب کاربر اضافه میشه
"""

import html

import telebot
from telebot import types

import database as db
import keyboards as kb
import utils


def register(bot: telebot.TeleBot):

    # -----------------------------------------------------------------
    # شروع خرید
    # -----------------------------------------------------------------
    @bot.message_handler(func=lambda m: utils.is_button(m.text, "buy"))
    def buy_coin_start(message):
        card = db.get_setting("card_number")
        if not card:
            bot.send_message(message.chat.id, utils.render_text("buy_no_card"))
            return
        unit = db.get_int_setting("coins_unit", 10)
        price = db.get_int_setting("price_per_unit", 4000)
        min_buy = db.get_int_setting("min_purchase_coins", 50)
        bot.send_message(
            message.chat.id,
            utils.render_text("buy_start", unit=unit, price=utils.toman(price), min_buy=min_buy),
            reply_markup=kb.buy_amounts_kb(),
        )

    # -----------------------------------------------------------------
    # انتخاب یکی از مبلغ‌های پیشنهادی
    # -----------------------------------------------------------------
    @bot.callback_query_handler(func=lambda c: c.data.startswith("buyamt_"))
    def buy_amount_preset(call):
        user_id = call.from_user.id
        choice = call.data.split("_", 1)[1]

        if choice == "custom":
            min_buy = db.get_int_setting("min_purchase_coins", 50)
            utils.set_state(user_id, "awaiting_coin_amount")
            bot.answer_callback_query(call.id)
            bot.send_message(
                call.message.chat.id,
                f"چند کوین میخوای بخری؟\nحداقل خرید: {min_buy} کوین\n\nفقط عدد بفرست:",
                reply_markup=kb.cancel_kb(),
            )
            return

        amount = int(choice)
        bot.answer_callback_query(call.id)
        _show_payment_details(bot, call.message.chat.id, user_id, amount)

    # -----------------------------------------------------------------
    # انصراف عمومی از هر مرحله‌ی ورودی متنی
    # -----------------------------------------------------------------
    @bot.message_handler(func=lambda m: m.text == "❌ انصراف")
    def cancel_flow(message):
        user_id = message.from_user.id
        utils.clear_state(user_id)
        bot.send_message(message.chat.id, "لغو شد.", reply_markup=kb.main_menu(user_id))

    # -----------------------------------------------------------------
    # دریافت تعداد کوین درخواستی
    # -----------------------------------------------------------------
    @bot.message_handler(
        func=lambda m: utils.get_state(m.from_user.id)
        and utils.get_state(m.from_user.id)["state"] == "awaiting_coin_amount"
    )
    def receive_coin_amount(message):
        user_id = message.from_user.id
        text = message.text.strip()
        if not text.isdigit():
            bot.send_message(message.chat.id, "لطفا فقط عدد بفرست 🔢")
            return

        amount = int(text)
        min_buy = db.get_int_setting("min_purchase_coins", 50)
        if amount < min_buy:
            bot.send_message(message.chat.id, utils.render_text("buy_min_error", min_buy=min_buy))
            return

        _show_payment_details(bot, message.chat.id, user_id, amount)

    # -----------------------------------------------------------------
    # دریافت عکس رسید
    # -----------------------------------------------------------------
    @bot.message_handler(
        content_types=["photo"],
        func=lambda m: utils.get_state(m.from_user.id)
        and utils.get_state(m.from_user.id)["state"] == "awaiting_receipt",
    )
    def receive_receipt(message):
        user_id = message.from_user.id
        state = utils.get_state(user_id)
        coins = state["data"]["coins"]
        toman_amount = state["data"]["toman"]
        file_id = message.photo[-1].file_id

        payment_id = db.create_payment(user_id, coins, toman_amount, file_id)
        utils.clear_state(user_id)

        bot.send_message(
            message.chat.id, utils.render_text("buy_receipt_sent"), reply_markup=kb.main_menu(user_id)
        )

        # ارسال برای همه‌ی ادمین‌ها جهت تایید
        first_name = html.escape(message.from_user.first_name or "-")
        username = f"@{message.from_user.username}" if message.from_user.username else "-"
        caption = (
            f"💳 درخواست خرید کوین #{payment_id}!\n\n"
            f"👤 کاربر : {first_name} | {html.escape(username)}\n"
            f"🆔️ آیدی عددی : <code>{user_id}</code>\n"
            f"تعداد کوین: {utils.fmt_num(coins)}\n"
            f"مبلغ: {utils.toman(toman_amount)}"
        )
        for admin_id in db.list_admins():
            try:
                bot.send_photo(
                    admin_id,
                    file_id,
                    caption=caption,
                    parse_mode="HTML",
                    reply_markup=kb.payment_review_kb(payment_id),
                )
            except Exception:
                pass

    # -----------------------------------------------------------------
    # تایید / رد پرداخت توسط ادمین
    # -----------------------------------------------------------------
    @bot.message_handler(
        content_types=["video", "document", "voice", "sticker", "audio", "animation", "video_note", "location", "contact"],
        func=lambda m: utils.get_state(m.from_user.id)
        and utils.get_state(m.from_user.id)["state"] == "awaiting_receipt",
    )
    def receive_receipt_wrong_type(message):
        bot.send_message(message.chat.id, "لطفاً فقط عکس رسید یا فیش واریزی رو بفرست 📷")

    @bot.callback_query_handler(func=lambda c: c.data.startswith("pay_ok_") or c.data.startswith("pay_no_"))
    def review_payment(call):
        admin_id = call.from_user.id
        if not db.is_admin(admin_id):
            bot.answer_callback_query(call.id, "فقط ادمین!", show_alert=True)
            return

        approve = call.data.startswith("pay_ok_")
        payment_id = int(call.data.rsplit("_", 1)[1])
        payment = db.get_payment(payment_id)

        if not payment:
            bot.answer_callback_query(call.id, "پرداخت پیدا نشد.", show_alert=True)
            return

        new_status = "approved" if approve else "rejected"
        won_the_race = db.try_set_payment_status(payment_id, new_status, admin_id)
        if not won_the_race:
            # یا از قبل بررسی شده، یا یه ادمین دیگه (یا همین دابل‌کلیک) لحظه‌ای زودتر ثبتش کرد
            bot.answer_callback_query(call.id, "قبلا بررسی شده.", show_alert=True)
            return

        if approve:
            db.add_coins(payment["user_id"], payment["coins"])
            bot.answer_callback_query(call.id, "تایید شد ✅")
            try:
                bot.send_message(
                    payment["user_id"],
                    utils.render_text("buy_approved", coins=utils.fmt_num(payment["coins"])),
                )
            except Exception:
                pass
            _post_purchase_to_log_channel(bot, payment)
        else:
            bot.answer_callback_query(call.id, "رد شد ❌")
            try:
                bot.send_message(payment["user_id"], utils.render_text("buy_rejected"))
            except Exception:
                pass

        try:
            bot.edit_message_caption(
                caption=call.message.caption + ("\n\n✅ تایید شد" if approve else "\n\n❌ رد شد"),
                chat_id=call.message.chat.id,
                message_id=call.message.message_id,
            )
        except Exception:
            pass


def _show_payment_details(bot, chat_id, user_id, amount):
    """شماره کارت و مبلغ رو نشون میده و منتظر عکس رسید میمونه."""
    unit = db.get_int_setting("coins_unit", 10)
    price_unit = db.get_int_setting("price_per_unit", 4000)
    toman_amount = int(amount / unit * price_unit) if unit else 0

    utils.set_state(user_id, "awaiting_receipt", {"coins": amount, "toman": toman_amount})

    card = db.get_setting("card_number")
    holder = db.get_setting("card_holder")
    text = utils.render_text_html(
        "buy_invoice",
        amount=utils.fmt_num(amount),
        toman_amount=utils.toman(toman_amount),
        card=f"<code>{html.escape(card)}</code>",
        holder=html.escape(holder),
    )
    bot.send_message(chat_id, text, parse_mode="HTML", reply_markup=kb.cancel_kb())


def _post_purchase_to_log_channel(bot, payment):
    """طبق درخواست: با هر خرید جدید، توی کانال لاگ پیام زده میشه."""
    log_channel = db.get_setting("log_channel_id")
    if not log_channel:
        return
    text = (
        "🛒 یک خرید جدید تایید شد!\n"
        f"💰 {utils.fmt_num(payment['coins'])} کوین خریداری شد.\n"
        "ربات همچنان در حال رشده 🚀"
    )
    try:
        bot.send_message(log_channel, text)
    except Exception:
        pass
