import logging
from datetime import datetime
import html

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto
from config import OWNERS
from data.memory import VS_PENDING_APPROVALS
from data.pending_store import set_pending, get_pending, delete_pending
from services.link_service import add_link
from services.user_service import save_user
from services.channel_service import get_all_channels
from services.transaction_service import save_transaction

log = logging.getLogger("bot.payment")

ANNOUNCEMENT_ICON = '<tg-emoji emoji-id="5424818078833715060">📣</tg-emoji>'
WARNING_ICON = '<tg-emoji emoji-id="5445331903496332384">❗️</tg-emoji>'


async def send_approval_to_admin(context, user, order, photo_id):
    """
    order = {
        "paket_type": "single" | "take_several" | "take_all",
        "paket_label": str (display untuk caption),
        "selected_ids": [int, ...],
        "harga_bayar": int,
        "promo_used": str or None,
        "discount_pct": int,
    }
    """
    log.info(
        "[APPROVAL] User %s (%s) konfirmasi order: %s | Harga: %s | IDs: %s",
        user.first_name, user.id,
        order.get("paket_label"),
        order.get("harga_bayar"),
        order.get("selected_ids")
    )
    sent_messages = []
    pending_entry = {
        "messages": sent_messages,
        "order": order,
        "photo_id": photo_id,
        "user": {
            "id": user.id,
            "first_name": user.first_name,
            "username": user.username,
        },
        "status": "open",
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
    }

    set_pending(user.id, pending_entry)

    notif = (
        "📦 <b>Order paket baru!</b>\n\n"
        "Cek menu <b>Notifications</b> -> <b>Order Masuk</b> untuk melihat detail pembayaran."
    )
    keyboard = InlineKeyboardMarkup([[
        InlineKeyboardButton("📦 Buka Order", callback_data="owner_notifications")
    ]])

    for owner_id in OWNERS:
        try:
            msg = await context.bot.send_message(
                chat_id=owner_id,
                text=notif,
                parse_mode="HTML",
                reply_markup=keyboard
            )
            sent_messages.append({
                "chat_id": owner_id,
                "message_id": msg.message_id,
                "kind": "notification",
            })
        except Exception:
            log.exception("[APPROVAL] Gagal kirim notif order ke owner %s", owner_id)

    pending_entry["messages"] = sent_messages
    set_pending(user.id, pending_entry)


