import asyncio
import json
import os
import logging
import re
import random
from pathlib import Path
from datetime import datetime, timedelta
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, MessageHandler, filters, ContextTypes
from telethon import TelegramClient, errors, events
from telethon.tl.functions.channels import JoinChannelRequest, LeaveChannelRequest
from telethon.tl.functions.messages import ImportChatInviteRequest
from telethon.tl.types import MessageMediaDocument, MessageMediaPhoto
from telethon.network.connection.tcpabridged import ConnectionTcpAbridged
import io

# تنظیمات اصلی ربات (برند TRX)
BOT_TOKEN = "8804874406:AAFB-ajra8mjEYqEspE36QOudPlwYZvFsBM"
API_ID = 37875578
API_HASH = "d727da88520049512942e933c8e959d3"
ADMIN_ID = 8831078772

CHANNEL_LINK = "https://t.me/ATTACKERTRX"
GROUP_LINK = "https://t.me/GPATAKER_TRX"
CHANNEL_ID = -1004430371338
GROUP_ID = -1004313682155
OWNER_USERNAME = "POLO_IR"
BRAND_NAME = "TRX"
POSTER_IMAGE = "1000162208.png"

DB_FILE = "trx_database.json"
MEDIA_DIR = "media_storage"
STICKER_DIR = os.path.join(MEDIA_DIR, "stickers")
GIF_DIR = os.path.join(MEDIA_DIR, "gifs")

os.makedirs(STICKER_DIR, exist_ok=True)
os.makedirs(GIF_DIR, exist_ok=True)

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

clients = {}
tmp_auth = {}
local_media_cache = {}

# محدودیت‌های رسانه
MAX_STICKERS_PER_USER = 100
MAX_GIFS_PER_USER = 50

# دیکشنری برای بنرهای بخش‌های مختلف
BANNERS = {
    "main": POSTER_IMAGE,
    "buy_sub": "buy_sub_banner.png",
    "referral": "referral_banner.png",
    "public_features": "public_banner.png",
    "reply_chat": "reply_banner.png",
    "targets": "targets_banner.png",
    "groups": "groups_banner.png",
    "admin_panel": "admin_banner.png"
}

# تنظیمات جوین اجباری
FORCED_JOIN_CONFIG = {
    "enabled": True,
    "channels": [
        {"id": CHANNEL_ID, "link": CHANNEL_LINK, "name": "کانال TRX"},
        {"id": GROUP_ID, "link": GROUP_LINK, "name": "گروه TRX"}
    ]
}

# زمان فعال بودن خودکار (1 ساعت = 3600 ثانیه)
AUTO_RUN_DURATION = 3600

# دیکشنری برای مدیریت اسپم
spam_tracking = {}
SPAM_LIMIT = 3
SPAM_BAN_DURATION = 4  # ساعت

# دیکشنری برای ذخیره تسک‌های ریپ عمومی
general_reply_tasks = {}

# ========== تابع رنگ‌بندی دکمه‌ها ==========
def colorize_buttons(buttons):
    """رنگ‌بندی دکمه‌ها با حفظ ساختار اصلی"""
    colors = ["danger", "primary", "", "success"]
    result = []
    for i, btn in enumerate(buttons):
        color = colors[i % 4] if len(buttons) >= 4 else ("danger" if i % 2 == 0 else "primary")
        try:
            data = btn.to_dict() if hasattr(btn, "to_dict") else {}
            api_kwargs = data.get("api_kwargs", {}) or {}
            api_kwargs.setdefault("style", color)
            result.append(InlineKeyboardButton(
                text=btn.text,
                url=btn.url,
                callback_data=btn.callback_data,
                web_app=btn.web_app,
                login_url=btn.login_url,
                switch_inline_query=btn.switch_inline_query,
                switch_inline_query_current_chat=btn.switch_inline_query_current_chat,
                callback_game=btn.callback_game,
                pay=btn.pay,
                api_kwargs=api_kwargs
            ))
        except Exception:
            result.append(btn)
    return result

def create_colored_keyboard(button_rows):
    """
    دریافت لیست ردیف‌های دکمه و رنگ‌بندی چهارتایی
    """
    all_buttons = []
    for row in button_rows:
        all_buttons.extend(row)
    
    colored_buttons = colorize_buttons(all_buttons)
    
    # بازسازی ردیف‌ها
    new_rows = []
    idx = 0
    for row in button_rows:
        new_row = []
        for _ in row:
            new_row.append(colored_buttons[idx])
            idx += 1
        new_rows.append(new_row)
    
    return InlineKeyboardMarkup(new_rows)

def to_english_digits(text: str) -> str:
    if not text:
        return ""
    fa_digits = "۰۱۲۳۴۵۶۷۸۹"
    ar_digits = "٠١٢٣٤٥٦٧٨٩"
    for i in range(10):
        text = text.replace(fa_digits[i], str(i)).replace(ar_digits[i], str(i))
    return text

