import uuid, datetime
from telethon import Button
from telethon.tl.custom import Message
from utils.notif import send_notif_order, send_notif_topup, send_notif_vps_success

from config import ADMIN_IDS
from utils.data_manager import (
    get_products, save_products, get_users, get_orders,
    get_settings, save_settings, get_product_by_id, get_category_by_id
)

ADMIN_CALLBACKS = (
    "admprod_", "admedit_", "admcat_", "admcatedit_",
    "admset_", "adm_back", "adm_users", "adm_orders", "adm_"
)

user_states = {}
user_data = {}


def get_user_data(uid):
    if uid not in user_data:
        user_data[uid] = {}
    return user_data[uid]


def is_admin(user_id: int) -> bool:
    return user_id in ADMIN_IDS


# ─── Keyboards ───

def admin_menu_keyboard():
    return [
        [Button.inline("📦 Kelola Produk", b"admprod_list"), Button.inline("📂 Kelola Kategori", b"admcat_list")],
        [Button.inline("👥 Data User", b"adm_users"), Button.inline("📋 Daftar Order", b"adm_orders")],
        [Button.inline("⚙️ Pengaturan", b"adm_settings")],
        [Button.inline("📢 Broadcast", b"adm_broadcast")],
        [Button.inline("🧪 Test Notif", b"adm_testnotif")]
    ]


def admin_product_keyboard():
    data = get_products()
    products = data.get("products", [])
    buttons = []
    for p in products:
        cat = get_category_by_id(p.get("category_id", ""))
        cat_type = cat.get("type", "biasa") if cat else "biasa"
        if cat_type == "vps":
            label = f"{p['name']} ({cat.get('stock', 0)} slot)"
        elif cat_type == "akun":
            label = f"{p['name']} ({len(p.get('stock', []))} akun)"
        else:
            stok = p.get("stock", 0) if isinstance(p.get("stock"), int) else len(p.get("stock", []))
            label = f"{p['name']} ({stok} stok)"
        buttons.append([Button.inline(label, f"admprod_{p['id']}".encode())])
    buttons.append([Button.inline("➕ Tambah Produk", b"admprod_add")])
    buttons.append([Button.inline("🔙 Kembali", b"adm_back")])
    return buttons


def admin_product_detail_keyboard(prod_id):
    prod = get_product_by_id(prod_id)
    cat = get_category_by_id(prod.get("category_id", "")) if prod else None
    cat_type = cat.get("type", "biasa") if cat else "biasa"
    is_vps = cat_type == "vps"
    is_akun = cat_type == "akun"

    buttons = [
        [
            Button.inline("✏️ Nama", f"admedit_name_{prod_id}".encode()),
            Button.inline("💰 Harga", f"admedit_price_{prod_id}".encode())
        ],
        [Button.inline("📝 Deskripsi", f"admedit_desc_{prod_id}".encode())]
    ]
    if is_akun:
        buttons.append([Button.inline("👤 Tambah Data Akun", f"admedit_stock_{prod_id}".encode())])
    elif not is_vps:
        buttons.append([Button.inline("📦 Set Jumlah Stok", f"admedit_stock_{prod_id}".encode())])
    buttons.append([
        Button.inline("🔄 Toggle Aktif", f"admedit_toggle_{prod_id}".encode()),
        Button.inline("🗑 Hapus", f"admedit_delete_{prod_id}".encode())
    ])
    buttons.append([Button.inline("🔙 Kembali", b"admprod_list")])
    return buttons


def admin_category_keyboard():
    data = get_products()
    categories = data.get("categories", [])
    buttons = []
    for c in categories:
        buttons.append([Button.inline(c["name"], f"admcat_{c['id']}".encode())])
    buttons.append([Button.inline("➕ Tambah Kategori", b"admcat_add")])
    buttons.append([Button.inline("🔙 Kembali", b"adm_back")])
    return buttons