async def process_approval(context, user_id, order):
    log.info("[APPROVE] Memproses approval untuk user_id=%s | order=%s", user_id, order)
    save_user(user_id)

    # 💾 Simpan transaksi ke database
    transaction_id = save_transaction(
        user_id=user_id,
        package_type=order.get("paket_type"),
        package_label=order.get("paket_label"),
        harga_bayar=order.get("harga_bayar"),
        promo_used=order.get("promo_used"),
        status="approved",
        transaction_code=order.get("transaction_code")
    )
    log.info("[APPROVE] Transaksi disimpan dengan ID: %s | Code: %s", transaction_id, order.get("transaction_code"))

    from services.vip_service import get_package_by_id
    selected_ids = order.get("selected_ids", [])
    promo_used = order.get("promo_used")

    teks_balasan = (
        f"{ANNOUNCEMENT_ICON} <b>PANDUAN AKSES GRUP VIP</b> {ANNOUNCEMENT_ICON}\n"
        "Mohon baca dulu sebelum masuk grup\n\n"
        f"{WARNING_ICON} <i>JANGAN MASUK LEWAT LINK KALO SUDAH KLIK LINK VIP</i> {WARNING_ICON}\n"
        f"{WARNING_ICON} <i>SILAHKAN TERUSKAN PESAN LINK INI KE CATATAN PRIBADI</i> {WARNING_ICON}\n"
        f"{WARNING_ICON} <i>CARI NAMA VIP NYA, TERUS PIN GRUP VIPNYA</i> {WARNING_ICON}\n\n"
        "🔗 <b>LINK VIP ANDA :</b>\n\n"
    )

    for pkg_id in selected_ids:
        pkg = get_package_by_id(pkg_id)
        if not pkg:
            continue

        if pkg.get("link"):
            log.info("[APPROVE] Paket '%s' pakai link statis: %s", pkg["nama"], pkg["link"])
            teks_balasan += (
                f"NAMA VIP : {html.escape(pkg['nama'])}\n"
                f"LINK : {html.escape(pkg['link'])}\n\n"
            )

        elif pkg.get("group_id"):
            log.info("[APPROVE] Membuat invite link untuk '%s' (group_id=%s)...", pkg["nama"], pkg["group_id"])
            try:
                invite = await context.bot.create_chat_invite_link(
                    chat_id=pkg["group_id"],
                    member_limit=1
                )
                add_link(
                    invite.invite_link,
                    pkg["group_id"],
                    pkg["nama"],
                    user_id,
                    promo_used
                )
                log.info("[APPROVE] Link berhasil: %s", invite.invite_link)
                teks_balasan += (
                    f"NAMA VIP : {html.escape(pkg['nama'])}\n"
                    f"LINK : {html.escape(invite.invite_link)}\n\n"
                )
            except Exception as e:
                log.error("[APPROVE] GAGAL buat link '%s': %s", pkg["nama"], e)
                teks_balasan += (
                    f"NAMA VIP : {html.escape(pkg['nama'])}\n"
                    "LINK : ⚠️ Gagal membuat link\n\n"
                )

        else:
            log.warning("[APPROVE] Paket '%s' tidak punya group_id maupun link.", pkg["nama"])
            teks_balasan += (
                f"NAMA VIP : {html.escape(pkg['nama'])}\n"
                "LINK : Hubungi admin untuk link\n\n"
            )

    teks_balasan += (
        f"{WARNING_ICON} <b>HARAP SIMPAN LINK SENDIRI</b>\n"
        f"ADMIN NGGAK AKAN KASIH LINK LAGI JIKA KALIAN KELUAR TANPA ADA BUKTI PAYMENT {WARNING_ICON} "
    )

    await context.bot.send_message(chat_id=user_id, text=teks_balasan, parse_mode="HTML")


async def process_rejection(context, user_id, order, reason=None):
    log.info("[REJECT] Menolak order user_id=%s | paket=%s", user_id, order.get("paket_label") if isinstance(order, dict) else "-")
    promo_used = order.get("promo_used") if isinstance(order, dict) else None
    reason_text = reason or "Bukti transfer tidak jelas atau tidak valid"
    
    # 💾 Simpan transaksi ke database dengan status rejected
    if isinstance(order, dict):
        save_transaction(
            user_id=user_id,
            package_type=order.get("paket_type"),
            package_label=order.get("paket_label"),
            harga_bayar=order.get("harga_bayar"),
            promo_used=promo_used,
            status="rejected",
            transaction_code=order.get("transaction_code")
        )
        log.info("[REJECT] Transaksi ditolak disimpan ke database | Code: %s", order.get("transaction_code"))
    
    if promo_used:
        from services.promo_service import release_promo
        release_promo(promo_used)
        log.info("[REJECT] Promo '%s' dilepas.", promo_used)

    await context.bot.send_message(
        chat_id=user_id,
        text=(
            "❌ <b>Pembayaran kamu ditolak oleh admin.</b>\n\n"
            f"Alasan: <b>{html.escape(reason_text)}</b>\n\n"
            "Silakan hubungi admin jika merasa ada kesalahan."
        ),
        parse_mode="HTML"
    )


