import asyncio
import logging
# pyrefly: ignore [missing-import]
from telethon import events
from handlers.middleware import permission_check, is_admin, get_target_user
from database.manager import DatabaseManager
from utils.templates import (
    registration_success, success_template, error_template, 
    admin_user_info_template, stats_template, key_template, signup_success, signout_success,
    balance_added_template
)
from config import BOT_NAME, COMMAND_PREFIX
import re

db = DatabaseManager()
logger = logging.getLogger("AdminHandler")

def register_admin_handlers(client):
    
    @client.on(events.NewMessage)
    async def admin_handler(event):
        try:
            if not await permission_check(event): return
            if not is_admin(event.sender_id): return

            text = event.raw_text.strip()
            cmd_parts = text.split()
            cmd = cmd_parts[0].lower()
            prefix = COMMAND_PREFIX.lower()

            # --- !help ---
            if cmd == f"{prefix}help":
                p = COMMAND_PREFIX
                help_text = f"""
👑 **ADMIN CONTROL PANEL**
━━━━━━━━━━━━━━━━━━
✨ **User Management**:
• `{p}signup` - Register user (Reply)
• `{p}addbalance [amt]` - Add balance (Reply)
• `{p}addusdt [amt]` - Add balance in USD (Reply)
• `{p}deduct [amt]` - Deduct balance (Reply)
• `{p}signout` - Remove user from system (Reply)
• `{p}setlimit [amt]` - Set due limit (Reply)
• `{p}cleardue [amt]` - Deduct from due (Reply)
• `{p}adddue [amt]` - Add to due (Reply)
• `{p}userinfo` - Full user report (Reply)
• `{p}ban` / `{p}unban` - User Access (Reply)

📦 **Inventory Control**:
• `{p}setrate [prod] [rate]`
• `{p}addstock [prod]` - Add stock (Reply)

📢 **System Tools**:
• `{p}setnumber [info]` - Update payment info
• `{p}setusdt [rate]` - Update USDT rate
• `{p}broadcast [msg]` - Message all users
• `{p}stats` - System statistics
━━━━━━━━━━━━━━━━━━
🤖 **{BOT_NAME}**
"""
                return await event.reply(help_text)

            # --- !signup (Reply to user) ---
            elif cmd == f"{prefix}signup":
                user_id, reply_msg = await get_target_user(event)
                if not user_id:
                    return await event.reply(error_template("Reply to a user message to sign them up."))
                
                sender = await reply_msg.get_sender()
                fullname = (sender.first_name or "") + (" " + sender.last_name if sender.last_name else "")
                
                await db.add_user(user_id, fullname, group_id=event.chat_id)
                user = await db.get_user(user_id)
                
                chat = await event.get_chat()
                group_name = getattr(chat, 'title', 'Private Chat')

                try:
                    # Send detailed info to PM
                    await client.send_message(user_id, registration_success(
                        user['fullname'], user['user_id'], user['role'], 
                        user['status'], user['currency'], group_name
                    ))
                except:
                    # Fallback to group only if PM fails
                    await event.reply(registration_success(
                        user['fullname'], user['user_id'], user['role'], 
                        user['status'], user['currency'], group_name
                    ))

            # --- !addbalance [amount] (Reply to user) ---
            elif cmd == f"{prefix}addbalance":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to add balance."))
                
                try:
                    amount = float(cmd_parts[1])
                    user = await db.get_user(user_id)
                    if not user: return await event.reply(error_template("User not found."))
                    
                    await db.update_balance(user_id, amount, is_add=True)
                    updated_user = await db.get_user(user_id)
                    
                    await db.add_log(event.sender_id, "balance_add", f"Added {amount} to {user_id}")
                    await event.reply(balance_added_template(
                        updated_user['fullname'], amount, 
                        user['balance'], updated_user['balance'], 
                        updated_user['currency']
                    ))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}addbalance 500`"))

            # --- !addusdt [amount] (Reply to user) ---
            elif cmd == f"{prefix}addusdt":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to add USDT balance."))
                
                try:
                    usdt_amount = float(cmd_parts[1])
                    db_usdt_rate = float(await db.get_setting("usdt_rate", 125))
                    bdt_amount = usdt_amount * db_usdt_rate
                    
                    await db.update_balance(user_id, bdt_amount, is_add=True)
                    await db.add_log(event.sender_id, "balance_add_usdt", f"Added ${usdt_amount} ({bdt_amount} BDT) to {user_id}")
                    await event.reply(success_template(f"Added `${usdt_amount}` (~{bdt_amount} BDT) to balance."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}addusdt 10`"))

            # --- !deduct [amount] (Reply to user) ---
            elif cmd == f"{prefix}deduct":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to deduct balance."))
                
                try:
                    amount = float(cmd_parts[1])
                    await db.update_balance(user_id, amount, is_add=False)
                    await event.reply(success_template(f"Deducted {amount} from balance."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}deduct 200`"))

            # --- !setlimit [amount] (Reply to user) ---
            elif cmd == f"{prefix}setlimit":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to set due limit."))
                
                try:
                    amount = float(cmd_parts[1])
                    await db.update_due_limit(user_id, amount)
                    await event.reply(success_template(f"Due limit for user set to {amount}."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}setlimit 5000`"))

            # --- !cleardue [amount] (Reply to user) ---
            elif cmd == f"{prefix}cleardue":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to clear due."))
                
                try:
                    if len(cmd_parts) >= 2:
                        amount = float(cmd_parts[1])
                        await db.update_due(user_id, amount, is_add=False)
                        await event.reply(success_template(f"Successfully cleared {amount} from due."))
                    else:
                        await db.clear_all_due(user_id)
                        await event.reply(success_template("Successfully cleared **ALL** due for this user."))
                except ValueError:
                    await event.reply(error_template("Invalid amount. Use a number."))

            # --- !adddue [amount] (Reply to user) ---
            elif cmd == f"{prefix}adddue":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to add due."))
                
                try:
                    amount = float(cmd_parts[1])
                    await db.update_due(user_id, amount, is_add=True)
                    await event.reply(success_template(f"Successfully added {amount} to due."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}adddue 200`"))

            # --- !userinfo (Reply to user) ---
            elif cmd == f"{prefix}userinfo":
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to see info."))
                
                user = await db.get_user(user_id)
                if not user: return await event.reply(error_template("User not found."))
                await event.reply(admin_user_info_template(user))

            # --- !stats ---
            elif cmd == f"{prefix}stats":
                stats = await db.get_stats()
                await event.reply(stats_template(stats))

            # --- !setrate [product] [rate] ---
            elif cmd == f"{prefix}setrate":
                try:
                    prod_name = cmd_parts[1]
                    rate = float(cmd_parts[2])
                    await db.update_product(prod_name, rate=rate)
                    await event.reply(success_template(f"Rate for {prod_name} set to {rate}."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}setrate 161 147`"))

            # --- !addstock [product] (Reply to voucher list) ---
            elif cmd == f"{prefix}addstock":
                user_id, reply_msg = await get_target_user(event)
                if not reply_msg:
                    return await event.reply(error_template("Reply to a message containing the vouchers/codes."))
                
                try:
                    prod_name = cmd_parts[1]
                    voucher_text = reply_msg.text
                    vouchers = [line for line in voucher_text.split('\n') if line.strip()]
                    count = len(vouchers)
                    
                    if count == 0:
                        return await event.reply(error_template("No vouchers found in that message."))

                    await db.add_vouchers(prod_name, vouchers)
                    await db.add_log(event.sender_id, "stock_load", f"Added {count} stock to {prod_name}")
                    await event.reply(success_template(f"Successfully added `{count}` items to `{prod_name}` stock!"))
                except IndexError:
                    await event.reply(error_template(f"Usage: `{prefix}addstock [PRODUCT_NAME]` (Reply to vouchers)"))

            # --- !setnumber [info] ---
            elif cmd == f"{prefix}setnumber":
                info = text.replace(cmd, "").strip()
                if not info: return await event.reply(error_template(f"Usage: `{prefix}setnumber Bkash: 017xx...`"))
                await db.set_setting("payment_info", info)
                await event.reply(success_template("Payment information updated successfully."))

            # --- !setusdt [rate] ---
            elif cmd == f"{prefix}setusdt":
                try:
                    rate = float(cmd_parts[1])
                    await db.set_setting("usdt_rate", str(rate))
                    await event.reply(success_template(f"USDT rate updated to {rate}."))
                except (IndexError, ValueError):
                    await event.reply(error_template(f"Usage: `{prefix}setusdt 125`"))

            # --- !ban / !unban (Reply to user) ---
            elif cmd in [f"{prefix}ban", f"{prefix}unban"]:
                user_id, _ = await get_target_user(event)
                if not user_id: return await event.reply(error_template("Reply to a user to ban/unban."))
                
                status = 'banned' if "ban" in cmd and "unban" not in cmd else 'active'
                await db.update_user_status(user_id, status)
                await event.reply(success_template(f"User status updated to {status.upper()}."))

            # --- !broadcast [message] ---
            elif cmd == f"{prefix}broadcast":
                msg = text.replace(cmd, "").strip()
                if not msg: return await event.reply(error_template("Usage: !broadcast [message]"))
                
                users = await db.get_all_user_ids()
                count = 0
                for u_id in users:
                    try:
                        await client.send_message(int(u_id), f"📢 **BROADCAST MESSAGE**\n━━━━━━━━━━━━━━━━━━\n{msg}")
                        count += 1
                        await asyncio.sleep(0.1) # Avoid flood
                    except: continue
                await event.reply(success_template(f"Broadcast sent to {count} users."))

            # --- !signout (Reply to user) ---
            elif cmd in [f"{prefix}signout", f"{prefix}singout"]:
                target_id, _ = await get_target_user(event)
                if not target_id:
                    return await event.reply(error_template("Reply to a user to sign them out."))
                
                user = await db.get_user(target_id)
                if not user:
                    return await event.reply(error_template("User is not registered."))
                
                await db.clear_user_data(target_id)
                await event.reply(signout_success(
                    user['fullname'], target_id, user['role'], user['status'], user['balance'], user['currency']
                ))

        except Exception as e:
            logger.error(f"Error in admin command: {e}")
            await event.reply(error_template("An error occurred while processing the admin command."))