def admin_category_detail_keyboard(cat_id):
    cat = get_category_by_id(cat_id)
    cat_type = cat.get("type", "biasa") if cat else "biasa"
    buttons = [
        [Button.inline("✏️ Edit Nama", f"admcatedit_name_{cat_id}".encode())]
    ]
    if cat_type == "vps":
        stok = cat.get("stock", 0)
        buttons.append([Button.inline(f"📦 Set Stok (sekarang: {stok})", f"admcatedit_stock_{cat_id}".encode())])
    buttons.append([Button.inline("🗑 Hapus Kategori", f"admcatedit_delete_{cat_id}".encode())])
    buttons.append([Button.inline("🔙 Kembali", b"admcat_list")])
    return buttons


def main_menu_keyboard():
    return [
        [Button.text("🛍 Produk"), Button.text("💰 Saldo")],
        [Button.text("💳 Topup"), Button.text("📖 Panduan")],
        [Button.text("📞 Kontak Admin")]
    ]


# ─── Handlers ───

async def admin_panel(bot, message):
    if not is_admin(message.sender_id):
        await message.reply("❌ Akses ditolak.")
        return
    await bot.send_message(
        message.chat_id,
        "🔧 **Panel Admin**\n\nSelamat datang, Admin!",
        buttons=admin_menu_keyboard()
    )


async def handle_admin_message(bot, message) -> bool:
    if not is_admin(message.sender_id):
        return False

    uid = message.sender_id
    text = message.text
    ud = get_user_data(uid)
    state = ud.get("admin_state")

    if state:
        await handle_admin_state(bot, message, state, text)
        return True

    if text == "📦 Kelola Produk":
        await bot.send_message(message.chat_id, "📦 **Kelola Produk**\n\nPilih produk untuk diedit:",
                               buttons=admin_product_keyboard())
        return True

    elif text == "📂 Kelola Kategori":
        await bot.send_message(message.chat_id, "📂 **Kelola Kategori**\n\nPilih kategori:",
                               buttons=admin_category_keyboard())
        return True

    elif text == "👥 Data User":
        users = get_users()
        total = len(users)
        total_balance = sum(u.get("balance", 0) for u in users.values())
        lines = [f"👥 **Data User** — Total: {total}\n"]
        for uid_str, u in list(users.items())[:20]:
            lines.append(f"• {u.get('name','?')} (@{u.get('username','-')}) — Rp{u.get('balance',0):,}")
        if total > 20:
            lines.append(f"\n... dan {total-20} lainnya")
        lines.append(f"\n💰 Total saldo semua user: Rp{total_balance:,}")
        await bot.send_message(message.chat_id, "\n".join(lines))
        return True

    elif text == "📋 Daftar Order":
        orders = get_orders()
        if not orders:
            await bot.send_message(message.chat_id, "Belum ada order.")
            return True
        lines = [f"📋 **Daftar Order** — Total: {len(orders)}\n"]
        for o in orders[-15:][::-1]:
            icon = "✅" if o.get("status") == "success" else "⏳" if o.get("status") == "pending" else "❌"
            lines.append(f"{icon} `{o.get('order_id')}` — {o.get('prod_name', o.get('type','?'))} — Rp{o.get('amount',0):,}")
        await bot.send_message(message.chat_id, "\n".join(lines))
        return True

    elif text == "⚙️ Pengaturan":
        settings = get_settings()
        buttons = [
            [Button.inline("✏️ Edit Pesan Sambutan", b"admset_welcome")],
            [Button.inline("📖 Edit Panduan", b"admset_panduan")],
            [Button.inline(
                f"🔧 Maintenance: {'ON' if settings.get('maintenance') else 'OFF'}",
                b"admset_maintenance"
            )]
        ]
        await bot.send_message(message.chat_id, "⚙️ **Pengaturan Bot**", buttons=buttons)
        return True

    elif text == "📢 Broadcast":
        get_user_data(uid)["admin_state"] = "broadcast"
        await bot.send_message(message.chat_id, "📢 Ketik pesan yang ingin di-broadcast ke semua user:")
        return True

    elif text == "🏠 Menu Utama":
        await bot.send_message(message.chat_id, "🏠 Kembali ke menu utama.", buttons=main_menu_keyboard())
        return True

    return False