async def update_all_approval_messages(context, user_id, new_caption):
    data = get_pending(user_id)
    messages = data.get("messages", []) if isinstance(data, dict) else []
    status_lines = [line.strip() for line in new_caption.splitlines() if line.strip()]
    status_text = status_lines[-1] if status_lines else "Order sudah diproses."
    back_markup = InlineKeyboardMarkup([[
        InlineKeyboardButton("⬅️ Kembali", callback_data="owner_order_inbox")
    ]])

    for item in messages:
        try:
            if item.get("kind") == "notification":
                await context.bot.edit_message_text(
                    chat_id=item["chat_id"],
                    message_id=item["message_id"],
                    text=(
                        "📦 <b>Order Paket</b>\n\n"
                        f"{html.escape(status_text)}"
                    ),
                    parse_mode="HTML",
                    reply_markup=back_markup
                )
            elif item.get("kind") == "approval_text":
                await context.bot.edit_message_text(
                    chat_id=item["chat_id"],
                    message_id=item["message_id"],
                    text=new_caption,
                    reply_markup=back_markup
                )
            else:
                await context.bot.edit_message_caption(
                    chat_id=item["chat_id"],
                    message_id=item["message_id"],
                    caption=new_caption[:1024],
                    reply_markup=back_markup
                )
        except Exception:
            pass

    delete_pending(user_id)


async def send_vs_approval(context, user, admin_id, paket, photo_id, transaction_code=None):
    from config import ADMINS
    username = f"@{user.username}" if user.username else "-"

    caption_base = (
        "🎥 ORDER VS BARU\n\n"
        f"🔖 Kode: {transaction_code or '-'}\n"
        f"👤 {user.first_name}\n"
        f"📌 {username}\n"
        f"🆔 {user.id}\n"
        f"📦 {paket}"
    )

    owner_keyboard = [[
        InlineKeyboardButton("✅ Approve", callback_data=f"vs_approve_{user.id}"),
        InlineKeyboardButton("❌ Reject", callback_data=f"vs_reject_{user.id}")
    ]]

    sent_messages = []

    for owner_id in OWNERS:
        msg = await context.bot.send_photo(
            chat_id=owner_id,
            photo=photo_id,
            caption=caption_base,
            reply_markup=InlineKeyboardMarkup(owner_keyboard)
        )
        sent_messages.append({"chat_id": owner_id, "message_id": msg.message_id})

    all_admins = list(set([admin_id] + ADMINS))
    for aid in all_admins:
        if aid in OWNERS:
            continue
        msg = await context.bot.send_photo(
            chat_id=aid,
            photo=photo_id,
            caption=caption_base + "\n\n🔔 Menunggu approval owner"
        )
        sent_messages.append({"chat_id": aid, "message_id": msg.message_id})

    VS_PENDING_APPROVALS[user.id] = {
        "messages": sent_messages,
        "paket": paket,
        "admin_id": admin_id
    }


def _format_rupiah(value):
    try:
        return f"Rp {int(value):,}".replace(",", ".")
    except (TypeError, ValueError):
        return "-"


async def post_testimonial_to_channels(context, user_data, order, photo_id=None, created_at=None):
    channels = get_all_channels()
    if not channels:
        return

    paket_label = order.get('paket_label', 'ORDER BARU')
    created_at = created_at or datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    caption = (
        f"📦 <b>TESTIMONI {html.escape(paket_label)}</b>\n\n"
        f"👤 Nama: <b>{html.escape(user_data.get('first_name', 'User'))}</b>\n"
        f"🆔 ID: <code>{user_data.get('id', '-')}</code>\n"
        f"💰 Harga: {_format_rupiah(order.get('harga_bayar'))}\n"
        f"🕐 Waktu: {html.escape(created_at)}\n"
    )

    for ch in channels:
        target = None
        if ch["type"] == "public" and ch.get("username"):
            target = f"@{ch['username'].lstrip('@')}"
        elif ch["type"] == "private" and ch.get("chat_id"):
            target = ch["chat_id"]

        if not target:
            continue

        try:
            await context.bot.send_message(
                chat_id=target,
                text=caption,
                parse_mode="HTML"
            )
            log.info("[TESTIMONIAL] Terkirim ke channel '%s' (%s)", ch["name"], target)
        except Exception as e:
            log.error("[TESTIMONIAL] Gagal kirim ke channel '%s' (%s): %s", ch["name"], target, e)