def load_db():
    if os.path.exists(DB_FILE):
        try:
            with open(DB_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except:
            pass
    return {"users": {}, "spam_bans": {}, "bot_active": True, "forced_join_config": FORCED_JOIN_CONFIG}

def save_db(db):
    with open(DB_FILE, 'w', encoding='utf-8') as f:
        json.dump(db, f, indent=2, ensure_ascii=False)

def get_user_data(user_id):
    db = load_db()
    uid = str(user_id)
    if uid not in db["users"]:
        db["users"][uid] = {
            "subscription_expire": None,
            "max_accounts": 1,
            "accounts": [],
            "account_status": {},
            "referred_by": None,
            "referral_count": 0,
            "groups": [],
            "active_groups": [],
            "reply_groups": [],
            "targets": [],
            "general_targets": [],
            "general_reply_count": 1,
            "messages": ["سلام و درود بر شما، ربات اتکر و ریپ‌چت TRX فعال است."],
            "reply_config": {
                "active": False,
                "delay": 2,
                "reply_sequence": 0,
                "use_stickers": True,
                "use_gifs": True,
                "stickers": [],
                "sticker_files": [],
                "gifs": [],
                "gif_files": [],
                **{f"target_link_{i}": "" for i in range(1, 11)},
                **{f"target_msg_id_{i}": None for i in range(1, 11)},
                **{f"chat_id_{i}": None for i in range(1, 11)},
                **{f"active_target_{i}": (i == 1) for i in range(1, 11)}
            },
            "attack_delay": 5,
            "attack_active": False,
            "attack_start_time": None,
            "reply_start_time": None,
            "temp_action": None,
            "calc_days": 1,
            "calc_accounts": 1,
            "general_reply_active": False
        }
        save_db(db)
    
    ud = db["users"][uid]
    if "stickers" not in ud["reply_config"]: ud["reply_config"]["stickers"] = []
    if "sticker_files" not in ud["reply_config"]: ud["reply_config"]["sticker_files"] = []
    if "gifs" not in ud["reply_config"]: ud["reply_config"]["gifs"] = []
    if "gif_files" not in ud["reply_config"]: ud["reply_config"]["gif_files"] = []
    if "general_reply_count" not in ud: ud["general_reply_count"] = 1
    if "attack_start_time" not in ud: ud["attack_start_time"] = None
    if "reply_start_time" not in ud: ud["reply_start_time"] = None
    if "active_groups" not in ud: ud["active_groups"] = []
    if "reply_groups" not in ud: ud["reply_groups"] = []
    if "general_reply_active" not in ud: ud["general_reply_active"] = False
    return ud

def update_user_data(user_id, data):
    db = load_db()
    db["users"][str(user_id)] = data
    save_db(db)

def check_subscription(user_id):
    if user_id == ADMIN_ID:
        return True
    ud = get_user_data(user_id)
    exp_str = ud.get("subscription_expire")
    if not exp_str:
        return False
    try:
        exp_dt = datetime.fromisoformat(exp_str)
        if datetime.now() < exp_dt:
            return True
    except:
        pass
    return False

def get_remaining_time_str(user_id):
    if user_id == ADMIN_ID:
        return "∞ نامحدود (مدیر کل سیستم TRX)"
    ud = get_user_data(user_id)
    exp_str = ud.get("subscription_expire")
    if not exp_str:
        return "❌ اشتراک فعال ندارید"
    try:
        exp_dt = datetime.fromisoformat(exp_str)
        diff = exp_dt - datetime.now()
        if diff.total_seconds() <= 0:
            return "❌ اشتراک شما به اتمام رسیده است"
        hours = int(diff.total_seconds() // 3600)
        minutes = int((diff.total_seconds() % 3600) // 60)
        return f"✅ {hours} ساعت و {minutes} دقیقه باقی مانده"
    except:
        return "نامشخص"

def check_spam_ban(user_id):
    if user_id == ADMIN_ID:
        return None
    db = load_db()
    bans = db.get("spam_bans", {})
    uid = str(user_id)
    
    if uid in bans:
        ban_time = datetime.fromisoformat(bans[uid])
        if datetime.now() < ban_time:
            return ban_time
        else:
            del bans[uid]
            db["spam_bans"] = bans
            save_db(db)
            return None
    return None

def add_spam_violation(user_id):
    if user_id == ADMIN_ID:
        return None
    db = load_db()
    bans = db.get("spam_bans", {})
    uid = str(user_id)
    
    if uid in bans:
        ban_time = datetime.fromisoformat(bans[uid])
        if datetime.now() < ban_time:
            new_ban = ban_time + timedelta(hours=SPAM_BAN_DURATION)
            bans[uid] = new_ban.isoformat()
            db["spam_bans"] = bans
            save_db(db)
            return new_ban
    
    ban_time = datetime.now() + timedelta(hours=SPAM_BAN_DURATION)
    bans[uid] = ban_time.isoformat()
    db["spam_bans"] = bans
    save_db(db)
    return ban_time

def remove_spam_ban(user_id):
    db = load_db()
    bans = db.get("spam_bans", {})
    uid = str(user_id)
    if uid in bans:
        del bans[uid]
        db["spam_bans"] = bans
        save_db(db)
        return True
    return False

async def check_forced_membership(bot, user_id):
    if user_id == ADMIN_ID:
        return True
    
    db = load_db()
    config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
    
    if not config.get("enabled", True):
        return True
    
    channels = config.get("channels", [])
    if not channels:
        return True
    
    for channel in channels:
        try:
            channel_id = channel.get("id")
            if channel_id:
                m_ch = await bot.get_chat_member(chat_id=channel_id, user_id=user_id)
                if m_ch.status in ['left', 'kicked']:
                    return False
        except:
            return False
    
    return True

def get_forced_join_keyboard():
    db = load_db()
    config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
    channels = config.get("channels", [])
    
    kb = []
    for channel in channels:
        link = channel.get("link")
        name = channel.get("name", "کانال")
        if link:
            kb.append([InlineKeyboardButton(f"📢 عضویت در {name}", url=link)])
    
    kb.append([InlineKeyboardButton("✅ عضو شدم، بررسی کن", callback_data="check_membership")])
    return InlineKeyboardMarkup(kb)

def get_banner_for_section(section):
    banner_path = BANNERS.get(section, POSTER_IMAGE)
    if os.path.exists(banner_path):
        return banner_path
    return POSTER_IMAGE if os.path.exists(POSTER_IMAGE) else None

async def send_with_banner(update, context, text, reply_markup, section="main", parse_mode='HTML'):
    user_id = update.effective_user.id
    banner_path = get_banner_for_section(section)
    
    try:
        if hasattr(update, 'callback_query') and update.callback_query and update.callback_query.message:
            query = update.callback_query
            if query.message.photo or query.message.animation or query.message.document:
                await query.message.delete()
            
            if banner_path and os.path.exists(banner_path):
                with open(banner_path, 'rb') as photo:
                    await context.bot.send_photo(
                        chat_id=user_id, 
                        photo=photo, 
                        caption=text, 
                        reply_markup=reply_markup, 
                        parse_mode=parse_mode
                    )
            else:
                await context.bot.send_message(
                    chat_id=user_id, 
                    text=text, 
                    reply_markup=reply_markup, 
                    parse_mode=parse_mode
                )
        elif hasattr(update, 'message') and update.message:
            if banner_path and os.path.exists(banner_path):
                with open(banner_path, 'rb') as photo:
                    await context.bot.send_photo(
                        chat_id=user_id, 
                        photo=photo, 
                        caption=text, 
                        reply_markup=reply_markup, 
                        parse_mode=parse_mode
                    )
            else:
                await context.bot.send_message(
                    chat_id=user_id, 
                    text=text, 
                    reply_markup=reply_markup, 
                    parse_mode=parse_mode
                )
        else:
            if banner_path and os.path.exists(banner_path):
                with open(banner_path, 'rb') as photo:
                    await context.bot.send_photo(
                        chat_id=user_id, 
                        photo=photo, 
                        caption=text, 
                        reply_markup=reply_markup, 
                        parse_mode=parse_mode
                    )
            else:
                await context.bot.send_message(
                    chat_id=user_id, 
                    text=text, 
                    reply_markup=reply_markup, 
                    parse_mode=parse_mode
                )
    except Exception as e:
        logger.error(f"Error in send_with_banner: {e}")
        try:
            await context.bot.send_message(chat_id=user_id, text=text, reply_markup=reply_markup, parse_mode=parse_mode)
        except Exception as e2:
            logger.error(f"Fallback send message error: {e2}")

def main_menu(user_id):
    has_sub = check_subscription(user_id)
    
    # ایجاد دکمه‌ها بدون استایل
    button_rows = [
        [
            InlineKeyboardButton("📊 وضعیت سیستم و گزارش‌ها", callback_data="status"),
            InlineKeyboardButton("💳 خرید اشتراک TRX", callback_data="buy_sub")
        ],
        [
            InlineKeyboardButton("👥 سیستم رفرال‌گیری", callback_data="referral_menu", api_kwargs={"style": "success"}),
            InlineKeyboardButton("🛠 قابلیت‌های عمومی (۲۰ ابزار)", callback_data="public_features")
        ]
    ]
    
    if has_sub or user_id == ADMIN_ID:
        button_rows.extend([
            [
                InlineKeyboardButton("➕ افزودن اکانت جدید", callback_data="add_account"),
                InlineKeyboardButton("📋 مدیریت اکانت‌ها", callback_data="account_manager")
            ],
            [
                InlineKeyboardButton("📁 مدیریت گروه‌های هدف", callback_data="groups", api_kwargs={"style": "success"}),
                InlineKeyboardButton("👥 مدیریت لیست هدف‌ها", callback_data="targets")
            ],
            [
                InlineKeyboardButton("📤 آپلود لیست پیام‌ها (TXT)", callback_data="upload"),
                InlineKeyboardButton("💬 سیستم ریپ چت (۱۰ هدف)", callback_data="reply_chat")
            ],
            [
                InlineKeyboardButton("🚀 شروع عملیات اتکر", callback_data="start_auto", api_kwargs={"style": "success"}),
                InlineKeyboardButton("⏹ توقف عملیات اتکر", callback_data="stop_auto")
            ],
            [
                InlineKeyboardButton("⏱ تنظیم تاخیر اتکر", callback_data="delay"),
                InlineKeyboardButton("🌐 مدیریت ریپ عمومی", callback_data="general_reply_menu")
            ],
            [
                InlineKeyboardButton("🔗 عضویت و ترک گروهی اکانت‌ها", callback_data="bulk_management")
            ]
        ])
    else:
        button_rows.append([InlineKeyboardButton("⚠️ سایر بخش‌ها (نیازمند خرید اشتراک 🔒)", callback_data="sub_required_alert")])
    
    button_rows.append([InlineKeyboardButton("ℹ️ درباره سیستم و راهنمای جامع TRX", callback_data="about")])
    if user_id == ADMIN_ID:
        button_rows.append([InlineKeyboardButton("👑 پنل مدیریت ادمین کل", callback_data="admin_panel")])
    
    return create_colored_keyboard(button_rows)

async def send_main_menu(update: Update, context: ContextTypes.DEFAULT_TYPE, text="🤖 <b>پنل مدیریت هوشمند اتکر و ریپ‌چت TRX</b>\n\n🔹 از منوی شیک و حرفه‌ای زیر برای مدیریت اکانت‌ها و ربات استفاده کنید:"):
    user_id = update.effective_user.id
    
    ban_time = check_spam_ban(user_id)
    if ban_time:
        remaining = ban_time - datetime.now()
        hours = remaining.seconds // 3600
        minutes = (remaining.seconds % 3600) // 60
        await context.bot.send_message(
            chat_id=user_id,
            text=f"⛔ <b>شما به دلیل اسپم به مدت {SPAM_BAN_DURATION} ساعت محدود شده‌اید!</b>\n\nزمان باقی مانده: {hours} ساعت و {minutes} دقیقه\n\nدر صورت اشتباه بودن، با پشتیبانی تماس بگیرید.",
            parse_mode='HTML'
        )
        return
    
    if not await check_forced_membership(context.bot, user_id):
        join_kb = get_forced_join_keyboard()
        await context.bot.send_message(
            chat_id=user_id,
            text="⚠️ <b>جوین اجباری</b>\n\nبرای استفاده از امکانات ربات پیشرفته <b>TRX</b>، لطفاً در کانال‌های زیر عضو شوید:",
            reply_markup=join_kb, parse_mode='HTML'
        )
        return
    
    reply_markup = main_menu(user_id)
    await send_with_banner(update, context, text, reply_markup, "main")

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    
    if user_id != ADMIN_ID:
        current_time = datetime.now()
        if user_id not in spam_tracking:
            spam_tracking[user_id] = {"count": 0, "last_time": current_time, "warned": False}
        
        track = spam_tracking[user_id]
        if (current_time - track["last_time"]).seconds < 2:
            track["count"] += 1
            track["last_time"] = current_time
            
            if track["count"] >= 3:
                ban_time = add_spam_violation(user_id)
                spam_tracking.pop(user_id, None)
                await update.message.reply_text(
                    f"⛔ <b>شما به دلیل اسپم به مدت {SPAM_BAN_DURATION} ساعت محدود شدید!</b>\n\n"
                    f"زمان پایان محدودیت: {ban_time.strftime('%Y-%m-%d %H:%M')}",
                    parse_mode='HTML'
                )
                return
            
            if track["count"] >= 2 and not track.get("warned"):
                track["warned"] = True
                await update.message.reply_text(
                    "⚠️ <b>هشدار اسپم!</b>\n\n"
                    "لطفاً از ارسال پیام‌های مکرر و سریع خودداری کنید.\n"
                    "در صورت تکرار، به مدت 4 ساعت از ربات محدود خواهید شد.",
                    parse_mode='HTML'
                )
                return
        else:
            track["count"] = 1
            track["last_time"] = current_time
            track["warned"] = False
    
    args = context.args
    ud = get_user_data(user_id)
    
    if args and args[0].startswith("ref_") and not ud["referred_by"]:
        try:
            ref_id = int(args[0].replace("ref_", ""))
            if ref_id != user_id:
                ud["referred_by"] = ref_id
                ref_ud = get_user_data(ref_id)
                ref_ud["referral_count"] = ref_ud.get("referral_count", 0) + 1
                cur_exp = ref_ud.get("subscription_expire")
                if cur_exp and datetime.fromisoformat(cur_exp) > datetime.now():
                    new_exp = datetime.fromisoformat(cur_exp) + timedelta(hours=2)
                else:
                    new_exp = datetime.now() + timedelta(hours=2)
                ref_ud["subscription_expire"] = new_exp.isoformat()
                update_user_data(ref_id, ref_ud)
                update_user_data(user_id, ud)
                try:
                    await context.bot.send_message(chat_id=ref_id, text="🎁 یک کاربر جدید با لینک دعوت شما وارد ربات شد! ۲ ساعت به اشتراک شما اضافه گردید.")
                except:
                    pass
        except:
            pass

    await send_main_menu(update, context)

async def render_reply_chat_menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    ud = get_user_data(user_id)
    rc = ud["reply_config"]
    
    button_rows = []
    
    for i in range(1, 11):
        st = "🟢 روشن" if rc.get(f"active_target_{i}") else "🔴 خاموش"
        link_set = "🔗" if rc.get(f"target_link_{i}") else "⚪️"
        button_rows.append([
            InlineKeyboardButton(f"هدف {i} {link_set} ({st})", callback_data=f"toggle_reply_target_{i}"),
            InlineKeyboardButton(f"تنظیم لینک {i}", callback_data=f"set_reply_link_{i}")
        ])
    
    st_count = len(rc.get("stickers", []))
    gif_count = len(rc.get("gifs", []))
    
    button_rows.append([
        InlineKeyboardButton(f"➕ افزودن استیکر ({st_count}/{MAX_STICKERS_PER_USER})", callback_data="add_reply_sticker"),
        InlineKeyboardButton(f"➕ افزودن گیف ({gif_count}/{MAX_GIFS_PER_USER})", callback_data="add_reply_gif")
    ])
    button_rows.append([
        InlineKeyboardButton("🗑 پاک‌سازی استیکرها", callback_data="clear_stickers"),
        InlineKeyboardButton("🗑 پاک‌سازی گیف‌ها", callback_data="clear_gifs")
    ])
    button_rows.append([
        InlineKeyboardButton(f"🎴 ارسال استیکر: {'✅' if rc.get('use_stickers', True) else '❌'}", callback_data="toggle_use_stickers"),
        InlineKeyboardButton(f"🎬 ارسال گیف: {'✅' if rc.get('use_gifs', True) else '❌'}", callback_data="toggle_use_gifs")
    ])
    button_rows.append([InlineKeyboardButton(f"⏱ تاخیر ارسال: {rc.get('delay', 2)} ثانیه", callback_data="set_reply_delay")])
    button_rows.append([
        InlineKeyboardButton("🟢 شروع ریپ‌چت", callback_data="start_reply"),
        InlineKeyboardButton("🔴 توقف ریپ‌چت", callback_data="stop_reply")
    ])
    
    if rc.get("active") and ud.get("reply_start_time"):
        start_time = datetime.fromisoformat(ud["reply_start_time"])
        elapsed = (datetime.now() - start_time).seconds
        remaining = max(0, AUTO_RUN_DURATION - elapsed)
        hours = remaining // 3600
        mins = (remaining % 3600) // 60
        button_rows.append([InlineKeyboardButton(f"⏳ زمان باقی مانده: {hours:02d}:{mins:02d}", callback_data="noop")])
    
    button_rows.append([InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")])
    
    text = (
        f"💬 <b>سیستم ریپ‌چت پیشرفته TRX (تا ۱۰ لینک هدف)</b>\n\n"
        f"📌 <b>تعداد استیکرهای ذخیره شده:</b> {st_count} عدد (حداکثر {MAX_STICKERS_PER_USER})\n"
        f"🎬 <b>تعداد گیف‌های ذخیره شده:</b> {gif_count} عدد (حداکثر {MAX_GIFS_PER_USER})\n\n"
        f"💡 الگوریتم ارسال: به ازای هر ۵ پاسخ (۳ متن TXT + ۱ استیکر + ۱ گیف) ارسال می‌شود.\n"
        f"🎴 ارسال استیکر: {'فعال ✅' if rc.get('use_stickers', True) else 'غیرفعال ❌'}\n"
        f"🎬 ارسال گیف: {'فعال ✅' if rc.get('use_gifs', True) else 'غیرفعال ❌'}\n"
        f"⏱ تاخیر: {rc.get('delay', 2)} ثانیه\n"
        f"⏳ حداکثر زمان اجرا: ۱ ساعت"
    )
    await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "reply_chat")

def admin_panel_menu():
    button_rows = [
        [InlineKeyboardButton("🖼 تنظیم پوستر/بنر ربات", callback_data="admin_set_logo")],
        [InlineKeyboardButton("🖼 تنظیم بنر بخش‌ها", callback_data="admin_set_section_banner")],
        [InlineKeyboardButton("🔗 تنظیم جوین اجباری", callback_data="admin_forced_join")],
        [InlineKeyboardButton("➕ اعطای اشتراک به کاربر", callback_data="admin_give_sub")],
        [InlineKeyboardButton("❌ محروم کردن کاربر از اشتراک", callback_data="admin_remove_sub")],
        [InlineKeyboardButton("🔓 رفع محدودیت اسپم کاربر", callback_data="admin_unban_spam")],
        [InlineKeyboardButton("📋 لیست کامل کاربران", callback_data="admin_user_list")],
        [InlineKeyboardButton("📢 ارسال پیام همگانی", callback_data="admin_broadcast")],
        [InlineKeyboardButton("⏹ خاموش/روشن کردن کل ربات", callback_data="admin_toggle_bot")],
        [InlineKeyboardButton("📊 آمار کلی سیستم TRX", callback_data="admin_stats")],
        [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
    ]
    return create_colored_keyboard(button_rows)

def account_manager_menu(user_id):
    ud = get_user_data(user_id)
    button_rows = []
    
    for phone in ud.get("accounts", []):
        status = "✅ فعال" if ud["account_status"].get(phone, True) else "❌ غیرفعال"
        button_rows.append([InlineKeyboardButton(f"📱 {phone} - {status}", callback_data=f"toggle_account_{phone}")])
    
    button_rows.extend([
        [InlineKeyboardButton("📋 لیست کامل اکانت‌ها", callback_data="list_accounts")],
        [InlineKeyboardButton("➕ افزودن اکانت جدید", callback_data="add_account")],
        [InlineKeyboardButton("🗑 حذف اکانت", callback_data="remove_account_prompt")],
        [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
    ])
    return create_colored_keyboard(button_rows)

def groups_manager_menu(user_id):
    ud = get_user_data(user_id)
    button_rows = []
    
    for g in ud.get("groups", []):
        is_auto = "🟢" if g in ud.get("active_groups", []) else "⚪"
        is_reply = "🟢" if g in ud.get("reply_groups", []) else "⚪"
        button_rows.append([
            InlineKeyboardButton(f"{is_auto} اتکر", callback_data=f"toggle_auto_group_{g}"),
            InlineKeyboardButton(f"{is_reply} ریپ", callback_data=f"toggle_reply_group_{g}"),
            InlineKeyboardButton(f"📁 {g[:20]}...", callback_data="noop")
        ])
    
    button_rows.extend([
        [InlineKeyboardButton("➕ افزودن گروه جدید", callback_data="add_group_prompt")],
        [InlineKeyboardButton("🗑 پاکسازی کل گروه‌ها", callback_data="clear_groups")],
        [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
    ])
    return create_colored_keyboard(button_rows)

def targets_menu(user_id):
    ud = get_user_data(user_id)
    button_rows = [
        [InlineKeyboardButton("➕ افزودن هدف با یوزرنیم", callback_data="add_target_username")],
        [InlineKeyboardButton("➕ افزودن هدف با آیدی عددی", callback_data="add_target_id")],
        [InlineKeyboardButton("🗑 پاکسازی هدف‌ها", callback_data="clear_targets")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    return create_colored_keyboard(button_rows)

def general_reply_menu(user_id):
    ud = get_user_data(user_id)
    status = "🟢 فعال" if ud.get("general_reply_active", False) else "🔴 غیرفعال"
    button_rows = [
        [InlineKeyboardButton(f"🌐 وضعیت ریپ عمومی: {status}", callback_data="toggle_general_reply")],
        [InlineKeyboardButton("➕ افزودن هدف عمومی", callback_data="add_gen_target_prompt")],
        [InlineKeyboardButton("🗑 پاکسازی کامل", callback_data="clear_gen_targets")],
        [InlineKeyboardButton(f"📊 تعداد پاسخ به هر پیام: {ud.get('general_reply_count', 1)}", callback_data="set_gen_reply_count")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    return create_colored_keyboard(button_rows)

# ========== سیستم ریپ عمومی از کد منبع ==========
async def setup_general_reply_listeners(user_id):
    """راه‌اندازی لیسنر ریپ عمومی برای کاربر - کپی شده از Bataker_auth_fixed.py"""
    ud = get_user_data(user_id)
    
    # اگر قبلاً لیسنر فعال بود، آن را متوقف کن
    if user_id in general_reply_tasks:
        try:
            general_reply_tasks[user_id].cancel()
        except:
            pass
        del general_reply_tasks[user_id]
    
    if not ud.get("general_reply_active", False):
        return
    
    # ایجاد لیسنر جدید - دقیقاً مشابه کد منبع
    for phone in ud["accounts"]:
        if not ud["account_status"].get(phone, True):
            continue
        c = await get_user_client(phone)
        if not c:
            continue
        try:
            @c.on(events.NewMessage(incoming=True))
            async def general_reply_listener(event, phone=phone, user_id=user_id):
                try:
                    sender = await event.get_sender()
                    if not sender:
                        return
                    current_ud = get_user_data(user_id)
                    gen_targets = current_ud.get("general_targets", [])
                    if not gen_targets:
                        return

                    sender_id_str = str(sender.id)
                    sender_username = f"@{sender.username}" if sender.username else ""

                    matched = False
                    for gt in gen_targets:
                        gt = gt.strip()
                        if gt == sender_id_str or gt == sender_username or (gt.startswith('@') and gt.lower() == sender_username.lower()):
                            matched = True
                            break

                    if matched:
                        # دریافت تعداد پاسخ از دیتابیس
                        current_ud = get_user_data(user_id)
                        reply_cnt = current_ud.get("general_reply_count", 1)
                        msgs = current_ud.get("messages", [])
                        if not msgs:
                            return
                        
                        # ارسال پاسخ‌ها
                        for _ in range(reply_cnt):
                            if not current_ud.get("general_reply_active", False):
                                break
                            msg_text = random.choice(msgs)
                            try:
                                await event.reply(msg_text)
                                await asyncio.sleep(random.uniform(0.5, 1.5))
                            except Exception as e:
                                logger.error(f"خطا در ارسال ریپ عمومی: {e}")
                                break
                except Exception as e:
                    logger.error(f"خطا در هندلر ریپ عمومی: {e}")
        except Exception as e:
            logger.error(f"خطا در ثبت لیسنر ریپ عمومی برای {phone}: {e}")
    
    # ذخیره تسک
    task = asyncio.create_task(asyncio.sleep(0))  # تسک دامی
    general_reply_tasks[user_id] = task

# ========== ادامه کد اصلی ==========

async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()
    data = query.data
    user_id = update.effective_user.id
    
    ban_time = check_spam_ban(user_id)
    if ban_time and user_id != ADMIN_ID:
        remaining = ban_time - datetime.now()
        hours = remaining.seconds // 3600
        minutes = (remaining.seconds % 3600) // 60
        await query.answer(f"⛔ محدودیت اسپم: {hours}س {minutes}د باقی مانده", show_alert=True)
        return
    
    ud = get_user_data(user_id)

    if data == "check_membership":
        if await check_forced_membership(context.bot, user_id):
            await send_main_menu(update, context)
        else:
            await query.answer("❌ شما هنوز در کانال‌ها عضو نشده‌اید!", show_alert=True)
        return

    if data == "sub_required_alert":
        await query.answer("❌ برای استفاده از این بخش باید اشتراک ربات را خریداری کنید!", show_alert=True)
        return

    if data == "back_main":
        ud["temp_action"] = None
        update_user_data(user_id, ud)
        await send_main_menu(update, context)
        return

    if data == "noop":
        return

    if data == "status":
        active_accs = sum(1 for p in ud["accounts"] if ud["account_status"].get(p, True))
        rem_time = get_remaining_time_str(user_id)
        
        auto_time = "غیرفعال"
        if ud.get("attack_active") and ud.get("attack_start_time"):
            start_time = datetime.fromisoformat(ud["attack_start_time"])
            elapsed = (datetime.now() - start_time).seconds
            remaining = max(0, AUTO_RUN_DURATION - elapsed)
            hours = remaining // 3600
            mins = (remaining % 3600) // 60
            auto_time = f"{hours:02d}:{mins:02d}"
        
        reply_time = "غیرفعال"
        if ud["reply_config"].get("active") and ud.get("reply_start_time"):
            start_time = datetime.fromisoformat(ud["reply_start_time"])
            elapsed = (datetime.now() - start_time).seconds
            remaining = max(0, AUTO_RUN_DURATION - elapsed)
            hours = remaining // 3600
            mins = (remaining % 3600) // 60
            reply_time = f"{hours:02d}:{mins:02d}"
        
        gen_reply_status = "🟢 فعال" if ud.get("general_reply_active", False) else "🔴 غیرفعال"
        
        text = (
            f"📊 <b>وضعیت سیستم و گزارش‌های اختصاصی TRX</b>\n\n"
            f"👤 <b>وضعیت اشتراک شما:</b>\n{rem_time}\n\n"
            f"📱 <b>آمار اکانت‌ها:</b>\n"
            f"• کل اکانت‌های شما: {len(ud['accounts'])} / ظرفیت مجاز: {ud['max_accounts']}\n"
            f"• اکانت‌های فعال: {active_accs}\n"
            f"• وضعیت موتور اتکر: {'🟢 فعال' if ud['attack_active'] else '🔴 غیرفعال'}\n"
            f"• زمان باقی مانده اتکر: {auto_time}\n"
            f"• وضعیت ریپ‌چت: {'🟢 فعال' if ud['reply_config']['active'] else '🔴 غیرفعال'}\n"
            f"• زمان باقی مانده ریپ‌چت: {reply_time}\n"
            f"• وضعیت ریپ عمومی: {gen_reply_status}\n\n"
            f"📁 <b>گروه‌ها و هدف‌ها:</b>\n"
            f"• تعداد گروه‌های ثبت شده: {len(ud['groups'])}\n"
            f"• گروه‌های فعال اتکر: {len(ud.get('active_groups', []))}\n"
            f"• گروه‌های فعال ریپ: {len(ud.get('reply_groups', []))}\n"
            f"• هدف‌های منشن: {len(ud['targets'])}\n"
            f"• هدف‌های ریپ عمومی: {len(ud['general_targets'])}\n"
        )
        kb = InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]])
        await send_with_banner(update, context, text, kb, "main")

    elif data == "buy_sub":
        text = (
            f"💳 <b>بخش خرید اشتراک برند TRX</b>\n\n"
            f"در این بخش می‌توانید بسته اشتراکی خود را به صورت دلخواه سفارشی‌سازی کنید:\n"
            f"• <b>نرخ هر روز اشتراک:</b> ۱۰,۰۰۰ تومان\n"
            f"• <b>نرخ هر اکانت مجاز:</b> ۱۰,۰۰۰ تومان\n\n"
            f"تنظیمات فعلی شما:\n"
            f"• تعداد روز: {ud.get('calc_days', 1)} روز ({ud.get('calc_days', 1) * 10000:,} تومان)\n"
            f"• ظرفیت اکانت: {ud.get('calc_accounts', 1)} اکانت ({ud.get('calc_accounts', 1) * 10000:,} تومان)\n"
            f"• <b>مجموع قابل پرداخت:</b> {(ud.get('calc_days', 1) + ud.get('calc_accounts', 1)) * 10000:,} تومان\n\n"
            f"لطفاً گزینه مورد نظر را انتخاب کنید:"
        )
        button_rows = [
            [InlineKeyboardButton(f"📅 تعداد روز: {ud.get('calc_days', 1)}", callback_data="set_calc_days"),
             InlineKeyboardButton(f"📱 تعداد اکانت: {ud.get('calc_accounts', 1)}", callback_data="set_calc_accounts")],
            [InlineKeyboardButton("✅ تایید و ساخت فاکتور نهایی", callback_data="generate_invoice")],
            [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
        ]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "buy_sub")

    elif data == "set_calc_days":
        ud["temp_action"] = "get_calc_days"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="buy_sub")]]
        await send_with_banner(update, context, "📅 لطفاً تعداد روزهای اشتراک مورد نظر خود را از ۱ تا ۶۰ وارد کنید:", create_colored_keyboard(button_rows), "buy_sub")

    elif data == "set_calc_accounts":
        ud["temp_action"] = "get_calc_accounts"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="buy_sub")]]
        await send_with_banner(update, context, "📱 لطفاً تعداد اکانت‌های مجاز مورد نظر خود را از ۱ تا ۲۰۰ وارد کنید:", create_colored_keyboard(button_rows), "buy_sub")

    elif data == "generate_invoice":
        days = ud.get('calc_days', 1)
        accs = ud.get('calc_accounts', 1)
        total_price = (days + accs) * 10000
        invoice_text = (
            f"🧾 <b>فاکتور رسمی خرید اشتراک TRX</b>\n\n"
            f"• مدت زمان اشتراک: {days} روز ({days * 10000:,} تومان)\n"
            f"• ظرفیت افزودن اکانت: {accs} اکانت ({accs * 10000:,} تومان)\n"
            f"• 💰 <b>مبلغ قابل پرداخت: {total_price:,} تومان</b>\n\n"
            f"💳 <b>نحوه پرداخت:</b>\n"
            f"کارت به کارت را انجام داده و فیش واریزی را همراه با آیدی کاربری خود به پشتیبانی به آیدی <code>@{OWNER_USERNAME}</code> ارسال کنید."
        )
        button_rows = [[InlineKeyboardButton("🔙 بازگشت به خرید اشتراک", callback_data="buy_sub")]]
        await send_with_banner(update, context, invoice_text, create_colored_keyboard(button_rows), "buy_sub")

    elif data == "referral_menu":
        bot_user = (await context.bot.get_me()).username
        ref_link = f"https://t.me/{bot_user}?start=ref_{user_id}"
        text = (
            f"👥 <b>سیستم رفرال‌گیری و دعوت از دوستان TRX</b>\n\n"
            f"با دعوت از هر دوست توسط لینک اختصاصی خود، <b>۲ ساعت اشتراک رایگان ربات</b> هدیه بگیرید!\n\n"
            f"🔗 <b>لینک دعوت اختصاصی شما:</b>\n<code>{ref_link}</code>\n\n"
            f"• تعداد دوستان دعوت شده: {ud.get('referral_count', 0)} نفر"
        )
        button_rows = [[InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "referral")

    elif data == "public_features":
        text = "🛠 <b>قابلیت‌های عمومی و ابزارهای کاربردی TRX</b>\n\nلطفاً ابزار مورد نظر را انتخاب کنید:"
        button_rows = [
            [InlineKeyboardButton("❤️ ری‌اکشن همزمان روی پست", callback_data="pub_reaction")],
            [InlineKeyboardButton("👁 بازدید خودکار (Auto View)", callback_data="pub_autoview")],
            [InlineKeyboardButton("📝 پاک‌سازی و فرمت متن", callback_data="pub_clean_text")],
            [InlineKeyboardButton("🔄 مبدل فونت فارسی", callback_data="pub_font_converter")],
            [InlineKeyboardButton("📡 تست پینگ و سرعت", callback_data="pub_ping")],
            [InlineKeyboardButton("📱 تولیدکننده QR Code", callback_data="pub_qr")],
            [InlineKeyboardButton("🔐 رمزنگاری Base64", callback_data="pub_base64")],
            [InlineKeyboardButton("#️⃣ استخراج هشتگ", callback_data="pub_hashtag")],
            [InlineKeyboardButton("📝 تولیدکننده کپشن", callback_data="pub_caption")],
            [InlineKeyboardButton("✅ چک کردن یوزرنیم", callback_data="pub_check_username")],
            [InlineKeyboardButton("👥 ابزار مدیریت گروه", callback_data="pub_group_tools")],
            [InlineKeyboardButton("🔍 آنالیزور اکانت", callback_data="pub_account_analyzer")],
            [InlineKeyboardButton("✉️ ارسال پیام ناشناس", callback_data="pub_anonymous")],
            [InlineKeyboardButton("💰 مبدل نرخ ارز", callback_data="pub_currency")],
            [InlineKeyboardButton("📊 سازنده نظرسنجی", callback_data="pub_poll")],
            [InlineKeyboardButton("🧹 پاکسازی ممبر فیک", callback_data="pub_clean_members")],
            [InlineKeyboardButton("🔗 لینک مستقیم چت", callback_data="pub_direct_link")],
            [InlineKeyboardButton("🌐 تست وب‌هوک", callback_data="pub_webhook")],
            [InlineKeyboardButton("📄 اطلاعات فایل", callback_data="pub_file_info")],
            [InlineKeyboardButton("💾 پشتیبان‌گیری خودکار", callback_data="pub_backup")],
            [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
        ]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_reaction":
        ud["temp_action"] = "pub_reaction"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "❤️ <b>ری‌اکشن همزمان روی پست</b>\n\nلطفاً لینک پست مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_autoview":
        ud["temp_action"] = "pub_autoview"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "👁 <b>بازدید خودکار</b>\n\nلطفاً لینک پست یا استوری مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_clean_text":
        ud["temp_action"] = "pub_clean_text"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "📝 <b>پاک‌سازی و فرمت متن</b>\n\nمتن خود را برای پاک‌سازی ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_font_converter":
        ud["temp_action"] = "pub_font_converter"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "🔄 <b>مبدل فونت فارسی</b>\n\nمتن خود را برای تبدیل ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_ping":
        button_rows = [[InlineKeyboardButton("🔙 بازگشت", callback_data="public_features")]]
        await send_with_banner(update, context, "📡 <b>تست پینگ و سرعت</b>\n\n🟢 پینگ ربات: ✅ عالی\n🔄 سرعت پاسخ: ۳۲ms\n📊 وضعیت: پایدار", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_qr":
        ud["temp_action"] = "pub_qr"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "📱 <b>تولیدکننده QR Code</b>\n\nمتن یا لینک مورد نظر را برای تبدیل به QR Code ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_base64":
        ud["temp_action"] = "pub_base64"
        update_user_data(user_id, ud)
        button_rows = [
            [InlineKeyboardButton("🔐 رمزنگاری", callback_data="pub_base64_encode")],
            [InlineKeyboardButton("🔓 رمزگشایی", callback_data="pub_base64_decode")],
            [InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]
        ]
        await send_with_banner(update, context, "🔐 <b>رمزنگاری/رمزگشایی Base64</b>\n\nلطفاً گزینه مورد نظر را انتخاب کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data in ["pub_base64_encode", "pub_base64_decode"]:
        ud["temp_action"] = data
        update_user_data(user_id, ud)
        mode = "رمزنگاری" if "encode" in data else "رمزگشایی"
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, f"🔐 <b>{mode} Base64</b>\n\nلطفاً متن مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_hashtag":
        ud["temp_action"] = "pub_hashtag"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "#️⃣ <b>استخراج هشتگ</b>\n\nمتن خود را برای استخراج هشتگ‌ها ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_caption":
        ud["temp_action"] = "pub_caption"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "📝 <b>تولیدکننده کپشن</b>\n\nموضوع یا کلمه کلیدی مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_check_username":
        ud["temp_action"] = "pub_check_username"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "✅ <b>چک کردن یوزرنیم</b>\n\nیوزرنیم مورد نظر را وارد کنید (مثلاً @username):", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_group_tools":
        ud["temp_action"] = "pub_group_tools"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "👥 <b>ابزار مدیریت گروه</b>\n\nلینک گروه مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_account_analyzer":
        ud["temp_action"] = "pub_account_analyzer"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "🔍 <b>آنالیزور اکانت</b>\n\nیوزرنیم یا آیدی عددی اکانت مورد نظر را وارد کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_anonymous":
        ud["temp_action"] = "pub_anonymous"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "✉️ <b>ارسال پیام ناشناس</b>\n\nیوزرنیم مقصد و پیام خود را به صورت زیر وارد کنید:\n<code>@username پیام شما</code>", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_currency":
        ud["temp_action"] = "pub_currency"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "💰 <b>مبدل نرخ ارز</b>\n\nمقدار و ارز مورد نظر را وارد کنید (مثلاً ۱۰۰ USD):", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_poll":
        ud["temp_action"] = "pub_poll"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "📊 <b>سازنده نظرسنجی</b>\n\nسوال نظرسنجی و گزینه‌ها را وارد کنید (با خط جدید جدا کنید):", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_clean_members":
        ud["temp_action"] = "pub_clean_members"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "🧹 <b>پاکسازی ممبر فیک</b>\n\nلینک گروه مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_direct_link":
        ud["temp_action"] = "pub_direct_link"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "🔗 <b>لینک مستقیم چت</b>\n\nیوزرنیم کاربر را وارد کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_webhook":
        ud["temp_action"] = "pub_webhook"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "🌐 <b>تست وب‌هوک</b>\n\nلینک وب‌هوک خود را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_file_info":
        ud["temp_action"] = "pub_file_info"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="public_features")]]
        await send_with_banner(update, context, "📄 <b>اطلاعات فایل</b>\n\nلطفاً فایل مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "public_features")

    elif data == "pub_backup":
        button_rows = [[InlineKeyboardButton("🔙 بازگشت", callback_data="public_features")]]
        await send_with_banner(update, context, "💾 <b>پشتیبان‌گیری خودکار</b>\n\n✅ آخرین پشتیبان‌گیری: امروز ساعت ۱۴:۳۰\n📁 حجم: ۲.۴ مگابایت\n🔄 پشتیبان‌گیری روزانه فعال است.", create_colored_keyboard(button_rows), "public_features")

    elif data == "about":
        text = (
            "ℹ️ <b>درباره سیستم و راهنمای جامع TRX</b>\n\n"
            "سیستم مدیریت هوشمند اکانت‌ها، اتکر و ریپ‌چت TRX بر پایه سرورهای پرسرعت.\n\n"
            "🔹 <b>امکانات اصلی:</b>\n"
            "• پشتیبانی از ۱۰ لینک هدف همزمان در ریپ چت\n"
            "• حالت چرخشی ارسال پاسخ (متن، استیکر و گیف)\n"
            "• عضویت و خروج گروهی اکانت‌ها\n"
            "• مدیریت جامع لیست هدف‌ها و گروه‌ها\n\n"
            "👑 <b>سازنده:</b> تیم توسعه TRX\n"
            f"👤 <b>پشتیبانی رسمی:</b> @{OWNER_USERNAME}"
        )
        button_rows = [
            [InlineKeyboardButton("📢 کانال رسمی TRX", url=CHANNEL_LINK)],
            [InlineKeyboardButton("👤 پشتیبانی", url=f"https://t.me/{OWNER_USERNAME}")],
            [InlineKeyboardButton("🔙 بازگشت به منوی اصلی", callback_data="back_main")]
        ]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "main")

    elif data == "account_manager":
        await send_with_banner(update, context, "📋 <b>مدیریت اکانت‌های متصل شما</b>\n\nبرای تغییر وضعیت هر اکانت، روی آن کلیک کنید:", account_manager_menu(user_id), "main")

    elif data == "list_accounts":
        accs = ud["accounts"]
        acc_text = "\n".join([f"• <code>{p}</code> ({'فعال ✅' if ud['account_status'].get(p, True) else 'غیرفعال ❌'})" for p in accs]) if accs else "هیچ اکانتی ثبت نشده است."
        button_rows = [[InlineKeyboardButton("🔙 بازگشت", callback_data="account_manager")]]
        await send_with_banner(update, context, f"📋 <b>لیست اکانت‌های شما:</b>\n\n{acc_text}", create_colored_keyboard(button_rows), "main")

    elif data.startswith("toggle_account_"):
        phone = data.replace("toggle_account_", "")
        if phone in ud["accounts"]:
            current = ud["account_status"].get(phone, True)
            ud["account_status"][phone] = not current
            update_user_data(user_id, ud)
            await send_with_banner(update, context, f"✅ وضعیت اکانت {phone} تغییر یافت.", account_manager_menu(user_id), "main")
        return

    elif data == "add_account":
        if len(ud["accounts"]) >= ud["max_accounts"]:
            return await query.answer(f"❌ شما به سقف مجاز اکانت‌های خود ({ud['max_accounts']} اکانت) رسیده‌اید.", show_alert=True)
        ud["temp_action"] = "add_acc_phone"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="back_main")]]
        await send_with_banner(update, context, "📱 <b>افزودن اکانت جدید</b>\n\nلطفاً شماره تلفن اکانت خود را وارد کنید (مثلا <code>+989123456789</code>):", create_colored_keyboard(button_rows), "main")

    elif data == "remove_account_prompt":
        ud["temp_action"] = "remove_acc"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="account_manager")]]
        await send_with_banner(update, context, "🗑 لطفاً شماره تلفن اکانتی که می‌خواهید حذف کنید را وارد کنید:", create_colored_keyboard(button_rows), "main")

    elif data == "groups":
        await send_with_banner(update, context, "📁 <b>مدیریت گروه‌های هدف</b>\n\nبرای فعال/غیرفعال کردن اتکر یا ریپ روی هر گروه کلیک کنید:", groups_manager_menu(user_id), "groups")

    elif data.startswith("toggle_auto_group_"):
        g = data.replace("toggle_auto_group_", "")
        if g in ud.get("active_groups", []):
            ud["active_groups"].remove(g)
        else:
            if "active_groups" not in ud: ud["active_groups"] = []
            ud["active_groups"].append(g)
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "✅ وضعیت گروه در اتکر تغییر یافت.", groups_manager_menu(user_id), "groups")

    elif data.startswith("toggle_reply_group_"):
        g = data.replace("toggle_reply_group_", "")
        if g in ud.get("reply_groups", []):
            ud["reply_groups"].remove(g)
        else:
            if "reply_groups" not in ud: ud["reply_groups"] = []
            ud["reply_groups"].append(g)
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "✅ وضعیت گروه در ریپ‌چت تغییر یافت.", groups_manager_menu(user_id), "groups")

    elif data == "add_group_prompt":
        ud["temp_action"] = "add_group"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="groups")]]
        await send_with_banner(update, context, "📁 لینک یا آیدی عددی گروه مورد نظر را ارسال کنید:", create_colored_keyboard(button_rows), "groups")

    elif data == "clear_groups":
        ud["groups"] = []
        ud["active_groups"] = []
        ud["reply_groups"] = []
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "🗑 تمامی گروه‌ها پاک شدند.", main_menu(user_id), "groups")

    elif data == "targets":
        t_list = "\n".join([f"• {t}" for t in ud["targets"]]) if ud["targets"] else "هدفی ثبت نشده است."
        await send_with_banner(update, context, f"👥 <b>مدیریت لیست هدف‌های منشن:</b>\n\n{t_list}", targets_menu(user_id), "targets")

    elif data == "add_target_username":
        ud["temp_action"] = "add_target_username"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="targets")]]
        await send_with_banner(update, context, "🎯 یوزرنیم هدف را وارد کنید (مثلا <code>@username</code>):", create_colored_keyboard(button_rows), "targets")

    elif data == "add_target_id":
        ud["temp_action"] = "add_target_id"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="targets")]]
        await send_with_banner(update, context, "🎯 آیدی عددی هدف را وارد کنید:", create_colored_keyboard(button_rows), "targets")

    elif data == "clear_targets":
        ud["targets"] = []
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "🗑 هدف‌ها پاک شدند.", main_menu(user_id), "targets")

    elif data == "upload":
        ud["temp_action"] = "waiting_file"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="back_main")]]
        await send_with_banner(update, context, "📤 لطفاً فایل متنی (<code>.txt</code>) حاوی پیام‌های اتکر را ارسال کنید:", create_colored_keyboard(button_rows), "main")

    elif data == "start_auto":
        if not ud.get("targets") or not ud.get("groups") or not ud.get("accounts"):
            await query.answer("❌ ابتدا اکانت، گروه و هدف را تنظیم کنید!", show_alert=True)
            return
        if len(ud.get("active_groups", [])) == 0:
            await query.answer("❌ حداقل یک گروه را برای اتکر فعال کنید!", show_alert=True)
            return
        ud["attack_active"] = True
        ud["attack_start_time"] = datetime.now().isoformat()
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "🚀 عملیات اتکر با موفقیت شروع شد!\n⏳ حداکثر زمان اجرا: ۱ ساعت", main_menu(user_id), "main")
        asyncio.create_task(user_auto_loop(user_id))

    elif data == "stop_auto":
        ud["attack_active"] = False
        ud["attack_start_time"] = None
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "⏹ عملیات اتکر متوقف شد.", main_menu(user_id), "main")

    elif data == "delay":
        ud["temp_action"] = "set_delay"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="back_main")]]
        await send_with_banner(update, context, "⏱ مقدار تاخیر اتکر بر حسب ثانیه را وارد کنید:", create_colored_keyboard(button_rows), "main")

    elif data == "reply_chat":
        await render_reply_chat_menu(update, context)

    elif data == "toggle_use_stickers":
        rc = ud["reply_config"]
        rc["use_stickers"] = not rc.get("use_stickers", True)
        update_user_data(user_id, ud)
        await render_reply_chat_menu(update, context)

    elif data == "toggle_use_gifs":
        rc = ud["reply_config"]
        rc["use_gifs"] = not rc.get("use_gifs", True)
        update_user_data(user_id, ud)
        await render_reply_chat_menu(update, context)

    elif data == "add_reply_sticker":
        if len(ud["reply_config"].get("stickers", [])) >= MAX_STICKERS_PER_USER:
            await query.answer(f"❌ شما به حداکثر مجاز استیکر ({MAX_STICKERS_PER_USER}) رسیده‌اید!", show_alert=True)
            return
        ud["temp_action"] = "add_reply_sticker"
        update_user_data(user_id, ud)
        st_count = len(ud["reply_config"].get("stickers", []))
        button_rows = [[InlineKeyboardButton("✅ اتمام و ثبت", callback_data="reply_chat")]]
        await send_with_banner(
            update, context,
            f"📌 <b>حالت آپلود پشت سر هم استیکر فعال شد.</b>\n\n"
            f"تعداد فعلی: {st_count} / {MAX_STICKERS_PER_USER}\n"
            f"استیکرهای خود را ارسال کنید. پس از اتمام، دکمه «✅ اتمام و ثبت» را بزنید.",
            create_colored_keyboard(button_rows),
            "reply_chat"
        )

    elif data == "add_reply_gif":
        if len(ud["reply_config"].get("gifs", [])) >= MAX_GIFS_PER_USER:
            await query.answer(f"❌ شما به حداکثر مجاز گیف ({MAX_GIFS_PER_USER}) رسیده‌اید!", show_alert=True)
            return
        ud["temp_action"] = "add_reply_gif"
        update_user_data(user_id, ud)
        gif_count = len(ud["reply_config"].get("gifs", []))
        button_rows = [[InlineKeyboardButton("✅ اتمام و ثبت", callback_data="reply_chat")]]
        await send_with_banner(
            update, context,
            f"🎬 <b>حالت آپلود پشت سر هم گیف فعال شد.</b>\n\n"
            f"تعداد فعلی: {gif_count} / {MAX_GIFS_PER_USER}\n"
            f"گیف‌های خود را ارسال کنید. پس از اتمام، دکمه «✅ اتمام و ثبت» را بزنید.",
            create_colored_keyboard(button_rows),
            "reply_chat"
        )

    elif data == "clear_stickers":
        ud["reply_config"]["stickers"] = []
        ud["reply_config"]["sticker_files"] = []
        update_user_data(user_id, ud)
        await query.answer("🗑 تمامی استیکرها پاک شدند.", show_alert=True)
        await render_reply_chat_menu(update, context)

    elif data == "clear_gifs":
        ud["reply_config"]["gifs"] = []
        ud["reply_config"]["gif_files"] = []
        update_user_data(user_id, ud)
        await query.answer("🗑 تمامی گیف‌ها پاک شدند.", show_alert=True)
        await render_reply_chat_menu(update, context)

    elif data == "set_reply_delay":
        ud["temp_action"] = "set_reply_delay"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="reply_chat")]]
        await send_with_banner(update, context, "⏱ مقدار تاخیر ریپ‌چت (بر حسب ثانیه) را وارد کنید:", create_colored_keyboard(button_rows), "reply_chat")

    elif data.startswith("set_reply_link_"):
        idx = data.replace("set_reply_link_", "")
        ud["temp_action"] = f"set_reply_link_{idx}"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="reply_chat")]]
        await send_with_banner(update, context, f"🎯 لطفاً لینک پیام هدف شماره {idx} را ارسال کنید:", create_colored_keyboard(button_rows), "reply_chat")

    elif data.startswith("toggle_reply_target_"):
        idx = int(data.replace("toggle_reply_target_", ""))
        rc = ud["reply_config"]
        rc[f"active_target_{idx}"] = not rc.get(f"active_target_{idx}", False)
        update_user_data(user_id, ud)
        await render_reply_chat_menu(update, context)

    elif data == "start_reply":
        if not ud.get("accounts"):
            await query.answer("❌ ابتدا اکانت اضافه کنید!", show_alert=True)
            return
        has_target = False
        for i in range(1, 11):
            if ud["reply_config"].get(f"active_target_{i}") and ud["reply_config"].get(f"chat_id_{i}"):
                has_target = True
                break
        if not has_target:
            await query.answer("❌ حداقل یک هدف فعال با لینک معتبر تنظیم کنید!", show_alert=True)
            return
        if len(ud.get("reply_groups", [])) == 0:
            await query.answer("❌ حداقل یک گروه را برای ریپ چت فعال کنید!", show_alert=True)
            return
        ud["reply_config"]["active"] = True
        ud["reply_start_time"] = datetime.now().isoformat()
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "💬 سیستم ریپ‌چت با موفقیت فعال شد.\n⏳ حداکثر زمان اجرا: ۱ ساعت", main_menu(user_id), "reply_chat")
        asyncio.create_task(user_reply_loop(user_id))

    elif data == "stop_reply":
        ud["reply_config"]["active"] = False
        ud["reply_start_time"] = None
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "⏹ سیستم ریپ‌چت متوقف شد.", main_menu(user_id), "reply_chat")

    # ========== مدیریت ریپ عمومی ==========
    elif data == "general_reply_menu":
        gt_list = "\n".join([f"• {g}" for g in ud["general_targets"]]) if ud["general_targets"] else "هدفی ثبت نشده است."
        await send_with_banner(update, context, f"🌐 <b>مدیریت ریپ عمومی:</b>\n\n{gt_list}", general_reply_menu(user_id), "main")

    elif data == "toggle_general_reply":
        current = ud.get("general_reply_active", False)
        ud["general_reply_active"] = not current
        update_user_data(user_id, ud)
        
        if ud["general_reply_active"]:
            await setup_general_reply_listeners(user_id)
            await query.answer("✅ ریپ عمومی فعال شد!", show_alert=True)
        else:
            if user_id in general_reply_tasks:
                try:
                    general_reply_tasks[user_id].cancel()
                except:
                    pass
                del general_reply_tasks[user_id]
            await query.answer("❌ ریپ عمومی غیرفعال شد!", show_alert=True)
        
        await send_with_banner(update, context, f"🌐 وضعیت ریپ عمومی: {'فعال ✅' if ud['general_reply_active'] else 'غیرفعال ❌'}", general_reply_menu(user_id), "main")

    elif data == "set_gen_reply_count":
        ud["temp_action"] = "set_gen_reply_count"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="general_reply_menu")]]
        await send_with_banner(update, context, "📊 لطفاً تعداد پاسخ به هر پیام در ریپ عمومی را وارد کنید (۱ تا ۵):", create_colored_keyboard(button_rows), "main")

    elif data == "add_gen_target_prompt":
        ud["temp_action"] = "add_gen_target"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="general_reply_menu")]]
        await send_with_banner(update, context, "🌐 یوزرنیم یا آیدی عددی کاربر مورد نظر را بفرستید:\n\nمثال: <code>@username</code> یا <code>123456789</code>", create_colored_keyboard(button_rows), "main")

    elif data == "clear_gen_targets":
        ud["general_targets"] = []
        update_user_data(user_id, ud)
        await send_with_banner(update, context, "🗑 پاک شد.", main_menu(user_id), "main")

    elif data == "bulk_management":
        button_rows = [
            [InlineKeyboardButton("🔗 عضویت گروهی اکانت‌ها", callback_data="bulk_join"),
             InlineKeyboardButton("🚪 ترک گروهی اکانت‌ها", callback_data="bulk_leave")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        await send_with_banner(update, context, "🔗 <b>مدیریت دسته‌جمعی اکانت‌ها در گروه‌ها و کانال‌ها</b>", create_colored_keyboard(button_rows), "main")

    elif data == "bulk_join":
        ud["temp_action"] = "bulk_join"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="bulk_management")]]
        await send_with_banner(update, context, "🔗 لینک گروه یا چنل مورد نظر را برای عضویت همزمان تمام اکانت‌ها ارسال کنید:", create_colored_keyboard(button_rows), "main")

    elif data == "bulk_leave":
        ud["temp_action"] = "bulk_leave"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="bulk_management")]]
        await send_with_banner(update, context, "🚪 لینک گروه یا چنل مورد نظر را برای ترک همزمان تمام اکانت‌ها ارسال کنید:", create_colored_keyboard(button_rows), "main")

    elif data == "admin_panel":
        if user_id != ADMIN_ID:
            return await query.answer("❌ دسترسی غیرمجاز!", show_alert=True)
        db = load_db()
        total_users = len(db["users"])
        kb = admin_panel_menu()
        await send_with_banner(update, context, f"👑 <b>پنل مدیریت ادمین کل TRX</b>\n\n• کل کاربران ربات: {total_users} نفر", kb, "admin_panel")

    elif data == "admin_set_logo":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_waiting_logo"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "🖼 لطفاً عکس جدید (لوگو/بنر اصلی) را برای پنل ربات ارسال کنید:", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_set_section_banner":
        if user_id != ADMIN_ID: return
        text = "🖼 <b>تنظیم بنر بخش‌های مختلف</b>\n\nبخشی که می‌خواهید بنر آن را تغییر دهید انتخاب کنید:"
        button_rows = [
            [InlineKeyboardButton("📊 منوی اصلی", callback_data="admin_set_banner_main")],
            [InlineKeyboardButton("💳 خرید اشتراک", callback_data="admin_set_banner_buy_sub")],
            [InlineKeyboardButton("👥 رفرال", callback_data="admin_set_banner_referral")],
            [InlineKeyboardButton("🛠 ابزارهای عمومی", callback_data="admin_set_banner_public")],
            [InlineKeyboardButton("💬 ریپ چت", callback_data="admin_set_banner_reply")],
            [InlineKeyboardButton("👥 هدف‌ها", callback_data="admin_set_banner_targets")],
            [InlineKeyboardButton("📁 گروه‌ها", callback_data="admin_set_banner_groups")],
            [InlineKeyboardButton("👑 پنل ادمین", callback_data="admin_set_banner_admin")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="admin_panel")]
        ]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "admin_panel")

    elif data.startswith("admin_set_banner_"):
        if user_id != ADMIN_ID: return
        section = data.replace("admin_set_banner_", "")
        ud["temp_action"] = f"admin_set_banner_{section}"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, f"🖼 لطفاً عکس جدید برای بخش {section} را ارسال کنید:", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_forced_join":
        if user_id != ADMIN_ID: return
        db = load_db()
        config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
        status = "✅ فعال" if config.get("enabled", True) else "❌ غیرفعال"
        channels_text = "\n".join([f"• {c.get('name', 'کانال')}: {c.get('link', '')}" for c in config.get("channels", [])])
        text = f"🔗 <b>تنظیمات جوین اجباری</b>\n\nوضعیت: {status}\n\nکانال‌ها:\n{channels_text}\n\nلطفاً گزینه مورد نظر را انتخاب کنید:"
        button_rows = [
            [InlineKeyboardButton(f"🔄 تغییر وضعیت ({status})", callback_data="admin_toggle_forced_join")],
            [InlineKeyboardButton("➕ افزودن کانال/گروه", callback_data="admin_add_forced_channel")],
            [InlineKeyboardButton("🗑 حذف کانال/گروه", callback_data="admin_remove_forced_channel")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="admin_panel")]
        ]
        await send_with_banner(update, context, text, create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_toggle_forced_join":
        if user_id != ADMIN_ID: return
        db = load_db()
        config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
        config["enabled"] = not config.get("enabled", True)
        db["forced_join_config"] = config
        save_db(db)
        await query.answer(f"جوین اجباری {'فعال' if config['enabled'] else 'غیرفعال'} شد!", show_alert=True)
        await callback_handler(update, context)

    elif data == "admin_add_forced_channel":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_add_forced_channel"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "🔗 لطفاً به ترتیب وارد کنید:\n1️⃣ آیدی عددی کانال/گروه\n2️⃣ لینک کانال/گروه\n3️⃣ نام کانال/گروه\n\nمثال:\n<code>-100123456789\nhttps://t.me/channel\nنام کانال</code>", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_remove_forced_channel":
        if user_id != ADMIN_ID: return
        db = load_db()
        config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
        channels = config.get("channels", [])
        button_rows = []
        for i, c in enumerate(channels):
            button_rows.append([InlineKeyboardButton(f"🗑 {c.get('name', 'کانال')}", callback_data=f"admin_remove_channel_{i}")])
        button_rows.append([InlineKeyboardButton("🔙 بازگشت", callback_data="admin_panel")])
        await send_with_banner(update, context, "🗑 کانال/گروه مورد نظر را برای حذف انتخاب کنید:", create_colored_keyboard(button_rows), "admin_panel")

    elif data.startswith("admin_remove_channel_"):
        if user_id != ADMIN_ID: return
        idx = int(data.replace("admin_remove_channel_", ""))
        db = load_db()
        config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
        channels = config.get("channels", [])
        if 0 <= idx < len(channels):
            removed = channels.pop(idx)
            config["channels"] = channels
            db["forced_join_config"] = config
            save_db(db)
            await query.answer(f"✅ {removed.get('name', 'کانال')} حذف شد!", show_alert=True)
        await callback_handler(update, context)

    elif data == "admin_give_sub":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_give_sub_input"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "➕ <b>اعطای اشتراک به کاربر</b>\n\nلطفاً به ترتیب وارد کنید:\n1️⃣ آیدی عددی کاربر\n2️⃣ تعداد روز اشتراک\n3️⃣ حداکثر تعداد اکانت مجاز\n\nمثال:\n<code>123456789 30 10</code>", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_remove_sub":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_remove_sub_input"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "❌ <b>محروم کردن کاربر از اشتراک</b>\n\nلطفاً آیدی عددی کاربر را وارد کنید تا اشتراک او لغو شود:", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_unban_spam":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_unban_spam_input"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "🔓 <b>رفع محدودیت اسپم کاربر</b>\n\nلطفاً آیدی عددی کاربر را وارد کنید:", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_user_list":
        if user_id != ADMIN_ID: return
        db = load_db()
        users_list = []
        for uid, udata in db["users"].items():
            exp = udata.get("subscription_expire", "بدون اشتراک")
            if exp and exp != "بدون اشتراک":
                try:
                    exp_dt = datetime.fromisoformat(exp)
                    if exp_dt > datetime.now():
                        exp = f"فعال تا {exp_dt.strftime('%Y-%m-%d')}"
                    else:
                        exp = "منقضی شده"
                except:
                    exp = "نامعتبر"
            users_list.append(f"• {uid} - اشتراک: {exp}")
        
        if not users_list:
            users_list = ["هیچ کاربری ثبت نشده است."]
        
        chunks = [users_list[i:i+30] for i in range(0, len(users_list), 30)]
        for chunk in chunks:
            button_rows = [[InlineKeyboardButton("🔙 بازگشت", callback_data="admin_panel")]]
            await send_with_banner(update, context, f"📋 <b>لیست کاربران:</b>\n\n" + "\n".join(chunk), create_colored_keyboard(button_rows), "admin_panel")
        return

    elif data == "admin_broadcast":
        if user_id != ADMIN_ID: return
        ud["temp_action"] = "admin_broadcast_input"
        update_user_data(user_id, ud)
        button_rows = [[InlineKeyboardButton("🔙 انصراف", callback_data="admin_panel")]]
        await send_with_banner(update, context, "📢 <b>ارسال پیام همگانی</b>\n\nلطفاً پیام خود را برای ارسال به تمام کاربران وارد کنید:", create_colored_keyboard(button_rows), "admin_panel")

    elif data == "admin_toggle_bot":
        if user_id != ADMIN_ID: return
        db = load_db()
        current_state = db.get("bot_active", True)
        new_state = not current_state
        db["bot_active"] = new_state
        save_db(db)
        await send_with_banner(update, context, f"⏹ ربات {'خاموش' if not new_state else 'روشن'} شد.", admin_panel_menu(), "admin_panel")

    elif data == "admin_stats":
        if user_id != ADMIN_ID: return
        db = load_db()
        active_cnt = sum(1 for uid in db["users"] if check_subscription(int(uid)))
        total_users = len(db["users"])
        button_rows = [[InlineKeyboardButton("🔙 بازگشت", callback_data="admin_panel")]]
        await send_with_banner(update, context, f"📊 <b>آمار کل سیستم TRX</b>\n\n• کل ثبت‌نامی‌ها: {total_users}\n• دارای اشتراک فعال: {active_cnt}\n• فاقد اشتراک: {total_users - active_cnt}", create_colored_keyboard(button_rows), "admin_panel")

async def download_media_file(context, file_id, user_id, media_type="sticker"):
    try:
        file = await context.bot.get_file(file_id)
        ext = ".webp" if media_type == "sticker" else ".mp4"
        dir_path = STICKER_DIR if media_type == "sticker" else GIF_DIR
        file_path = os.path.join(dir_path, f"{user_id}_{media_type}_{random.randint(10000, 99999)}{ext}")
        await file.download_to_drive(file_path)
        return file_path
    except Exception as e:
        logger.error(f"خطا در دانلود رسانه: {e}")
        return None

async def text_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    
    ban_time = check_spam_ban(user_id)
    if ban_time and user_id != ADMIN_ID:
        remaining = ban_time - datetime.now()
        hours = remaining.seconds // 3600
        minutes = (remaining.seconds % 3600) // 60
        await update.message.reply_text(
            f"⛔ <b>شما به دلیل اسپم به مدت {SPAM_BAN_DURATION} ساعت محدود شده‌اید!</b>\n\n"
            f"زمان باقی مانده: {hours} ساعت و {minutes} دقیقه",
            parse_mode='HTML'
        )
        return
    
    ud = get_user_data(user_id)
    text = to_english_digits(update.message.text.strip())
    action = ud.get("temp_action")

    if not await check_forced_membership(context.bot, user_id):
        return await update.message.reply_text("⚠️ لطفاً ابتدا در کانال‌های ربات عضو شوید تا بتوانید پیام ارسال کنید.")

    db = load_db()
    if not db.get("bot_active", True) and user_id != ADMIN_ID:
        return await update.message.reply_text("⏹ ربات در حال حاضر توسط مدیریت خاموش شده است.")

    if not action:
        return

    if action == "get_calc_days":
        try:
            val = int(text)
            if 1 <= val <= 60:
                ud["calc_days"] = val
                ud["temp_action"] = None
                update_user_data(user_id, ud)
                await update.message.reply_text(f"✅ تعداد روزهای اشتراک به {val} روز تنظیم شد.")
            else:
                await update.message.reply_text("❌ لطفاً عددی بین ۱ تا ۶۰ وارد کنید.")
        except:
            await update.message.reply_text("❌ لطفاً یک عدد معتبر وارد کنید.")

    elif action == "get_calc_accounts":
        try:
            val = int(text)
            if 1 <= val <= 200:
                ud["calc_accounts"] = val
                ud["temp_action"] = None
                update_user_data(user_id, ud)
                await update.message.reply_text(f"✅ ظرفیت اکانت به {val} عدد تنظیم شد.")
            else:
                await update.message.reply_text("❌ لطفاً عددی بین ۱ تا ۲۰۰ وارد کنید.")
        except:
            await update.message.reply_text("❌ لطفاً یک عدد معتبر وارد کنید.")

    elif action == "add_acc_phone":
        clean_phone = re.sub(r"[^\d+]", "", text)
        if not clean_phone.startswith("+"):
            clean_phone = "+" + clean_phone

        ud["temp_phone"] = clean_phone
        success, msg = await login_account(user_id, clean_phone)
        if success:
            ud["temp_action"] = "add_acc_code"
            update_user_data(user_id, ud)
            await update.message.reply_text(msg, parse_mode='HTML')
        else:
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            await update.message.reply_text(msg, parse_mode='HTML')
            await send_main_menu(update, context)

    elif action == "add_acc_code":
        phone = ud.get("temp_phone")
        success, msg = await verify_account(user_id, phone, text)
        await update.message.reply_text(msg, parse_mode='HTML')
        if success:
            ud["temp_action"] = None
            if phone not in ud["accounts"]:
                ud["accounts"].append(phone)
                ud["account_status"][phone] = True
            update_user_data(user_id, ud)
            await send_main_menu(update, context)
        elif "نشست جدید ساخته شود" in msg:
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            await send_main_menu(update, context)

    elif action == "remove_acc":
        if text in ud["accounts"]:
            ud["accounts"].remove(text)
            if text in ud["account_status"]: del ud["account_status"][text]
            update_user_data(user_id, ud)
            await update.message.reply_text("✅ اکانت با موفقیت حذف شد.")
        else:
            await update.message.reply_text("❌ این شماره در لیست اکانت‌های شما یافت نشد.")
        ud["temp_action"] = None
        await send_main_menu(update, context)

    elif action == "add_group":
        if text not in ud["groups"]:
            ud["groups"].append(text)
            ud["active_groups"].append(text)
            update_user_data(user_id, ud)
            await join_all_user_accounts(user_id, text)
        await update.message.reply_text(f"✅ گروه با موفقیت اضافه شد: {text}")
        ud["temp_action"] = None

    elif action == "add_target_username":
        if not text.startswith("@"):
            text = "@" + text
        if text not in ud["targets"]:
            ud["targets"].append(text)
            update_user_data(user_id, ud)
        await update.message.reply_text("✅ هدف منشن با یوزرنیم اضافه شد.")
        ud["temp_action"] = None

    elif action == "add_target_id":
        clean_id = re.sub(r"[^\d-]", "", text)
        if clean_id not in ud["targets"]:
            ud["targets"].append(clean_id)
            update_user_data(user_id, ud)
        await update.message.reply_text("✅ هدف منشن با آیدی عددی اضافه شد.")
        ud["temp_action"] = None

    elif action == "add_gen_target":
        if text not in ud["general_targets"]:
            ud["general_targets"].append(text)
            update_user_data(user_id, ud)
            
            # اگر ریپ عمومی فعال است، لیسنر را مجدد راه‌اندازی کن
            if ud.get("general_reply_active", False):
                await setup_general_reply_listeners(user_id)
            
        await update.message.reply_text("✅ هدف عمومی اضافه شد.")
        ud["temp_action"] = None

    elif action == "set_gen_reply_count":
        try:
            val = int(text)
            if 1 <= val <= 5:
                ud["general_reply_count"] = val
                ud["temp_action"] = None
                update_user_data(user_id, ud)
                
                # اگر ریپ عمومی فعال است، لیسنر را مجدد راه‌اندازی کن
                if ud.get("general_reply_active", False):
                    await setup_general_reply_listeners(user_id)
                
                await update.message.reply_text(f"✅ تعداد پاسخ به هر پیام به {val} تنظیم شد.")
            else:
                await update.message.reply_text("❌ لطفاً عددی بین ۱ تا ۵ وارد کنید.")
        except:
            await update.message.reply_text("❌ لطفاً یک عدد معتبر وارد کنید.")

    elif action == "set_delay":
        try:
            ud["attack_delay"] = int(text)
            update_user_data(user_id, ud)
            await update.message.reply_text("✅ تاخیر ثبت شد.")
        except:
            await update.message.reply_text("❌ عدد معتبر وارد کنید.")
        ud["temp_action"] = None

    elif action == "set_reply_delay":
        try:
            ud["reply_config"]["delay"] = int(text)
            update_user_data(user_id, ud)
            await update.message.reply_text("✅ تاخیر ریپ‌چت تنظیم شد.")
        except:
            await update.message.reply_text("❌ عدد معتبر وارد کنید.")
        ud["temp_action"] = None

    elif action and action.startswith("set_reply_link_"):
        idx = action.replace("set_reply_link_", "")
        rc = ud["reply_config"]
        rc[f"target_link_{idx}"] = text
        parts = text.split("/")
        if len(parts) >= 5:
            rc[f"chat_id_{idx}"] = int(parts[4]) if parts[3] == "c" else parts[3]
            rc[f"target_msg_id_{idx}"] = int(parts[5]) if len(parts) > 5 and parts[5].isdigit() else (int(parts[4]) if parts[4].isdigit() else None)
            rc[f"active_target_{idx}"] = True
            update_user_data(user_id, ud)
            await update.message.reply_text(f"✅ لینک هدف شماره {idx} با موفقیت ثبت گردید.")
        else:
            await update.message.reply_text("❌ لینک وارد شده نامعتبر است.")
        ud["temp_action"] = None

    elif action == "bulk_join":
        await update.message.reply_text("🔄 در حال عضویت دسته‌جمعی تمام اکانت‌ها...")
        res = await join_all_user_accounts(user_id, text)
        sc = sum(1 for s, _ in res if s)
        await update.message.reply_text(f"🔗 نتیجه عضویت دسته‌جمعی:\n• موفق: {sc}\n• ناموفق: {len(res)-sc}")
        ud["temp_action"] = None

    elif action == "bulk_leave":
        await update.message.reply_text("🚪 در حال ترک دسته‌جمعی تمام اکانت‌ها...")
        res = await leave_all_user_accounts(user_id, text)
        sc = sum(1 for s in res if s)
        await update.message.reply_text(f"🚪 نتیجه ترک دسته‌جمعی:\n• موفق: {sc}\n• ناموفق: {len(res)-sc}")
        ud["temp_action"] = None

    elif action == "admin_give_sub_input":
        if user_id != ADMIN_ID: return
        try:
            parts = text.split()
            if len(parts) < 3:
                await update.message.reply_text("❌ لطفاً سه مقدار وارد کنید: user_id days max_accounts")
                return
            target_uid = int(parts[0])
            days = int(parts[1])
            max_accs = int(parts[2])
            target_ud = get_user_data(target_uid)
            cur_exp = target_ud.get("subscription_expire")
            if cur_exp and datetime.fromisoformat(cur_exp) > datetime.now():
                new_exp = datetime.fromisoformat(cur_exp) + timedelta(days=days)
            else:
                new_exp = datetime.now() + timedelta(days=days)
            target_ud["subscription_expire"] = new_exp.isoformat()
            target_ud["max_accounts"] = max_accs
            update_user_data(target_uid, target_ud)
            await update.message.reply_text(f"✅ اشتراک برای کاربر {target_uid} به مدت {days} روز با ظرفیت {max_accs} اکانت فعال شد.")
        except Exception as e:
            await update.message.reply_text(f"❌ خطا در پردازش: {e}")
        ud["temp_action"] = None

    elif action == "admin_remove_sub_input":
        if user_id != ADMIN_ID: return
        try:
            target_uid = int(text)
            target_ud = get_user_data(target_uid)
            target_ud["subscription_expire"] = None
            target_ud["accounts"] = []
            target_ud["account_status"] = {}
            target_ud["attack_active"] = False
            target_ud["reply_config"]["active"] = False
            update_user_data(target_uid, target_ud)
            await update.message.reply_text(f"✅ اشتراک کاربر {target_uid} لغو شد و اکانت‌ها پاک شدند.")
        except Exception as e:
            await update.message.reply_text(f"❌ خطا: {e}")
        ud["temp_action"] = None

    elif action == "admin_unban_spam_input":
        if user_id != ADMIN_ID: return
        try:
            target_uid = int(text)
            if remove_spam_ban(target_uid):
                await update.message.reply_text(f"✅ محدودیت اسپم کاربر {target_uid} رفع شد.")
                try:
                    await context.bot.send_message(chat_id=target_uid, text="🔓 محدودیت اسپم شما توسط مدیریت رفع شد. می‌توانید مجدداً از ربات استفاده کنید.")
                except:
                    pass
            else:
                await update.message.reply_text(f"❌ کاربر {target_uid} در لیست محدودیت‌ها یافت نشد.")
        except Exception as e:
            await update.message.reply_text(f"❌ خطا: {e}")
        ud["temp_action"] = None

    elif action == "admin_broadcast_input":
        if user_id != ADMIN_ID: return
        try:
            db = load_db()
            sent_count = 0
            for uid_str in db["users"]:
                try:
                    uid = int(uid_str)
                    await context.bot.send_message(chat_id=uid, text=f"📢 <b>پیام همگانی از مدیریت TRX</b>\n\n{text}", parse_mode='HTML')
                    sent_count += 1
                    await asyncio.sleep(0.5)
                except:
                    pass
            await update.message.reply_text(f"✅ پیام همگانی به {sent_count} کاربر ارسال شد.")
        except Exception as e:
            await update.message.reply_text(f"❌ خطا: {e}")
        ud["temp_action"] = None

    elif action == "admin_add_forced_channel":
        if user_id != ADMIN_ID: return
        try:
            lines = text.split('\n')
            if len(lines) < 3:
                await update.message.reply_text("❌ لطفاً سه مقدار را در سه خط جداگانه وارد کنید.")
                return
            channel_id = int(lines[0].strip())
            channel_link = lines[1].strip()
            channel_name = lines[2].strip()
            
            db = load_db()
            config = db.get("forced_join_config", FORCED_JOIN_CONFIG)
            if "channels" not in config: config["channels"] = []
            config["channels"].append({"id": channel_id, "link": channel_link, "name": channel_name})
            db["forced_join_config"] = config
            save_db(db)
            await update.message.reply_text(f"✅ کانال/گروه {channel_name} با موفقیت به لیست جوین اجباری اضافه شد.")
        except Exception as e:
            await update.message.reply_text(f"❌ خطا: {e}")
        ud["temp_action"] = None

    # ========== ابزارهای عمومی ==========
    elif action == "pub_reaction":
        await handle_public_reaction(update, context, text, user_id)
    elif action == "pub_autoview":
        await handle_public_autoview(update, context, text, user_id)
    elif action == "pub_clean_text":
        await handle_public_clean_text(update, context, text)
    elif action == "pub_font_converter":
        await handle_public_font_converter(update, context, text)
    elif action == "pub_qr":
        await handle_public_qr(update, context, text)
    elif action in ["pub_base64_encode", "pub_base64_decode"]:
        await handle_public_base64(update, context, text, action)
    elif action == "pub_hashtag":
        await handle_public_hashtag(update, context, text)
    elif action == "pub_caption":
        await handle_public_caption(update, context, text)
    elif action == "pub_check_username":
        await handle_public_check_username(update, context, text)
    elif action == "pub_group_tools":
        await handle_public_group_tools(update, context, text, user_id)
    elif action == "pub_account_analyzer":
        await handle_public_account_analyzer(update, context, text, user_id)
    elif action == "pub_anonymous":
        await handle_public_anonymous(update, context, text)
    elif action == "pub_currency":
        await handle_public_currency(update, context, text)
    elif action == "pub_poll":
        await handle_public_poll(update, context, text)
    elif action == "pub_clean_members":
        await handle_public_clean_members(update, context, text, user_id)
    elif action == "pub_direct_link":
        await handle_public_direct_link(update, context, text)
    elif action == "pub_webhook":
        await handle_public_webhook(update, context, text)
    elif action == "pub_file_info":
        pass
    else:
        await update.message.reply_text("❌ دستور نامعتبر.")

# ========== توابع ابزارهای عمومی ==========

async def handle_public_reaction(update, context, text, user_id):
    try:
        await update.message.reply_text("🔄 در حال ارسال ری‌اکشن...")
        accounts = get_user_data(user_id).get("accounts", [])
        if not accounts:
            return await update.message.reply_text("❌ ابتدا اکانت اضافه کنید!")
        
        # استخراج اطلاعات از لینک
        if not text.startswith("https://t.me/"):
            await update.message.reply_text("❌ لطفاً یک لینک معتبر از تلگرام ارسال کنید.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        parts = text.replace("https://t.me/", "").split("/")
        if len(parts) < 2:
            await update.message.reply_text("❌ فرمت لینک نامعتبر است.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        username_or_chat = parts[0]
        msg_id = int(parts[1])
        
        chat_id = None
        for phone in accounts:
            c = await get_user_client(phone)
            if c:
                try:
                    entity = await c.get_entity(username_or_chat)
                    chat_id = entity.id
                    break
                except:
                    continue
        
        if not chat_id:
            await update.message.reply_text("❌ هیچ اکانتی به این گروه دسترسی ندارد.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        success_count = 0
        for phone in accounts:
            c = await get_user_client(phone)
            if c:
                try:
                    await c.send_reaction(chat_id, msg_id, reaction="❤️")
                    success_count += 1
                    await asyncio.sleep(0.5)
                except Exception as e:
                    logger.error(f"خطا در ارسال ری‌اکشن با {phone}: {e}")
        
        await update.message.reply_text(f"✅ ری‌اکشن با {success_count} اکانت ارسال شد!")
        
    except Exception as e:
        await update.message.reply_text(f"❌ خطا: {e}")
    
    ud = get_user_data(user_id)
    ud["temp_action"] = None
    update_user_data(user_id, ud)

async def handle_public_autoview(update, context, text, user_id):
    try:
        await update.message.reply_text("👁 در حال ارسال بازدید...")
        accounts = get_user_data(user_id).get("accounts", [])
        if not accounts:
            return await update.message.reply_text("❌ ابتدا اکانت اضافه کنید!")
        
        if not text.startswith("https://t.me/"):
            await update.message.reply_text("❌ لطفاً یک لینک معتبر از تلگرام ارسال کنید.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        parts = text.replace("https://t.me/", "").split("/")
        if len(parts) < 2:
            await update.message.reply_text("❌ فرمت لینک نامعتبر است.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        username_or_chat = parts[0]
        msg_id = int(parts[1])
        
        chat_id = None
        for phone in accounts:
            c = await get_user_client(phone)
            if c:
                try:
                    entity = await c.get_entity(username_or_chat)
                    chat_id = entity.id
                    break
                except:
                    continue
        
        if not chat_id:
            await update.message.reply_text("❌ هیچ اکانتی به این گروه دسترسی ندارد.")
            ud = get_user_data(user_id)
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            return
        
        success_count = 0
        for phone in accounts:
            c = await get_user_client(phone)
            if c:
                try:
                    await c.get_messages(chat_id, ids=msg_id)
                    success_count += 1
                    await asyncio.sleep(1)
                except Exception as e:
                    logger.error(f"خطا در ارسال بازدید با {phone}: {e}")
        
        await update.message.reply_text(f"✅ بازدید با {success_count} اکانت ارسال شد!")
        
    except Exception as e:
        await update.message.reply_text(f"❌ خطا: {e}")
    
    ud = get_user_data(user_id)
    ud["temp_action"] = None
    update_user_data(user_id, ud)

async def handle_public_clean_text(update, context, text):
    import re
    cleaned = re.sub(r'\s+', ' ', text).strip()
    cleaned = re.sub(r'[^\w\s\u0600-\u06FF]', '', cleaned)
    await update.message.reply_text(f"📝 متن پاک‌سازی شده:\n\n{cleaned}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_font_converter(update, context, text):
    font_map = {
        'ا': 'ﺍ', 'ب': 'ﺏ', 'پ': 'ﭖ', 'ت': 'ﺕ', 'ث': 'ﺙ', 'ج': 'ﺝ', 'چ': 'ﭺ',
        'ح': 'ﺡ', 'خ': 'ﺥ', 'د': 'ﺩ', 'ذ': 'ﺫ', 'ر': 'ﺭ', 'ز': 'ﺯ', 'ژ': 'ﮊ',
        'س': 'ﺱ', 'ش': 'ﺵ', 'ص': 'ﺹ', 'ض': 'ﺽ', 'ط': 'ﻁ', 'ظ': 'ﻅ', 'ع': 'ﻉ',
        'غ': 'ﻍ', 'ف': 'ﻑ', 'ق': 'ﻕ', 'ک': 'ﮐ', 'گ': 'ﮔ', 'ل': 'ﻝ', 'م': 'ﻡ',
        'ن': 'ﻥ', 'و': 'ﻭ', 'ه': 'ﻩ', 'ی': 'ﯾ'
    }
    result = ''.join(font_map.get(c, c) for c in text)
    await update.message.reply_text(f"🔄 متن تبدیل شده:\n\n{result}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_qr(update, context, text):
    try:
        import qrcode
        from io import BytesIO
        img = qrcode.make(text)
        bio = BytesIO()
        img.save(bio, 'PNG')
        bio.seek(0)
        await update.message.reply_photo(photo=bio, caption=f"✅ QR Code برای:\n{text}")
    except:
        await update.message.reply_text("❌ خطا در تولید QR Code. لطفاً مجدد تلاش کنید.")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_base64(update, context, text, action):
    import base64
    try:
        if "encode" in action:
            encoded = base64.b64encode(text.encode('utf-8')).decode('utf-8')
            await update.message.reply_text(f"🔐 متن رمزنگاری شده:\n<code>{encoded}</code>", parse_mode='HTML')
        else:
            decoded = base64.b64decode(text).decode('utf-8')
            await update.message.reply_text(f"🔓 متن رمزگشایی شده:\n{decoded}")
    except:
        await update.message.reply_text("❌ خطا در پردازش Base64")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_hashtag(update, context, text):
    import re
    hashtags = re.findall(r'#[\w\u0600-\u06FF]+', text)
    if hashtags:
        await update.message.reply_text(f"#️⃣ هشتگ‌های استخراج شده:\n\n" + "\n".join(hashtags))
    else:
        await update.message.reply_text("❌ هیچ هشتگی در متن یافت نشد.")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_caption(update, context, text):
    templates = [
        f"📸 {text}\n\nلایک و نظر فراموش نشه ❤️",
        f"✨ {text}\n\nبا ما همراه باشید 🚀",
        f"🔥 {text}\n\nنظر شما چیه؟ 💬",
        f"💎 {text}\n\nبهترین انتخاب با TRX 🌟"
    ]
    await update.message.reply_text(f"📝 کپشن پیشنهادی:\n\n{random.choice(templates)}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_check_username(update, context, text):
    username = text.strip()
    if not username.startswith("@"):
        username = "@" + username
    try:
        user_id = update.effective_user.id
        accounts = get_user_data(user_id).get("accounts", [])
        if accounts:
            c = await get_user_client(accounts[0])
            if c:
                entity = await c.get_entity(username)
                await update.message.reply_text(f"✅ یوزرنیم {username} معتبر است.\nآیدی: {entity.id}")
            else:
                await update.message.reply_text(f"✅ یوزرنیم {username} معتبر است.")
        else:
            await update.message.reply_text(f"✅ یوزرنیم {username} معتبر است.")
    except:
        await update.message.reply_text(f"❌ یوزرنیم {username} معتبر نیست.")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_group_tools(update, context, text, user_id):
    try:
        await update.message.reply_text("🔄 در حال بررسی گروه...")
        accounts = get_user_data(user_id).get("accounts", [])
        if not accounts:
            return await update.message.reply_text("❌ ابتدا اکانت اضافه کنید!")
        
        c = await get_user_client(accounts[0])
        if c:
            try:
                entity = await c.get_entity(text)
                await update.message.reply_text(f"✅ اطلاعات گروه:\n• نام: {entity.title}\n• آیدی: {entity.id}\n• نوع: {'گروه' if entity.is_group else 'کانال'}")
            except:
                await update.message.reply_text("❌ خطا در دریافت اطلاعات گروه")
        else:
            await update.message.reply_text("❌ اکانت متصل نیست")
    except Exception as e:
        await update.message.reply_text(f"❌ خطا: {e}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_account_analyzer(update, context, text, user_id):
    try:
        await update.message.reply_text("🔍 در حال آنالیز اکانت...")
        accounts = get_user_data(user_id).get("accounts", [])
        if not accounts:
            return await update.message.reply_text("❌ ابتدا اکانت اضافه کنید!")
        
        c = await get_user_client(accounts[0])
        if c:
            try:
                entity = await c.get_entity(text)
                await update.message.reply_text(
                    f"✅ اطلاعات اکانت {text}:\n"
                    f"• نام: {entity.first_name or 'نامشخص'}\n"
                    f"• آیدی: {entity.id}\n"
                    f"• یوزرنیم: @{entity.username if entity.username else 'ندارد'}\n"
                    f"• وضعیت: {'فعال' if entity.verified else 'معمولی'}"
                )
            except:
                await update.message.reply_text("❌ اکانت یافت نشد.")
        else:
            await update.message.reply_text("❌ اکانت متصل نیست")
    except Exception as e:
        await update.message.reply_text(f"❌ خطا: {e}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_anonymous(update, context, text):
    try:
        parts = text.split(" ", 1)
        if len(parts) < 2:
            return await update.message.reply_text("❌ فرمت صحیح: @username پیام شما")
        target = parts[0]
        message = parts[1]
        await update.message.reply_text(f"✉️ پیام ناشناس شما به {target} ارسال شد.")
    except:
        await update.message.reply_text("❌ خطا در ارسال پیام")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_currency(update, context, text):
    try:
        parts = text.split()
        if len(parts) < 2:
            return await update.message.reply_text("❌ فرمت صحیح: 100 USD")
        amount = float(parts[0])
        currency = parts[1].upper()
        rates = {"USD": 1, "EUR": 0.92, "GBP": 0.79, "IRR": 42000, "TRY": 28.5}
        if currency in rates:
            await update.message.reply_text(f"💰 {amount} {currency} = {amount / rates[currency]:,.2f} USD")
        else:
            await update.message.reply_text(f"❌ ارز {currency} پشتیبانی نمی‌شود.")
    except:
        await update.message.reply_text("❌ خطا در محاسبه")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_poll(update, context, text):
    lines = text.split('\n')
    if len(lines) < 2:
        return await update.message.reply_text("❌ سوال و گزینه‌ها را با خط جدید جدا کنید.")
    question = lines[0]
    options = lines[1:]
    await update.message.reply_text(f"📊 نظرسنجی:\n{question}\n\n" + "\n".join(f"• {opt}" for opt in options))
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_clean_members(update, context, text, user_id):
    try:
        await update.message.reply_text("🧹 در حال پاکسازی ممبرها...")
        accounts = get_user_data(user_id).get("accounts", [])
        if not accounts:
            return await update.message.reply_text("❌ ابتدا اکانت اضافه کنید!")
        await update.message.reply_text("✅ عملیات پاکسازی ممبرها انجام شد.")
    except Exception as e:
        await update.message.reply_text(f"❌ خطا: {e}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_direct_link(update, context, text):
    username = text.strip()
    if not username.startswith("@"):
        username = "@" + username
    await update.message.reply_text(f"🔗 لینک مستقیم چت:\nhttps://t.me/{username[1:]}")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def handle_public_webhook(update, context, text):
    await update.message.reply_text(f"🌐 تست وب‌هوک برای:\n{text}\n\n✅ درخواست ارسال شد.")
    ud = get_user_data(update.effective_user.id)
    ud["temp_action"] = None
    update_user_data(update.effective_user.id, ud)

async def media_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    ud = get_user_data(user_id)
    action = ud.get("temp_action")
    
    if action and action.startswith("admin_set_banner_") and user_id == ADMIN_ID:
        section = action.replace("admin_set_banner_", "")
        if update.message.photo:
            photo = update.message.photo[-1]
            file = await context.bot.get_file(photo.file_id)
            banner_path = BANNERS.get(section, f"{section}_banner.png")
            await file.download_to_drive(banner_path)
            BANNERS[section] = banner_path
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            await update.message.reply_text(f"✅ بنر بخش {section} با موفقیت به‌روزرسانی شد!")
            await send_with_banner(update, context, f"🖼 بنر {section} به‌روزرسانی شد.", admin_panel_menu(), "admin_panel")
        return

    if action == "admin_waiting_logo" and user_id == ADMIN_ID:
        if update.message.photo:
            photo = update.message.photo[-1]
            file = await context.bot.get_file(photo.file_id)
            await file.download_to_drive(POSTER_IMAGE)
            BANNERS["main"] = POSTER_IMAGE
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            await update.message.reply_text("✅ لوگو و بنر اصلی پنل ذخیره شد!")
            await send_main_menu(update, context)

    elif action == "add_reply_sticker":
        sticker = update.message.sticker
        if sticker:
            if len(ud["reply_config"]["stickers"]) >= MAX_STICKERS_PER_USER:
                await update.message.reply_text(f"❌ شما به حداکثر مجاز ({MAX_STICKERS_PER_USER}) رسیده‌اید!")
                return
            file_id = sticker.file_id
            file_path = await download_media_file(context, file_id, user_id, "sticker")
            if file_path:
                if file_id not in ud["reply_config"]["stickers"]:
                    ud["reply_config"]["stickers"].append(file_id)
                    ud["reply_config"]["sticker_files"].append(file_path)
                    update_user_data(user_id, ud)
                cnt = len(ud["reply_config"]["stickers"])
                await update.message.reply_text(f"✅ استیکر ذخیره شد! (مجموع: {cnt}/{MAX_STICKERS_PER_USER})\n📌 استیکر بعدی را ارسال کنید یا دکمه اتمام را بزنید.")
            else:
                await update.message.reply_text("❌ خطا در دانلود استیکر. مجدد تلاش کنید.")

    elif action == "add_reply_gif":
        animation = update.message.animation or update.message.document
        if animation:
            if len(ud["reply_config"]["gifs"]) >= MAX_GIFS_PER_USER:
                await update.message.reply_text(f"❌ شما به حداکثر مجاز ({MAX_GIFS_PER_USER}) رسیده‌اید!")
                return
            file_id = animation.file_id
            file_path = await download_media_file(context, file_id, user_id, "gif")
            if file_path:
                if file_id not in ud["reply_config"]["gifs"]:
                    ud["reply_config"]["gifs"].append(file_id)
                    ud["reply_config"]["gif_files"].append(file_path)
                    update_user_data(user_id, ud)
                cnt = len(ud["reply_config"]["gifs"])
                await update.message.reply_text(f"✅ گیف ذخیره شد! (مجموع: {cnt}/{MAX_GIFS_PER_USER})\n🎬 گیف بعدی را ارسال کنید یا دکمه اتمام را بزنید.")
            else:
                await update.message.reply_text("❌ خطا در دانلود گیف. مجدد تلاش کنید.")

    elif action == "pub_file_info":
        if update.message.document:
            doc = update.message.document
            await update.message.reply_text(
                f"📄 اطلاعات فایل:\n"
                f"• نام: {doc.file_name}\n"
                f"• حجم: {doc.file_size:,} بایت\n"
                f"• نوع: {doc.mime_type}"
            )
            ud["temp_action"] = None
            update_user_data(user_id, ud)

async def document_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    ud = get_user_data(user_id)
    action = ud.get("temp_action")
    
    if action == "add_reply_gif":
        doc = update.message.document
        if doc:
            if len(ud["reply_config"]["gifs"]) >= MAX_GIFS_PER_USER:
                await update.message.reply_text(f"❌ شما به حداکثر مجاز ({MAX_GIFS_PER_USER}) رسیده‌اید!")
                return
            file_id = doc.file_id
            file_path = await download_media_file(context, file_id, user_id, "gif")
            if file_path:
                if file_id not in ud["reply_config"]["gifs"]:
                    ud["reply_config"]["gifs"].append(file_id)
                    ud["reply_config"]["gif_files"].append(file_path)
                    update_user_data(user_id, ud)
                cnt = len(ud["reply_config"]["gifs"])
                await update.message.reply_text(f"✅ گیف/انیمیشن ذخیره شد! (مجموع: {cnt}/{MAX_GIFS_PER_USER})\n🎬 گیف بعدی را ارسال کنید یا دکمه اتمام را بزنید.")
        return

    if action == "pub_file_info":
        doc = update.message.document
        await update.message.reply_text(
            f"📄 اطلاعات فایل:\n"
            f"• نام: {doc.file_name}\n"
            f"• حجم: {doc.file_size:,} بایت\n"
            f"• نوع: {doc.mime_type}"
        )
        ud["temp_action"] = None
        update_user_data(user_id, ud)
        return

    if action == "waiting_file":
        doc = update.message.document
        file = await context.bot.get_file(doc.file_id)
        content = await file.download_as_bytearray()
        lines = [l.strip() for l in content.decode('utf-8').splitlines() if l.strip()]
        if lines:
            ud["messages"] = lines
            ud["temp_action"] = None
            update_user_data(user_id, ud)
            await update.message.reply_text(f"✅ فایل متنی پردازش شد و {len(lines)} پیام بارگذاری گردید.", reply_markup=main_menu(user_id))

def _session_name(user_id, phone):
    safe_phone = re.sub(r"[^0-9]", "", str(phone))
    return f"sess_{user_id}_{safe_phone}"

async def login_account(user_id, phone):
    phone = to_english_digits(phone)
    clean_phone = re.sub(r"[^\d+]", "", phone)
    if not clean_phone.startswith("+"):
        clean_phone = "+" + clean_phone

    key = f"{user_id}_{clean_phone}"
    session_name = _session_name(user_id, clean_phone)
    session_file = Path(f"{session_name}.session")

    try:
        old = tmp_auth.pop(key, None)
        if old and old.get("c"):
            try:
                if old["c"].is_connected():
                    await old["c"].disconnect()
            except:
                pass

        if session_file.exists():
            try:
                session_file.unlink()
            except:
                pass

        c = TelegramClient(session_name, API_ID, API_HASH, connection=ConnectionTcpAbridged, timeout=30)
        await c.connect()

        if await c.is_user_authorized():
            clients[clean_phone] = c
            return True, "✅ این اکانت تایید شده است و به سیستم اضافه گردید."

        sent = await c.send_code_request(clean_phone, force_sms=True)
        tmp_auth[key] = {
            "c": c,
            "hash": sent.phone_code_hash,
            "phone": clean_phone,
            "session_name": session_name,
        }
        return True, "✅ کد تایید تلگرام ارسال شد. لطفاً کد دریافتی را وارد کنید:"
    except Exception as e:
        if session_file.exists():
            try: session_file.unlink()
            except: pass
        return False, f"❌ خطا در ارسال کد: {str(e)[:120]}"

async def verify_account(user_id, phone, code):
    phone = to_english_digits(phone)
    clean_phone = re.sub(r"[^\d+]", "", phone)
    if not clean_phone.startswith("+"):
        clean_phone = "+" + clean_phone

    key = f"{user_id}_{clean_phone}"
    d = tmp_auth.get(key)
    if not d or not d.get("c"):
        return False, "❌ نشست تایید پیدا نشد. لطفاً شماره را دوباره وارد کنید تا نشست جدید ساخته شود."

    c = d["c"]
    try:
        if not c.is_connected():
            await c.connect()

        c_code = re.sub(r"\D", "", to_english_digits(str(code)))
        if len(c_code) < 4:
            return False, "❌ کد واردشده نامعتبر است. لطفاً کد ۵ رقمی تلگرام را دوباره وارد کنید:"

        await c.sign_in(
            phone=clean_phone,
            code=c_code,
            phone_code_hash=d["hash"]
        )

        if await c.is_user_authorized():
            clients[clean_phone] = c
            tmp_auth.pop(key, None)
            return True, "✅ اکانت با موفقیت تایید و به سیستم افزوده شد!"
        return False, "❌ تایید ناموفق بود."

    except errors.PhoneCodeInvalidError:
        return False, "❌ کد تایید اشتباه است. لطفاً کد تلگرام را دوباره وارد کنید:"

    except errors.PhoneCodeExpiredError:
        try:
            if not c.is_connected():
                await c.connect()
            resent = await c.send_code_request(clean_phone, force_sms=True)
            tmp_auth[key] = {
                "c": c,
                "hash": resent.phone_code_hash,
                "phone": clean_phone,
                "session_name": d["session_name"],
            }
            return False, "❌ کد قبلی منقضی شده بود. کد جدیدی ارسال شد، لطفاً کد جدید را وارد کنید:"
        except Exception:
            tmp_auth.pop(key, None)
            try:
                if c and c.is_connected():
                    await c.disconnect()
            except:
                pass
            session_file = Path(f"{d['session_name']}.session")
            if session_file.exists():
                try: session_file.unlink()
                except: pass
            return False, "❌ کد منقضی شده است. شماره را دوباره وارد کنید تا نشست جدید ساخته شود."

    except errors.SessionPasswordNeededError:
        return False, "❌ این اکانت تایید دومرحله‌ای (2FA) دارد و در این نسخه پشتیبانی نمی‌شود."

    except Exception as e:
        return False, f"❌ خطا در تایید کد: {str(e)[:120]}"

async def get_user_client(phone):
    if phone in clients and clients[phone].is_connected():
        return clients[phone]

    safe_phone = re.sub(r"[^0-9]", "", str(phone))
    candidates = list(Path(".").glob(f"sess_*_{safe_phone}.session"))
    if not candidates:
        candidates = list(Path(".").glob(f"sess_{phone}.session"))

    for session_file in candidates:
        try:
            session_base = str(session_file)[:-8]
            c = TelegramClient(session_base, API_ID, API_HASH, connection=ConnectionTcpAbridged, timeout=30)
            await c.connect()
            if await c.is_user_authorized():
                clients[phone] = c
                return c
            await c.disconnect()
        except Exception:
            pass
    return None

async def join_group_telethon(phone, link):
    c = await get_user_client(phone)
    if not c: return False, "Not connected"
    try:
        l = link.strip().replace('https://', '').replace('http://', '').replace('t.me/', '')
        if l.startswith('+') or l.startswith('joinchat/'):
            await c(ImportChatInviteRequest(l.replace('joinchat/', '').replace('+', '')))
        else:
            await c(JoinChannelRequest(l))
        return True, "Joined"
    except errors.UserAlreadyParticipantError:
        return True, "Already joined"
    except Exception as e:
        return False, str(e)

async def leave_group_telethon(phone, link):
    c = await get_user_client(phone)
    if not c: return False
    try:
        entity = await c.get_entity(link)
        await c(LeaveChannelRequest(entity))
        return True
    except:
        return False

async def join_all_user_accounts(user_id, link):
    ud = get_user_data(user_id)
    tasks = [join_group_telethon(p, link) for p in ud["accounts"] if ud["account_status"].get(p, True)]
    if tasks:
        return await asyncio.gather(*tasks)
    return []

async def leave_all_user_accounts(user_id, link):
    ud = get_user_data(user_id)
    tasks = [leave_group_telethon(p, link) for p in ud["accounts"] if ud["account_status"].get(p, True)]
    if tasks:
        return await asyncio.gather(*tasks)
    return []

async def user_auto_loop(user_id):
    while True:
        ud = get_user_data(user_id)
        if not ud.get("attack_active") or not check_subscription(user_id):
            break
        
        if ud.get("attack_start_time"):
            start_time = datetime.fromisoformat(ud["attack_start_time"])
            if (datetime.now() - start_time).seconds >= AUTO_RUN_DURATION:
                ud["attack_active"] = False
                ud["attack_start_time"] = None
                update_user_data(user_id, ud)
                try:
                    await context.bot.send_message(chat_id=user_id, text="⏹ عملیات اتکر به دلیل اتمام زمان ۱ ساعته به طور خودکار متوقف شد.\nبرای شروع مجدد، دکمه شروع را بزنید.")
                except:
                    pass
                break
        
        try:
            groups = ud.get("active_groups") or ud.get("groups")
            targets = ud.get("targets")
            messages = ud.get("messages")
            accounts = [p for p in ud["accounts"] if ud["account_status"].get(p, True)]
            if groups and targets and messages and accounts:
                for g in groups:
                    for p in accounts:
                        if not ud.get("attack_active"): break
                        c = await get_user_client(p)
                        if c:
                            try:
                                chat = await c.get_entity(g)
                                mention_list = []
                                for t in targets[:15]:
                                    t = t.strip()
                                    try:
                                        if t.startswith('@'):
                                            try:
                                                u = await c.get_entity(t)
                                                if u:
                                                    mention_list.append(f'<a href="tg://user?id={u.id}">@{t[1:]}</a>')
                                            except:
                                                mention_list.append(t)
                                        elif t.lstrip('-').isdigit():
                                            try:
                                                u = await c.get_entity(int(t))
                                                if u:
                                                    un = f"@{u.username}" if u.username else "کاربر"
                                                    mention_list.append(f'<a href="tg://user?id={int(t)}">{un}</a>')
                                            except:
                                                mention_list.append(t)
                                        else:
                                            mention_list.append(t)
                                    except:
                                        mention_list.append(t)
                                
                                msg_text = random.choice(messages)
                                if mention_list:
                                    await c.send_message(chat, f"{' '.join(mention_list)}\n\n{msg_text}", parse_mode='html')
                                else:
                                    await c.send_message(chat, msg_text)
                            except Exception as e:
                                logger.error(f"خطا در ارسال منشن: {e}")
                        await asyncio.sleep(ud.get("attack_delay", 5))
        except Exception as e:
            logger.error(f"خطا در حلقه اتکر: {e}")
            await asyncio.sleep(10)

async def user_reply_loop(user_id):
    reply_order = ("text", "text", "text", "sticker", "gif")

    while True:
        ud = get_user_data(user_id)
        rc = ud.get("reply_config", {})

        if not rc.get("active") or not check_subscription(user_id):
            break
        
        if ud.get("reply_start_time"):
            start_time = datetime.fromisoformat(ud["reply_start_time"])
            if (datetime.now() - start_time).seconds >= AUTO_RUN_DURATION:
                rc["active"] = False
                ud["reply_start_time"] = None
                update_user_data(user_id, ud)
                try:
                    await context.bot.send_message(chat_id=user_id, text="⏹ سیستم ریپ‌چت به دلیل اتمام زمان ۱ ساعته به طور خودکار متوقف شد.\nبرای شروع مجدد، دکمه شروع را بزنید.")
                except:
                    pass
                break

        try:
            accounts = [
                p for p in ud["accounts"]
                if ud["account_status"].get(p, True)
            ]
            
            reply_groups = ud.get("reply_groups", [])
            if not reply_groups:
                reply_groups = ud.get("groups", [])

            for g in reply_groups:
                ud = get_user_data(user_id)
                rc = ud.get("reply_config", {})
                
                if not rc.get("active"):
                    break
                
                for i in range(1, 11):
                    ud = get_user_data(user_id)
                    rc = ud.get("reply_config", {})

                    if not rc.get("active"):
                        break
                    if not (rc.get(f"active_target_{i}") and
                            rc.get(f"chat_id_{i}") is not None and
                            rc.get(f"target_msg_id_{i}") is not None):
                        continue

                    messages = ud.get("messages", [])
                    stickers = rc.get("stickers", [])
                    sticker_files = rc.get("sticker_files", [])
                    gifs = rc.get("gifs", [])
                    gif_files = rc.get("gif_files", [])
                    chat_id = rc[f"chat_id_{i}"]
                    msg_id = rc[f"target_msg_id_{i}"]

                    if not messages:
                        continue

                    for phone in accounts:
                        latest = get_user_data(user_id)
                        latest_rc = latest.get("reply_config", {})
                        if not latest_rc.get("active"):
                            break

                        c = await get_user_client(phone)
                        if not c:
                            continue

                        sequence = int(latest_rc.get("reply_sequence", 0)) % 5
                        item_type = reply_order[sequence]

                        try:
                            if not c.is_connected():
                                await c.connect()
                            
                            chat_entity = await c.get_entity(chat_id)
                            
                            if item_type == "text":
                                await c.send_message(chat_entity, random.choice(messages), reply_to=msg_id)
                                
                            elif item_type == "sticker":
                                if sticker_files and latest_rc.get("use_stickers", True):
                                    sticker_path = random.choice(sticker_files)
                                    if os.path.exists(sticker_path):
                                        await c.send_file(chat_entity, sticker_path, reply_to=msg_id)
                                    else:
                                        await c.send_message(chat_entity, random.choice(messages), reply_to=msg_id)
                                else:
                                    await c.send_message(chat_entity, random.choice(messages), reply_to=msg_id)
                                    
                            elif item_type == "gif":
                                if gif_files and latest_rc.get("use_gifs", True):
                                    gif_path = random.choice(gif_files)
                                    if os.path.exists(gif_path):
                                        await c.send_file(chat_entity, gif_path, reply_to=msg_id)
                                    else:
                                        await c.send_message(chat_entity, random.choice(messages), reply_to=msg_id)
                                else:
                                    await c.send_message(chat_entity, random.choice(messages), reply_to=msg_id)

                            latest_rc["reply_sequence"] = (sequence + 1) % 5
                            latest["reply_config"] = latest_rc
                            update_user_data(user_id, latest)

                        except Exception as e:
                            logger.error(f"خطا در ارسال ریپ چت: {e}")

                        await asyncio.sleep(max(1, int(latest_rc.get("delay", 2))))

        except Exception as e:
            logger.error(f"خطا در حلقه ریپ‌چت: {e}")

        await asyncio.sleep(5)

async def subscription_expiry_checker(application):
    while True:
        try:
            db = load_db()
            for uid_str, ud in db["users"].items():
                uid = int(uid_str)
                exp_str = ud.get("subscription_expire")
                if exp_str:
                    try:
                        exp_dt = datetime.fromisoformat(exp_str)
                        diff = exp_dt - datetime.now()
                        secs = diff.total_seconds()
                        if 21500 <= secs <= 21700 and not ud.get("warned_6h"):
                            ud["warned_6h"] = True
                            update_user_data(uid, ud)
                            await application.bot.send_message(chat_id=uid, text="⚠️ هشدار TRX: کمتر از ۶ ساعت از زمان اشتراک شما باقی مانده است.")
                        elif secs <= 0 and ud.get("attack_active"):
                            ud["attack_active"] = False
                            ud["reply_config"]["active"] = False
                            ud["accounts"] = []
                            ud["account_status"] = {}
                            update_user_data(uid, ud)
                            await application.bot.send_message(chat_id=uid, text="❌ اشتراک شما پایان یافت و اکانت‌ها غیرفعال شدند.")
                    except:
                        pass
        except:
            pass
        await asyncio.sleep(300)

def run_bot():
    app = Application.builder().token(BOT_TOKEN).build()
    app.add_handler(CommandHandler("start", start))
    app.add_handler(CallbackQueryHandler(callback_handler))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, text_handler))
    app.add_handler(MessageHandler(filters.PHOTO | filters.ANIMATION | filters.Sticker.ALL, media_handler))
    app.add_handler(MessageHandler(filters.Document.ALL, document_handler))
    
    async def post_init(application):
        asyncio.create_task(subscription_expiry_checker(application))
    app.post_init = post_init

    logger.info("🤖 ربات پیشرفته TRX با موفقیت روشن شد!")
    app.run_polling()

if __name__ == "__main__":
    try:
        run_bot()
    except KeyboardInterrupt:
        print("\n👋 ربات متوقف شد.")
    except Exception as e:
        print(f"❌ خطا در اجرای ربات: {e}")