async def handle_admin_state(bot, message, state: str, text: str):
    uid = message.sender_id
    ud = get_user_data(uid)
    data = get_products()

    if state == "broadcast":
        users = get_users()
        ud.pop("admin_state", None)
        success = 0
        failed = 0
        await bot.send_message(message.chat_id, "⏳ Mengirim broadcast...")
        for target_uid in users:
            try:
                await bot.send_message(int(target_uid), text)
                success += 1
            except Exception:
                failed += 1
        await bot.send_message(
            message.chat_id,
            f"📢 **Broadcast Selesai**\n\n✅ Terkirim: {success}\n❌ Gagal: {failed}",
            buttons=admin_menu_keyboard()
        )

    elif state == "add_category_name":
        ud["new_category_name"] = text
        ud["admin_state"] = "add_category_type"
        buttons = [
            [Button.inline("☁️ VPS", b"admcat_type_vps")],
            [Button.inline("👤 Akun", b"admcat_type_akun")],
            [Button.inline("📦 Biasa", b"admcat_type_biasa")]
        ]
        await bot.send_message(message.chat_id, "Pilih tipe kategori:", buttons=buttons)

    elif state == "add_product_name":
        ud["new_product"] = {"name": text}
        ud["admin_state"] = "add_product_price"
        await bot.send_message(message.chat_id, "💰 Masukkan harga produk (angka saja):")

    elif state == "add_product_price":
        try:
            price = int(text.replace(".", "").replace(",", "").strip())
            ud["new_product"]["price"] = price
            ud["admin_state"] = "add_product_desc"
            await bot.send_message(message.chat_id, "📝 Masukkan deskripsi produk:")
        except ValueError:
            await bot.send_message(message.chat_id, "❌ Harga harus angka. Contoh: 75000")

    elif state == "add_product_desc":
        ud["new_product"]["description"] = text
        cats = data.get("categories", [])
        if not cats:
            await bot.send_message(message.chat_id, "❌ Belum ada kategori. Tambah kategori dulu.")
            ud.pop("admin_state", None)
            return
        buttons = []
        for c in cats:
            buttons.append([Button.inline(c["name"], f"admprod_setcat_{c['id']}".encode())])
        await bot.send_message(message.chat_id, "📂 Pilih kategori produk:", buttons=buttons)
        ud["admin_state"] = "add_product_cat"

    elif state == "add_product_stock":
        prod_id = ud.get("editing_prod_id")
        stock_lines = [line.strip() for line in text.strip().split("\n") if line.strip()]
        prod = get_product_by_id(prod_id)
        cat = get_category_by_id(prod.get("category_id", "")) if prod else None
        cat_type = cat.get("type", "biasa") if cat else "biasa"
        label = "akun" if cat_type == "akun" else "stok"
        for p in data["products"]:
            if p["id"] == prod_id:
                if not isinstance(p.get("stock"), list):
                    p["stock"] = []
                p["stock"].extend(stock_lines)
                break
        save_products(data)
        ud.pop("admin_state", None)
        ud.pop("editing_prod_id", None)
        await bot.send_message(message.chat_id, f"✅ {len(stock_lines)} {label} berhasil ditambahkan!",
                               buttons=admin_menu_keyboard())

    elif state == "edit_product_stock_count":
        prod_id = ud.get("editing_prod_id")
        try:
            jumlah = int(text.strip())
            for p in data["products"]:
                if p["id"] == prod_id:
                    p["stock"] = jumlah
                    break
            save_products(data)
            ud.pop("admin_state", None)
            ud.pop("editing_prod_id", None)
            await bot.send_message(message.chat_id, f"✅ Stok diset ke **{jumlah}**",
                                   buttons=admin_menu_keyboard())
        except ValueError:
            await bot.send_message(message.chat_id, "❌ Masukkan angka saja. Contoh: 10")

    elif state == "edit_cat_stock":
        cat_id = ud.get("editing_cat_id")
        try:
            stok = int(text.strip())
            for c in data["categories"]:
                if c["id"] == cat_id:
                    c["stock"] = stok
                    break
            save_products(data)
            ud.pop("admin_state", None)
            await bot.send_message(message.chat_id, f"✅ Stok kategori diset ke **{stok}**",
                                   buttons=admin_menu_keyboard())
        except ValueError:
            await bot.send_message(message.chat_id, "❌ Masukkan angka. Contoh: 10")

    elif state == "edit_product_name":
        prod_id = ud.get("editing_prod_id")
        for p in data["products"]:
            if p["id"] == prod_id:
                p["name"] = text
                break
        save_products(data)
        ud.pop("admin_state", None)
        await bot.send_message(message.chat_id, f"✅ Nama produk diubah ke **{text}**",
                               buttons=admin_menu_keyboard())

    elif state == "edit_product_price":
        prod_id = ud.get("editing_prod_id")
        try:
            price = int(text.replace(".", "").replace(",", "").strip())
            for p in data["products"]:
                if p["id"] == prod_id:
                    p["price"] = price
                    break
            save_products(data)
            ud.pop("admin_state", None)
            await bot.send_message(message.chat_id, f"✅ Harga diubah ke Rp{price:,}",
                                   buttons=admin_menu_keyboard())
        except ValueError:
            await bot.send_message(message.chat_id, "❌ Harga harus angka.")

    elif state == "edit_product_desc":
        prod_id = ud.get("editing_prod_id")
        for p in data["products"]:
            if p["id"] == prod_id:
                p["description"] = text
                break
        save_products(data)
        ud.pop("admin_state", None)
        await bot.send_message(message.chat_id, "✅ Deskripsi berhasil diupdate!",
                               buttons=admin_menu_keyboard())

    elif state == "edit_cat_name":
        cat_id = ud.get("editing_cat_id")
        for c in data["categories"]:
            if c["id"] == cat_id:
                c["name"] = text
                break
        save_products(data)
        ud.pop("admin_state", None)
        await bot.send_message(message.chat_id, f"✅ Nama kategori diubah ke **{text}**",
                               buttons=admin_menu_keyboard())

    elif state == "edit_welcome":
        settings = get_settings()
        settings["welcome_message"] = text
        save_settings(settings)
        ud.pop("admin_state", None)
        await bot.send_message(message.chat_id, "✅ Pesan sambutan diperbarui!",
                               buttons=admin_menu_keyboard())

    elif state == "edit_panduan":
        settings = get_settings()
        settings["panduan"] = text
        save_settings(settings)
        ud.pop("admin_state", None)
        await bot.send_message(message.chat_id, "✅ Panduan diperbarui!",
                               buttons=admin_menu_keyboard())


async def handle_admin_callback(bot, event) -> bool:
    if not is_admin(event.sender_id):
        return False

    cb = event.data.decode()
    if not any(cb.startswith(prefix) for prefix in ADMIN_CALLBACKS):
        return False

    uid = event.sender_id
    ud = get_user_data(uid)
    await event.answer()

    if cb == "admprod_list":
        await event.edit("📦 **Kelola Produk**", buttons=admin_product_keyboard())

    elif cb == "admprod_add":
        ud["admin_state"] = "add_product_name"
        await event.edit("✏️ Masukkan nama produk baru:")

    elif cb == "adm_testnotif":
        now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
        await send_notif_order(bot, {
            'order_id': 'ORD-TEST123',
            'user_id': uid,
            'prod_name': 'TEST',
            'amount': 1,
            'method': 'TEST',
            'created_at': now,
        })
        await send_notif_topup(bot, {
            'order_id': 'TOP-TEST456',
            'user_id': uid,
            'amount': 1,
            'created_at': now,
        })
        await send_notif_vps_success(bot, uid, 'ORD-TEST123', 'TEST', 'TEST', 'TEST', 'TEST')
        await event.answer("Test notif terkirim!", alert=True)

    elif cb.startswith("admcat_type_"):
        cat_type = cb[12:]
        name = ud.get("new_category_name", "")
        new_cat = {"id": "cat_" + str(uuid.uuid4())[:6], "name": name, "type": cat_type}
        if cat_type == "vps":
            new_cat["stock"] = 0
        prods = get_products()
        prods["categories"].append(new_cat)
        save_products(prods)
        ud.pop("new_category_name", None)
        ud.pop("admin_state", None)
        await event.edit(f"✅ Kategori **{name}** dengan tipe **{cat_type}** berhasil ditambahkan!")

    elif cb.startswith("admcatedit_stock_"):
        cat_id = cb[17:]
        ud["admin_state"] = "edit_cat_stock"
        ud["editing_cat_id"] = cat_id
        await event.edit("📦 Masukkan jumlah stok VPS (angka saja):\nContoh: 10")

    elif cb.startswith("admprod_setcat_"):
        cat_id = cb[15:]
        np = ud.get("new_product", {})
        np["category_id"] = cat_id
        np["id"] = "prod_" + str(uuid.uuid4())[:6]
        np["stock"] = []
        np["active"] = True
        prods = get_products()
        prods["products"].append(np)
        save_products(prods)
        ud.pop("new_product", None)
        ud.pop("admin_state", None)
        await event.edit(f"✅ Produk **{np['name']}** berhasil ditambahkan!")

    elif cb.startswith("admprod_"):
        prod_id = cb[8:]
        prod = get_product_by_id(prod_id)
        if not prod:
            await event.edit("Produk tidak ditemukan.")
            return True
        cat = get_category_by_id(prod.get("category_id", ""))
        cat_type = cat.get("type", "biasa") if cat else "biasa"
        if cat_type == "vps":
            stock_text = f"{cat.get('stock', 0)} slot tersedia"
        elif cat_type == "akun":
            stock_text = f"{len(prod.get('stock', []))} akun tersedia"
        else:
            stok = prod.get("stock", 0)
            stock_text = str(stok if isinstance(stok, int) else len(stok))
        status = "✅ Aktif" if prod.get("active") else "❌ Nonaktif"
        text = (
            f"📦 **{prod['name']}**\n\n"
            f"💰 Harga: Rp{prod['price']:,}\n"
            f"📝 Deskripsi: {prod['description']}\n"
            f"📦 Stok: {stock_text}\n"
            f"🔄 Status: {status}"
        )
        await event.edit(text, buttons=admin_product_detail_keyboard(prod_id))

    elif cb.startswith("admedit_name_"):
        prod_id = cb[13:]
        ud["admin_state"] = "edit_product_name"
        ud["editing_prod_id"] = prod_id
        await event.edit("✏️ Masukkan nama baru:")

    elif cb.startswith("admedit_price_"):
        prod_id = cb[14:]
        ud["admin_state"] = "edit_product_price"
        ud["editing_prod_id"] = prod_id
        await event.edit("💰 Masukkan harga baru (angka saja):")

    elif cb.startswith("admedit_desc_"):
        prod_id = cb[13:]
        ud["admin_state"] = "edit_product_desc"
        ud["editing_prod_id"] = prod_id
        await event.edit("📝 Masukkan deskripsi baru:")

    elif cb.startswith("admedit_stock_"):
        prod_id = cb[14:]
        prod = get_product_by_id(prod_id)
        cat = get_category_by_id(prod.get("category_id", "")) if prod else None
        cat_type = cat.get("type", "biasa") if cat else "biasa"
        ud["editing_prod_id"] = prod_id
        if cat_type == "akun":
            ud["admin_state"] = "add_product_stock"
            await event.edit("👤 **Tambah Data Akun**\n\nKirim data akun, satu baris satu akun.\nContoh:\n`user: admin | pass: 123456`")
        else:
            ud["admin_state"] = "edit_product_stock_count"
            await event.edit("📦 **Set Jumlah Stok**\n\nMasukkan jumlah stok (angka saja):\nContoh: `10`")

    elif cb.startswith("admedit_toggle_"):
        prod_id = cb[15:]
        prods = get_products()
        status = ""
        for p in prods["products"]:
            if p["id"] == prod_id:
                p["active"] = not p.get("active", True)
                status = "aktif" if p["active"] else "nonaktif"
                break
        save_products(prods)
        await event.edit(f"✅ Produk sekarang **{status}**.")

    elif cb.startswith("admedit_delete_"):
        prod_id = cb[15:]
        prods = get_products()
        prods["products"] = [p for p in prods["products"] if p["id"] != prod_id]
        save_products(prods)
        await event.edit("🗑 Produk berhasil dihapus!", buttons=admin_product_keyboard())

    elif cb == "admcat_list":
        await event.edit("📂 **Kelola Kategori**", buttons=admin_category_keyboard())

    elif cb == "admcat_add":
        ud["admin_state"] = "add_category_name"
        await event.edit("✏️ Masukkan nama kategori baru:")

    elif cb.startswith("admcat_"):
        cat_id = cb[7:]
        cat = get_category_by_id(cat_id)
        if not cat:
            await event.edit("Kategori tidak ditemukan.")
            return True
        await event.edit(
            f"📂 **{cat['name']}**\n\nID: `{cat['id']}`\nTipe: `{cat.get('type', 'biasa')}`",
            buttons=admin_category_detail_keyboard(cat_id)
        )

    elif cb.startswith("admcatedit_name_"):
        cat_id = cb[16:]
        ud["admin_state"] = "edit_cat_name"
        ud["editing_cat_id"] = cat_id
        await event.edit("✏️ Masukkan nama kategori baru:")

    elif cb.startswith("admcatedit_delete_"):
        cat_id = cb[18:]
        prods = get_products()
        prods["categories"] = [c for c in prods["categories"] if c["id"] != cat_id]
        save_products(prods)
        await event.edit("🗑 Kategori berhasil dihapus!", buttons=admin_category_keyboard())

    elif cb == "admset_welcome":
        ud["admin_state"] = "edit_welcome"
        settings = get_settings()
        await event.edit(f"✏️ Pesan sambutan saat ini:\n\n{settings.get('welcome_message','')}\n\nKirim pesan sambutan baru:")

    elif cb == "admset_panduan":
        ud["admin_state"] = "edit_panduan"
        await event.edit("📖 Kirim teks panduan baru:")

    elif cb == "admset_maintenance":
        settings = get_settings()
        settings["maintenance"] = not settings.get("maintenance", False)
        save_settings(settings)
        status = "ON 🔧" if settings["maintenance"] else "OFF ✅"
        await event.answer(f"Maintenance sekarang: {status}", alert=True)

    elif cb == "adm_broadcast":
        ud["admin_state"] = "broadcast"
        await event.edit("📢 Ketik pesan yang ingin di-broadcast ke semua user:")

    elif cb == "adm_back":
        await event.edit("🔧 **Panel Admin**", buttons=admin_menu_keyboard())

    elif cb == "adm_users":
        users = get_users()
        total = len(users)
        total_balance = sum(u.get("balance", 0) for u in users.values())
        lines = [f"👥 **Data User** — Total: {total}\n"]
        for uid_str, u in list(users.items())[:20]:
            lines.append(f"• {u.get('name','?')} (@{u.get('username','-')}) — Rp{u.get('balance',0):,}")
        if total > 20:
            lines.append(f"\n... dan {total-20} lainnya")
        lines.append(f"\n💰 Total saldo semua user: Rp{total_balance:,}")
        await event.edit("\n".join(lines))

    elif cb == "adm_orders":
        orders = get_orders()
        if not orders:
            await event.edit("Belum ada order.")
            return True
        lines = [f"📋 **Daftar Order** — Total: {len(orders)}\n"]
        for o in orders[-15:][::-1]:
            icon = "✅" if o.get("status") == "success" else "⏳" if o.get("status") == "pending" else "❌"
            lines.append(f"{icon} `{o.get('order_id')}` — {o.get('prod_name', o.get('type','?'))} — Rp{o.get('amount',0):,}")
        await event.edit("\n".join(lines))

    elif cb == "adm_settings":
        settings = get_settings()
        buttons = [
            [Button.inline("✏️ Edit Pesan Sambutan", b"admset_welcome")],
            [Button.inline("📖 Edit Panduan", b"admset_panduan")],
            [Button.inline(
                f"🔧 Maintenance: {'ON' if settings.get('maintenance') else 'OFF'}",
                b"admset_maintenance"
            )]
        ]
        await event.edit("⚙️ **Pengaturan Bot**", buttons=buttons)

    return True