#المبرمج_جاك
import os
import json
import time
import html
import asyncio
import warnings
import urllib.request
import traceback
import re
import string
import platform
import random
import random
import string
import asyncio
import itertools
import re
import string
import asyncio
import string
import asyncio
import itertools
from telethon.tl.functions.account import CheckUsernameRequest
from telethon.tl.functions.channels import CreateChannelRequest, UpdateUsernameRequest
from telethon.tl.functions.messages import SendMessageRequest
from telethon.errors import FloodWaitError, ChannelsTooMuchError, UserChannelsTooMuchError, UsernameOccupiedError, UsernameInvalidError
from telethon import events
from telethon.errors import FloodWaitError, UsernameInvalidError
from telethon.tl.functions.account import CheckUsernameRequest
from telethon import events
from telethon.tl.functions.channels import CreateChannelRequest, UpdateUsernameRequest
from telethon.tl.functions.account import CheckUsernameRequest
from telethon.errors import FloodWaitError
from datetime import datetime
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, LinkPreviewOptions
from telegram.ext import (
    Application,
    CommandHandler,
    CallbackQueryHandler,
    MessageHandler,
    filters,
    ContextTypes,
    ConversationHandler
)
from telethon import TelegramClient, events
from telethon import events, functions, types
from telethon.errors import SessionPasswordNeededError, PhoneCodeInvalidError, PasswordHashInvalidError
from telethon.errors import FloodWaitError, UsernameOccupiedError, UsernameInvalidError
import time
import threading
from telethon.sync import events  
from telethon.tl.functions.users import GetFullUserRequest
from telethon.tl.functions.photos import GetUserPhotosRequest
import time
from telethon import events
from telethon.tl.types import User, Chat, Channel

warnings.filterwarnings("ignore", category=UserWarning)

BOT_TOKEN = "8915623293:AAHDSjHikjV797zBfhwa7bJfUMGkQLU5WaU"  
API_ID = 30529223  
API_HASH = "4d0b8709921bfe21ba93fbc301327916"  
DEVELOPER_ID = 6640295325  
BOT_NAME = "O7"
SOURCE_NAME = "O7"
SOURCE_NAME_EN = "𝙎𝙊𝙐𝙍𝘾𝙀 𝙊𝟳"
SOURCE_USER = "xaacx"
DEV_USER = "oo7oo"
SOURCE_LOGO_ALAWAMER = "𝙎𝙊𝙐𝙍𝘾𝙀 𝙊𝟳"

var = {}
ACTIVE_CLIENTS = {}
backup_data = {"first_name": None, "last_name": None, "about": None, "photo": None}

DATA_FILE = "bot_data.json"
MUTED_FILE = 'muted_users.json'
RODOOD_FILE = 'rodoood.json'

Asiacel_Bot = '@yynnurybot'
Billion_Bot = '@EEObot'
Dinar_Bot = '@D900_BOT'
Infinity_Bot = '@INFINTBoT'

active_publishing_tasks = []
stop_flags = {}
hunter_flags = {}
active_fake_actions = {}



time_features = {
    'name_task': None,
    'bio_task': None,
    'original_name': '',
    'original_bio': ''
}


(
    WAIT_PHONE,
    WAIT_CODE,
    WAIT_PASSWORD,
    WAIT_EXTRACT,
    WAIT_BROADCAST,
    WAIT_FORCE_CHANNEL,
    WAIT_RESTORE_BACKUP,
    WAIT_BAN,
    WAIT_UNBAN,
    WAIT_VIP_ID,
    WAIT_VIP_ACCOUNTS,
    WAIT_VIP_DAYS,
    WAIT_DEL_VIP
) = range(13)

def load_data():
    if os.path.exists(DATA_FILE):
        try:
            with open(DATA_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except:
            pass
    return {
        "users": [],
        "banned_users": [],
        "stats": {"today_users": [], "last_day": str(datetime.now().date()), "total_messages": 0},
        "settings": {"status": True},
        "force_channels": [],
        "accounts": {}  
    }

def save_data(data):
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

data = load_data()

def check_day_reset():
    current_day = str(datetime.now().date())
    if data["stats"].get("last_day") != current_day:
        data["stats"]["today_users"] = []
        data["stats"]["last_day"] = current_day
        save_data(data)
        
import requests

def get_creation_date(uid: int) -> str:
    uid = int(uid)
    s = str(uid)

    try:
        url = "https://restore-access.indream.app/regdate"
        headers = {
            "user-agent": "Mozilla/5.0",
            "content-type": "application/json"
        }

        res = requests.post(
            url,
            headers=headers,
            json={"telegramId": uid},
            timeout=8
        )

        if res.status_code == 200:
            data = res.json()
            if "data" in data and "date" in data["data"]:
                return data["data"]["date"].replace("-", "/")[:7]
    except:
        pass

    base_years = [
        2013, 2014, 2015, 2016,
        2017, 2018, 2019, 2020,
        2021, 2022, 2023, 2024,
        2025, 2026
    ]

    try:
        num = int(s[-3:]) if len(s) >= 3 else int(s)

        year_index = num % len(base_years)
        year = base_years[year_index]

        month = (num % 12) + 1

        return f"{year}/{month:02d}"

    except:
        return "غير معروف"
        
        
def load_Rad_data(file, default):
    if os.path.exists(file):
        with open(file, 'r', encoding='utf-8') as f:
            return json.load(f)
    return default

def save_Rad_data(file, data):
    with open(file, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

muted_users = set(load_Rad_data(MUTED_FILE, []))
all_rodoood = load_Rad_data(RODOOD_FILE, {})


def clean_text(text):
    return re.sub(r'[^\w\s]', '', text).strip()

async def claim_username(username):
    try:
        created_chat = await client(CreateChannelRequest(
            title=f"🥇 Secured @{username}",
            about="تم صيد وحجز هذا المعرف تلقائياً بواسطة السورس السريع.",
            megagroup=False
        ))
        channel = created_chat.chats[0]
        await client(UpdateUsernameRequest(channel=channel, username=username))
        return True
    except RPCError as e:
        if "CHANNELS_ADMIN_PUBLIC_LIMIT" in str(e):
            return "limit_reached"
        return False
    except Exception:
        return False                

async def is_subscribed(app: Application, user_id: int) -> bool:
    if user_id == DEVELOPER_ID:
        return True
    for ch in data.get("force_channels", []):
        try:
            member = await app.bot.get_chat_member(chat_id=ch["id"], user_id=user_id)
            if member.status in ["left", "kicked"]:
                return False
        except Exception:
            return False
    return True
    
def get_pattern_by_type(hunt_type):
    patterns = {
        "ثلاثي1": "H_B_H", "خماسي ارقام": "HB444", "ثلاثي2": "H_4_B", "ثلاثي3": "H_4_0",
        "رباعي1": "HHH_B", "رباعي2": "H_BBB", "رباعي3": "HH_BB", "رباعي4": "HH_HB",
        "رباعي5": "HH_BH", "رباعي6": "HB_BH", "رباعي7": "HB_HB", "رباعي8": "HB_BB",
        "شبه رباعي1": "H_H_H_B", "شبه رباعي2": "H_B_B_B", "شبه رباعي3": "H_BB_H",
        "شبه رباعي4": "H_BB_B", "خماسي حرفين1": "HHHBR", "خماسي حرفين2": "H4BBB",
        "سداسي_حرفين1": "HBHHHB", "سداسي_حرفين2": "HHHHBB", "سداسي_حرفين6": "HHBBBB",
        "سداسي_شرطه": "HHHH_B", "سباعيات1": "HHHHHHB", "بوتات1": "HB_Bot"
    }
    if hunt_type.startswith("@"): return hunt_type.replace("@", "").lower()
    return patterns.get(hunt_type, hunt_type)

def generate_username(pattern):
    if any(c in pattern for c in ['H', 'B', '4']):
        chars, nums = string.ascii_lowercase, string.digits
        res = ""
        for p in pattern:
            if p == 'H': res += random.choice(chars)
            elif p == 'B': res += random.choice(chars + nums)
            elif p == '4': res += random.choice(nums)
            else: res += p
        return res
    return pattern
    

def loop_fake_action(client, chat_id, telegram_action, seconds):
    start_time = time.time()
    try:
        while time.time() - start_time < seconds:
            if threading.current_thread() != active_fake_actions.get(chat_id):
                break
                
            with client.action(chat_id, telegram_action):
                time.sleep(4)  
    except Exception:
        pass
    finally:
        if chat_id in active_fake_actions and threading.current_thread() == active_fake_actions.get(chat_id):
            del active_fake_actions[chat_id]
            
            
    def run_counter_loop(event, chat_id, seconds):
        for i in range(seconds, 0, -1):
            if chat_id not in active_counters:
                break
            try:
                event.edit(f"**‌‎⎙ - العداد التلقائي : {i}**")
            except Exception:
                break
            time.sleep(1)
            
        if chat_id in active_counters:
            try:
                event.edit("**‌‎⎙ - انتهى الوقت.**")
            except Exception:
                pass
            active_counters.pop(chat_id, None)


def get_force_keyboard():
    buttons = []
    for ch in data.get("force_channels", []):
        buttons.append([InlineKeyboardButton(text=ch["title"], url=ch["invite_link"])])
    return InlineKeyboardMarkup(buttons)

def get_main_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton(text="- عدد الحسابات", callback_data="count_accs", icon_custom_emoji_id="5852967837970206643", style="primary")],
        [InlineKeyboardButton(text="- حذف حساب", callback_data="del_acc", icon_custom_emoji_id="5852477713482255786", style="danger"), InlineKeyboardButton(text="- اضافة حساب", callback_data="add_acc", icon_custom_emoji_id="5397916757333654639", style="success")],
        [InlineKeyboardButton(text="- تعليمات البوت", callback_data="bot_guide", icon_custom_emoji_id="5440660757194744323", style="danger")],
        [InlineKeyboardButton(text="- قناة السورس", url=f"https://t.me/{SOURCE_USER}", icon_custom_emoji_id="5422439311196834318", style="primary")]
    ])

def get_dev_keyboard():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton(text="اخر التحديثات", url=f"https://t.me/{SOURCE_USER}", icon_custom_emoji_id="5271604874419647061", style="success")],
        [InlineKeyboardButton(text="الاعدادات", callback_data="dev_settings", icon_custom_emoji_id="5341715473882955310", style="primary"), InlineKeyboardButton(text="الاحصائيات", callback_data="dev_stats", icon_custom_emoji_id="5231200819986047254", style="primary")],
        [InlineKeyboardButton(text="الاجباري", callback_data="dev_force", icon_custom_emoji_id="5440660757194744323", style="primary"), InlineKeyboardButton(text="الاذاعة", callback_data="dev_bc", icon_custom_emoji_id="5224736245665511429", style="primary")],
        [InlineKeyboardButton(text="قسم الحظر", callback_data="dev_ban_section", icon_custom_emoji_id="5240241223632954241", style="danger"),
InlineKeyboardButton(text="الـ VIP", callback_data="vip", icon_custom_emoji_id="5438496463044752972", style="primary")],
        [InlineKeyboardButton(text="النسخة الإحتياطية", callback_data="dev_backup", icon_custom_emoji_id="5282843764451195532", style="success")]
    ])

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    check_day_reset()
    
    data["stats"]["total_messages"] = data["stats"].get("total_messages", 0) + 1
    
    if user_id not in data["users"]:
        data["users"].append(user_id)
        if user_id not in data["stats"]["today_users"]:
            data["stats"]["today_users"].append(user_id)
        save_data(data)
        
        try:
            user_name = update.effective_user.first_name
            user_username = f"@{update.effective_user.username}" if update.effective_user.username else "لا يوجد"
            date_now = datetime.now().strftime("%Y-%m-%d")
            total_users = len(data["users"])
            
            msg = (
                f"<b>New User •••\n"
                f" — — — — — — — — —\n"
                f"- Name : <a href=\"tg://user?id={user_id}\">{html.escape(user_name)}</a>\n"
                f"- User : {user_username}\n"
                f"- ID : <code>{user_id}</code>\n"
                f"- Date : {date_now}\n"
                f" — — — — — — — — —\n"
                f"- Total number of users : {total_users}</b>"
            )
            await context.bot.send_message(chat_id=DEVELOPER_ID, text=msg, parse_mode="HTML")
        except Exception as e:
            print(f"Error sending notification: {e}")

    if str(user_id) in data.get("banned_users", []):
        return

    if not await is_subscribed(context.application, user_id):
        await update.message.reply_text(
            f"<b>⌔︙عذراً عليك الأشتراك في قناة البوت أولاً،\n⌔︙اشترك ثم ارسل /start</b>",
            parse_mode="HTML",
            reply_markup=get_force_keyboard()
        )
        return

    if not data["settings"].get("status", True) and user_id != DEVELOPER_ID:
        await update.message.reply_text("<b><blockquote> 🛠 - البوت في وضع الصيانة الآن . </blockquote></b>", parse_mode="HTML")
        return

    if user_id == DEVELOPER_ID:
        await update.message.reply_text(
            "<b> - اهلا بك،\n- انت في قسم لوحة المطور الخاصة بالبوت </b>",
            parse_mode="HTML",
            reply_markup=get_dev_keyboard()
        )
    
    await update.message.reply_text(
        f"<b>◄ اهـلا بك في سورس {BOT_NAME} المدفوع ►</b>",
        parse_mode="HTML",
        reply_markup=get_main_keyboard()
    )
    
    
ACTIVE_CLIENTS = {}
data = load_data()
async def track_messages(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    if str(user_id) in data.get("banned_users", []):
        return
    data["stats"]["total_messages"] = data["stats"].get("total_messages", 0) + 1
    save_data(data)


async def start_user_client(user_id, session_name):
    from telethon import TelegramClient, events
    from telethon.errors import FloodWaitError, UsernameInvalidError
    from telethon.tl.functions.account import CheckUsernameRequest
    from telethon.tl.functions.channels import UpdateUsernameRequest, CreateChannelRequest
    import json
    import os
    import time
    import asyncio
    import random
    import string
    
    client = TelegramClient(session_name, API_ID, API_HASH)
    ACTIVE_CLIENTS[user_id] = client
    
    client.hunting_active = False
    client.hunting_attempts = 0
    client.hunting_pattern = ""
    client.channel_id = None
    client.found_usernames = []
    
    data = {}
    if os.path.exists("user_times.json"):
        try:
            with open("user_times.json", "r") as f:
                data = json.load(f)
        except:
            data = {}
    
    data[str(user_id)] = time.time()
    with open("user_times.json", "w") as f:
        json.dump(data, f)
   
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.الاوامر'))
    async def list_commands(event):
        commands_text = ("""
**- قائمة اوامر السورس :

• `.صيد` - لصيد المعرفات .

• `.ايقاف الصيد` - لإيقاف الصيد .

• `.حالة الصيد` - لمعرفة حالة الصيد .

• `.فحص` - فحص المعرفات .

• `.نمط` - لإرسال نمط .

• `.شامل` - للفحص الشامل للنمط ( الأقوى ) .

• `.ايقاف` - لإيقاف الشامل .

• `.القوي` - لتفعيل الصيد والفحص بسرعة البرق الملقب بالقوي .

• `.توقيف القوي` - لإيقاف صيد القوي .

• `.شامل2` - لتشغيل الشامل2 يعمل فقط احرف.

• `.ايقاف2` - لإيقاف الشامل2 .

• `.بوت` - لفحص يوزرات بوتات .

• `.ايقاف البوت` - لإيقاف فحص اليوزرت بوتات .**
        """)
        await event.edit(commands_text)

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.فحص\s+(.*)'))
    async def check_user(event):
        username = event.pattern_match.group(1).strip()
        if username.startswith('@'):
            username = username[1:]
        
        await event.edit(f"**🔍 جاري فحص المعرف: `@{username}`...**")
        
        try:
            result = await event.client(CheckUsernameRequest(username=username))
            if result:
                await event.edit(f"**✅ المعرف `@{username}` متاح حالياً!**")
            else:
                await event.edit(f"**❌ المعرف `@{username}` غير متاح (محجوز).**")
        except FloodWaitError as e:
            await event.edit(f"**⚠️ تليجرام فرض حظر مؤقت. انتظر {e.seconds} ثانية.**")
        except UsernameInvalidError:
            await event.edit(f"**❌ المعرف `@{username}` غير صالح.**")
        except Exception as e:
            await event.edit(f"**❌ حدث خطأ أثناء الفحص: {str(e)}**")
            
            

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.شامل\s+(.*)'))
    async def check_pattern(event):
        pattern_input = event.pattern_match.group(1).strip()
        chat_id = event.chat_id
        stop_flags[chat_id] = False
        
        symbols = []
        for char in pattern_input:
            if not char.isalnum() and char != '_' and char not in symbols:
                symbols.append(char)
        
        if not symbols:
            await event.edit("**❌ خطأ: النمط لا يحتوي على رموز للتبديل!**")
            return
            
        chars = string.ascii_lowercase + string.digits
        msg = await event.edit(f"**⚡️ جارٍ الفحص الشامل للنمط: `{pattern_input}`**")
        
        first_s = symbols[0]
        other_s = symbols[1:]
        available = []
        count = 0
        
        for f_val in chars:
            if stop_flags.get(chat_id): break
            for others in itertools.product(chars, repeat=len(other_s)):
                if stop_flags.get(chat_id): break
                mapping = {first_s: f_val}
                mapping.update(dict(zip(other_s, others)))
                username = "".join([mapping.get(c, c) for c in pattern_input])
                
                if not (5 <= len(username) <= 32) or not re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', username) or '__' in username or username.endswith('_'):
                    continue
                
                count += 1
                try:
                    if await event.client(CheckUsernameRequest(username=username)):
                        available.append(username)
                        await event.respond(f"**✅ متاح: @{username}**")
                    if count % 10 == 0:
                        await msg.edit(f"**⚡️ جاري الفحص... تثبيت: {f_val} | فحصت: {count} | متاحات: {len(available)}**")
                    await asyncio.sleep(0.05) 
                except FloodWaitError as e:
                    await asyncio.sleep(e.seconds)
                except: continue
        await event.edit(f"**🏁 انتهى الفحص. المتاحات: {len(available)}**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ايقاف$'))
    async def stop_scan(event):
        chat_id = event.chat_id
        stop_flags[chat_id] = True
        await event.edit("**⏹️ تم الإيقاف فوراً.**")
        
        
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.شامل2\s+(.*)'))
    async def check_pattern2(event):
        pattern_input = event.pattern_match.group(1).strip()
        chat_id = event.chat_id
        
        if 'stop_flags2' not in globals():
            global stop_flags2
            stop_flags2 = {}
            
        stop_flags2[chat_id] = False
        
        symbols = []
        for char in pattern_input:
            if not char.isalnum() and char != '_' and char not in symbols:
                symbols.append(char)
        
        if not symbols:
            await event.edit("**❌ خطأ: النمط لا يحتوي على رموز للتبديل!**")
            return
            
        chars = string.ascii_lowercase
        msg = await event.edit(f"**⚡️ جارٍ الفحص الشامل للنمط: `{pattern_input}`**")
        
        first_s = symbols[0]
        other_s = symbols[1:]
        available = []
        count = 0
        
        for f_val in chars:
            if stop_flags2.get(chat_id): break
            for others in itertools.product(chars, repeat=len(other_s)):
                if stop_flags2.get(chat_id): break
                mapping = {first_s: f_val}
                mapping.update(dict(zip(other_s, others)))
                username = "".join([mapping.get(c, c) for c in pattern_input])
                
                if not (5 <= len(username) <= 32) or not re.match(r'^[a-zA-Z]+$', username):
                    continue
                
                count += 1
                try:
                    if await event.client(CheckUsernameRequest(username=username)):
                        available.append(username)
                        await event.respond(f"**✅ متاح: @{username}**")
                    if count % 10 == 0:
                        await msg.edit(f"**⚡️ جاري الفحص... تثبيت: {f_val} | فحصت: {count} | متاحات: {len(available)}**")
                    await asyncio.sleep(0.05) 
                except FloodWaitError as e:
                    await asyncio.sleep(e.seconds)
                except Exception:
                    continue

        await event.edit(f"**🏁 انتهى الفحص. المتاحات: {len(available)}**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ايقاف2$'))
    async def stop_scan2(event):
        chat_id = event.chat_id
        if 'stop_flags2' not in globals():
            global stop_flags2
            stop_flags2 = {}
        stop_flags2[chat_id] = True
        await event.edit("**⏹️ تم الإيقاف فوراً.**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.القوي\s+(.*)'))
    async def alqawi_hunter(event):
        pattern_input = event.pattern_match.group(1).strip()
        chat_id = event.chat_id
        hunter_flags[chat_id] = True
        
        symbols = []
        for char in pattern_input:
            if not char.isalnum() and char != '_' and char not in symbols:
                symbols.append(char)
                
        if not symbols:
            await event.edit("**⚠️ النمط المدخل لا يحتوي على رموز قابلة للاستبدال!**")
            return
        
        chars = string.ascii_lowercase + string.digits
        first_s = symbols[0]
        other_s = symbols[1:] if len(symbols) > 1 else []
        msg = await event.edit(f"**🔍 تفعيل الفحص القوي...**")
        
        count = 0
        available_users = []
        
        for f_val in chars:
            if not hunter_flags.get(chat_id): break
            
            for others in itertools.product(chars, repeat=len(other_s)):
                if not hunter_flags.get(chat_id): break
                
                mapping = {first_s: f_val}
                if other_s:
                    mapping.update(dict(zip(other_s, others)))
                    
                username = "".join([mapping.get(c, c) for c in pattern_input])
                
                if not (5 <= len(username) <= 32) or not re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', username) or '__' in username or username.endswith('_'):
                    continue
                    
                count += 1
                try:
                    is_available = await event.client(CheckUsernameRequest(username=username))
                    if is_available:
                        available_users.append(username)
                        await event.respond(f"**✅ يوزر متاح: @{username}**")
                    
                    if count % 10 == 0:
                        await msg.edit(f"**🔍 الفحص شغال | تثبيت: {f_val} | فحصت: {count} | المتاح: {len(available_users)}**")
                    
                    await asyncio.sleep(0.05)
                    
                except FloodWaitError as e:
                    await asyncio.sleep(e.seconds)
                except Exception:
                    continue
                    
        await event.edit(f"**🏁 انتهى الفحص. إجمالي المتاح: {len(available_users)}**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.توقيف القوي$'))
    async def stop_hunter(event):
        chat_id = event.chat_id
        hunter_flags[chat_id] = False
        await event.edit("**⏹️ تم إيقاف الفحص.**")
        
        
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.بوت\s+(.*)'))
    async def bot_hunter(event):
        pattern_input = event.pattern_match.group(1).strip()
        chat_id = event.chat_id
        
        if 'bot_hunter_flags' not in globals():
            global bot_hunter_flags
            bot_hunter_flags = {}
            
        bot_hunter_flags[chat_id] = True
        
        symbols = []
        for char in pattern_input:
            if not char.isalnum() and char != '_' and char not in symbols:
                symbols.append(char)
                
        if not symbols:
            await event.edit("**⚠️ النمط المدخل لا يحتوي على رموز قابلة للاستبدال!**")
            return
        
        chars = string.ascii_lowercase + string.digits
        first_s = symbols[0]
        other_s = symbols[1:] if len(symbols) > 1 else []
        msg = await event.edit(f"**🤖 تفعيل فحص البوتات...**")
        
        count = 0
        available_users = []
        
        for f_val in chars:
            if not bot_hunter_flags.get(chat_id): break
            
            product_iter = itertools.product(chars, repeat=len(other_s)) if other_s else [()]
            
            for others in product_iter:
                if not bot_hunter_flags.get(chat_id): break
                
                mapping = {first_s: f_val}
                if other_s:
                    mapping.update(dict(zip(other_s, others)))
                    
                username = "".join([mapping.get(c, c) for c in pattern_input])
                
                if not (5 <= len(username) <= 32) or not re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', username) or '__' in username or username.endswith('_'):
                    continue
                    
                count += 1
                try:
                    is_available = await event.client(CheckUsernameRequest(username=username))
                    if is_available:
                        available_users.append(username)
                        await event.respond(f"**✅ يوزر متاح: @{username}**")
                    
                    if count % 10 == 0:
                        await msg.edit(f"**🤖 فحص البوتات شغال | تثبيت: {f_val} | فحصت: {count} | المتاح: {len(available_users)}**")
                    
                    await asyncio.sleep(0.0)
                    
                except FloodWaitError as e:
                    await asyncio.sleep(e.seconds)
                except Exception:
                    continue
                    
        await event.edit(f"**🏁 انتهى فحص البوتات. إجمالي المتاح: {len(available_users)}**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.توقيف البوت$'))
    async def stop_bot_hunter(event):
        chat_id = event.chat_id
        if 'bot_hunter_flags' not in globals():
            global bot_hunter_flags
            bot_hunter_flags = {}
        bot_hunter_flags[chat_id] = False
        await event.edit("**⏹️ تم إيقاف فحص البوتات.**")


            
    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.نمط\s+(.*)'))
    async def pattern_check(event):
        import string
        import asyncio
        from telethon.tl.functions.account import CheckUsernameRequest
        from telethon.errors import FloodWaitError

        pattern_input = event.pattern_match.group(1).strip()
        if pattern_input.startswith('@'):
            pattern_input = pattern_input[1:]
        
        if '$' not in pattern_input:
            await event.edit("**❌ يجب أن يحتوي النمط على علامة `$` ليتم التوليد (مثال: .نمط $pxxp)**")
            return
            
        await event.edit(f"**🔍 جاري فحص النمط `@{pattern_input}` وتوليد القائمة...**")
        
        chars = string.ascii_lowercase + string.digits
        results = []
        
        for char in chars:
            current_username = pattern_input.replace('$', char)
            try:
                is_available = await event.client(CheckUsernameRequest(username=current_username))
                if is_available:
                    results.append(f"**{current_username}** متاح ✔️")
                else:
                    results.append(f"**{current_username}** غير متاح ❌")
            except FloodWaitError as e:
                results.append(f"**{current_username}** انتظار {e.seconds} ثانية ⚠️")
                await asyncio.sleep(e.seconds)
            except Exception:
                results.append(f"**{current_username}** غير متاح ❌")
            
            await asyncio.sleep(0.03)
        
        report = f"**📊 تقرير فحص النمط `@{pattern_input}` :**\n\n" + "\n".join(results)
        await event.edit(report)


    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.صيد\s+(.*)'))
    async def start_hunting(event):
        import asyncio, random, string
        from telethon.tl.functions.channels import CreateChannelRequest, UpdateUsernameRequest
        from telethon.tl.functions.account import CheckUsernameRequest
        from telethon.errors import FloodWaitError

        if getattr(event.client, 'hunting_active', False):
            await event.edit("**⚠️ الصيد يعمل بالفعل حالياً!**")
            return
            
        pattern = event.pattern_match.group(1).strip()
        if pattern.startswith('@'):
            pattern = pattern[1:]
            
        if '$' not in pattern:
            await event.edit("**❌ يجب أن يحتوي النمط على علامة `$` مثل: `.صيد $ppssp`**")
            return

        await event.edit("**⚙️ جاري تشغيل السورس وتهيئة نظام الحجز السريع...**")
        event.client.channel_id = event.chat_id
        event.client.hunting_active = True
        event.client.hunting_attempts = 0
        
        await event.edit(f"**🚀 تم بدء الصيد المستمر على النمط: `@{pattern}`\nملاحظة: جميع علامات `$` ستكون حرفاً واحداً (a-z) متطابق.**")
        
        while event.client.hunting_active:
            chosen_char = random.choice(string.ascii_lowercase)
            
            current_username = ""
            for char in pattern:
                if char == '$':
                    current_username += chosen_char
                else:
                    current_username += char
            
            event.client.hunting_attempts += 1
            
            try:
                is_available = await event.client(CheckUsernameRequest(username=current_username))
                
                if is_available:
                    try:
                        created_channel = await event.client(CreateChannelRequest(
                            title=current_username, 
                            about="- @l_3b0d"
                        ))
                        channel_peer = created_channel.chats[0]
                        await event.client(UpdateUsernameRequest(channel=channel_peer, username=current_username))
                        await event.client.send_message(event.client.channel_id, f"**✅ تم صيد اليوزر: @{current_username}**")
                    
                    except Exception as e:
                        err_msg = str(e).lower()
                        if "limit" in err_msg:
                            await event.client.send_message('me', f"⚠️ يوزر متاح ولكن الحساب ممتلئ: @{current_username}\nقم بحذف قناة قديمة.")
                        else:
                            await event.client.send_message(event.client.channel_id, f"**❌ فشل صيد @{current_username}**")
                
            except FloodWaitError as e:
                await asyncio.sleep(min(e.seconds, 0.2))
            except Exception:
                pass
            
            await asyncio.sleep(random.uniform(0.0, 0.003))

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.ايقاف\s+الصيد'))
    async def stop_hunting_cmd(event):
        if not getattr(event.client, 'hunting_active', False):
            await event.edit("**❌ الصيد متوقف بالفعل.**")
            return
        event.client.hunting_active = False
        await event.edit("**🛑 تم إيقاف عملية الصيد بنجاح.**")

    @client.on(events.NewMessage(outgoing=True, pattern=r'^\.حالة\s+الصيد'))
    async def check_status(event):
        is_active = getattr(event.client, 'hunting_active', False)
        attempts = getattr(event.client, 'hunting_attempts', 0)
        status_text = "فعالة ✅" if is_active else "متوقفة 🛑"
        await event.edit(f"**📊 حالة الصيد: {status_text}\n- عدد المحاولات: {attempts}**")


    await client.start()
    await client.run_until_disconnected()


async def restart_all_sessions():
    import json
    import os
    import asyncio
    
    data = {}
    if os.path.exists("accounts.json"):
        try:
            with open("accounts.json", "r") as f:
                data = json.load(f)
        except:
            data = {}

    for user_id, acc in data.get("accounts", {}).items():
        session_name = acc.get("session_name")

        if session_name and os.path.exists(f"{session_name}.session"):
            asyncio.create_task(
                start_user_client(int(user_id), session_name)
            )
            
import time
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import ContextTypes, ConversationHandler

async def inline_buttons_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    user_id = query.from_user.id
    
    if str(user_id) in data.get("banned_users", []):
        await query.answer("<b>- انت محظور من استخدام البوت .</b>", parse_mode="HTML", show_alert=True)
        return

    await query.answer()
    cmd = query.data

    if not data.get("settings", {}).get("status", True) and user_id != DEVELOPER_ID:
        await query.edit_message_text("<b><blockquote> 🛠 - البوت في وضع الصيانة الآن . </blockquote></b>", parse_mode="HTML")
        return

    if cmd == "to_main":
        context.user_data.clear()
        await query.edit_message_text(
            f"<b>◄ اهـلا بك في سورس {BOT_NAME} المدفوع ►</b>",
            parse_mode="HTML",
            reply_markup=get_main_keyboard()
        )
    elif cmd == "count_accs":
        accounts_data = data.get("accounts", {})
        count = len(accounts_data)
        text = f"<b>⌔ - عدد الحسابات المضافه: {count}\n⌔ - الثقة يم سورس {SOURCE_NAME} وبس .</b>"
        kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
        await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)
        
    elif cmd == "add_acc":
        user_id_str = str(user_id)
        vips_db = context.bot_data.get('vips', {})
        user_subscriptions = vips_db.get(user_id_str, [])
        
        current_time = time.time()
        total_allowed_accounts = 0
        active_subs = []
        
        for sub in user_subscriptions:
            if sub['expiry'] > current_time:
                total_allowed_accounts += int(sub['accounts'])
                active_subs.append(sub)
        
        if len(active_subs) != len(user_subscriptions):
            if active_subs:
                vips_db[user_id_str] = active_subs
            else:
                vips_db.pop(user_id_str, None)

        if total_allowed_accounts == 0:
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton("- المطور", url=f"https://t.me/{DEV_USER}")],
                [InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]
            ])
            await query.edit_message_text(
                "<b>- السورس مدفوع لا يمكنك إضافة حساب\n- راسل المطور من الزر بالاسفل لتفعيل الاشتراك.</b>",
                parse_mode="HTML",
                reply_markup=kb
            )
            return

        user_current_accounts = 0
        accounts_data = data.get("accounts", {})
        if user_id_str in accounts_data:
            if isinstance(accounts_data[user_id_str], list):
                user_current_accounts = len(accounts_data[user_id_str])
            else:
                user_current_accounts = 1
            
        if user_current_accounts >= total_allowed_accounts:
            kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
            await query.edit_message_text(
                f"<b>- لا يمكنك اضافة حساب جديد. لقد استهلكت جميع الحسابات المسموحة لك ({user_current_accounts}/{total_allowed_accounts}).</b>", 
                parse_mode="HTML", 
                reply_markup=kb
            )
            return

        kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
        await query.edit_message_text("<blockquote><b>أرسل الآن رقم هاتف الحساب مع الرمز الدولي :</b> </blockquote>", parse_mode="HTML", reply_markup=kb)
        return WAIT_PHONE
        
        
    elif cmd == "del_acc":
        str_uid = str(user_id)
        if str_uid not in data["accounts"]:
            kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
            await query.edit_message_text("<blockquote><b>- لا توجد حسابات لحذفها .</b></blockquote>", parse_mode="HTML", reply_markup=kb)
        else:
            acc = data["accounts"][str_uid]
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton(f"{acc['name']}", callback_data=f"confirm_del_{str_uid}")],
                [InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]
            ])
            await query.edit_message_text(
    "<blockquote><b>\n\n- اختر الحساب لحذفه:\n\n</b></blockquote>", 
    parse_mode="HTML", 
    reply_markup=kb
)


    elif cmd.startswith("confirm_del_"):
        target_uid = cmd.replace("confirm_del_", "")

        if target_uid not in data["accounts"]:
            await query.answer("- الحساب غير موجود.", show_alert=True)
            return

        acc = data["accounts"][target_uid]
        acc_name = acc["name"]
        session_name = acc["session_name"]
        session_file = f"{session_name}.session"

        try:
            client = ACTIVE_CLIENTS.get(int(target_uid))

            if client is None:
                client = TelegramClient(session_name, API_ID, API_HASH)
                await client.connect()

            if await client.is_user_authorized():
                await client.log_out()

            await client.disconnect()

        except Exception as e:
            print(f"Logout Error: {e}")

        finally:
            ACTIVE_CLIENTS.pop(int(target_uid), None)

        for file in (
            session_file,
            session_file + "-journal",
            session_file + "-wal",
            session_file + "-shm",
        ):
            try:
                if os.path.exists(file):
                    os.remove(file)
            except Exception as e:
                print(f"Delete Error ({file}): {e}")

        del data["accounts"][target_uid]
        save_data(data)

        kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])

        await query.edit_message_text(
            f"<b><blockquote>- الحساب: {acc_name}</blockquote>\n<blockquote>- تم حذفه من البوت بنجاح</blockquote></b>",
            parse_mode="HTML", reply_markup=kb
        )
        
    elif cmd == "extract_info":
        kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
        await query.edit_message_text("<b><blockquote>- ارسل الآن ايدي الحساب { ID } :</b></blockquote>", parse_mode="HTML", reply_markup=kb)
        return WAIT_EXTRACT

    elif cmd == "bot_guide":
        text = (
            f"<b>☭ • مرحباً بك في سورس {SOURCE_NAME} المدفوع {SOURCE_NAME_EN}\n"
            f"☭ • لتفعيل السورس المدفوع على حسابك بأمان، كل ما عليك هو إضافة حسابك عن طريق زر إضافة حساب\n"
            f"☭ • بعد إتمام التفعيل، توجه إلى أي محادثة خاصة بك أو مع البوت واكتب الأمر بالضبط: .الاوامر\n"
            f"☭ • ستظهر لك قائمة الأوامر الخاصة بالسورس المدفوع\n"
            f"☭ • لأي مشكلة أو استفسار لا تتردد في مراسلة المطور\n"
            f"☭ • ولا تنسى متابعة قناة تحديثات السورس</b>\n"
            f"<blockquote>- تحديثات البوت : @{SOURCE_USER}</blockquote>"
        )
        kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
        await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)

    if user_id == DEVELOPER_ID:
        if cmd == "to_dev":
            context.user_data.clear()
            await query.edit_message_text(
                "<b> - اهلا بك،\n- انت في قسم لوحة المطور الخاصة بالبوت </b>",
                parse_mode="HTML",
                reply_markup=get_dev_keyboard()
            )
        elif cmd == "dev_stats":
            check_day_reset()
            text = (
                "<b>- اهلا بك في قسم الاحصائيات 📊 .\n"
                "— — — — — — — — — —\n"
                f"• عدد اعضاء البوت : {len(data['users'])}\n"
                f"• عدد المستخدمين الجدد اليوم : {len(data['stats'].get('today_users', []))}\n"
                f"• عدد رسائل البوت : {data['stats'].get('total_messages', 0)} </b>"
            )
            kb = InlineKeyboardMarkup([[InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)
        elif cmd == "dev_settings":
            status_symbol = "√" if data["settings"].get("status", True) else "×"
            text = (
                "<b>- الاعدادات الخاصة بالبوت ⚙ .\n"
                "- √ ~ تعني مفعل\n"
                "- × ~ تعني معطل</b>"
            )
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton(f"حالة البوت : {status_symbol}", callback_data="toggle_status")],
                [InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]
            ])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)
        elif cmd == "toggle_status":
            data["settings"]["status"] = not data["settings"].get("status", True)
            save_data(data)
            status_symbol = "√" if data["settings"]["status"] else "×"
            text = (
                "<b>- الاعدادات الخاصة بالبوت ⚙ .\n"
                "- √ ~ تعني مفعل\n"
                "- × ~ تعني معطل</b>"
            )
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton(f"حالة البوت : {status_symbol}", callback_data="toggle_status")],
                [InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]
            ])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)
        elif cmd == "dev_bc":
            kb = InlineKeyboardMarkup([[InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]])
            await query.edit_message_text("<b> - أرسل الآن الرسالة وسأقوم باذاعتها فورًا : </b>", parse_mode="HTML", reply_markup=kb)
            return WAIT_BROADCAST
        elif cmd == "dev_force" or cmd == "BACK2":
            text = (
                "<b>- اهلا بك في قسم قنوات الاشتراك الاجباري .\n"
                "- اضغط على اسم القناة ليتم حذفها .\n"
                "- اضغط على ( ➕ ) لاضافه المزيد من القنوات .</b>"
            )
            buttons = []
            for idx, ch in enumerate(data.get("force_channels", [])):
                buttons.append([InlineKeyboardButton(ch["title"], callback_data=f"del_ch_{idx}", style="primary")])
            buttons.append([InlineKeyboardButton("➕", callback_data="add_force_ch", style="primary")])
            buttons.append([InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=InlineKeyboardMarkup(buttons))
        elif cmd == "add_force_ch":
            await query.edit_message_text("<b>- قم برفع البوت ادمن في قناتك ثم قم بأرسل توجيه من القناة الى البوت .</b>", parse_mode="HTML")
            return WAIT_FORCE_CHANNEL
        elif cmd.startswith("del_ch_"):
            idx = int(cmd.replace("del_ch_", ""))
            if 0 <= idx < len(data.get("force_channels", [])):
                data["force_channels"].pop(idx)
                save_data(data)
            text = (
                "<b>- اهلا بك في قسم قنوات الاشتراك الاجباري .\n"
                "- اضغط على اسم القناة ليتم حذفها .\n"
                "- اضغط على ( ➕ ) لاضافه المزيد من القنوات .</b>"
            )
            buttons = []
            for i, ch in enumerate(data.get("force_channels", [])):
                buttons.append([InlineKeyboardButton(ch["title"], callback_data=f"del_ch_{i}", style="primary")])
            buttons.append([InlineKeyboardButton("➕", callback_data="add_force_ch", style="primary")])
            buttons.append([InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=InlineKeyboardMarkup(buttons))
        elif cmd == "dev_backup":
            text = (
                "<b>- اهـلاً بك عزيزي في قسم النسخة الإحتياطية ⚠️\n"
                "— — — — — — — — — —\n"
                "~ من خلال هذا القسم يمكنك التحكم في النسخة الإحتياطية للبوت\n"
                "~ اختر ما تريده من الاسفل :</b>"
            )
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton("- رفع نسخة", callback_data="restore_backup", style="primary")],
                [InlineKeyboardButton("- النسخة الإحتياطية", callback_data="get_backup", style="primary")],
                [InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]
            ])
            await query.edit_message_text(text, parse_mode="HTML", reply_markup=kb)
        elif cmd == "restore_backup":
            await query.edit_message_text("ارسل آلان النسخة الاحتياطية للبوت ليتم رفعها")
            return WAIT_RESTORE_BACKUP
        elif cmd == "get_backup":
            if os.path.exists(DATA_FILE):
                await context.bot.send_document(chat_id=user_id, document=open(DATA_FILE, "rb"), filename="bot_data.json")
            else:
                await query.message.reply_text("لا توجد بيانات لتصديرها حالياً.")
        elif cmd == "dev_ban_section":
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton("- حظر مستخدم", callback_data="ban_user", style="danger")],
                [InlineKeyboardButton("- الغاء حظر", callback_data="unban_user", style="success")],
                [InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]
            ])
            await query.edit_message_text("- اختر ما تريده من الازرار :", reply_markup=kb)
        elif cmd == "ban_user":
            await query.edit_message_text("ارسل ايدي المستخدم ليتم حظره:")
            return WAIT_BAN
        elif cmd == "unban_user":
            await query.edit_message_text("ارسل ايدي المستخدم لفك الحظر:")
            return WAIT_UNBAN
            
        elif cmd == "vip":
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton("- مستخدمين الـ VIP", callback_data="vip_users", style="primary")],
                [InlineKeyboardButton("- اضف VIP", callback_data="add_vip", style="success"),
                 InlineKeyboardButton("- حذف VIP", callback_data="del_vip", style="danger")],
                [InlineKeyboardButton("رجوع - Back", callback_data="to_dev", style="danger")]
            ])
            text = "- اهلاً بك عزيزي المطور في قسم الـVIP\n-- -- -- -- -- -- \n- اختر ما تريده من الاسفل :"
            await query.edit_message_text(text, reply_markup=kb)

        elif cmd == "vip_users":
            import time
            vips_db = context.bot_data.get('vips', {})
            
            if not vips_db:
                text = "- لا يوجد مستخدمين VIP حالياً."
            else:
                text = "- مستخدمين الـ VIP هم :\n\n"
                current_time = time.time()
                
                for user_id, subscriptions in list(vips_db.items()):
                    for sub in subscriptions:
                        remaining_time = sub['expiry'] - current_time
                        
                        if remaining_time > 0:
                            days = int(remaining_time // 86400)
                            hours = int((remaining_time % 86400) // 3600)
                            minutes = int((remaining_time % 3600) // 60)
                            
                            text += f"- [{user_id}](tg://user?id={user_id}) - عدد الحسابات المسموح له : {sub['accounts']} - المتبقي {days} يوم • {hours} ساعة • {minutes} دقيقة •\n"
                        else:

                            subscriptions.remove(sub)
                    
                    if not subscriptions:
                        del vips_db[user_id]
            
            kb = InlineKeyboardMarkup([
                [InlineKeyboardButton("رجوع - Back", callback_data="dev_vip_section", style="danger")]
            ])
            await query.edit_message_text(text, reply_markup=kb, parse_mode="Markdown")

        elif cmd == "add_vip":
            await query.edit_message_text("- ارسل الآن ايدي المستخدم لإضافته الى VIP :")
            return WAIT_VIP_ID

        elif cmd == "del_vip":
            await query.edit_message_text("- ارسل ايدي المستخدم لحذفه من الـ VIP:")
            return WAIT_DEL_VIP
            


async def receive_vip_id(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.message.text.strip()
    context.user_data['temp_vip_id'] = user_id
    await update.message.reply_text("- ارسل الان عدد الحسابات المسموح له :")
    return WAIT_VIP_ACCOUNTS


async def receive_vip_accounts(update: Update, context: ContextTypes.DEFAULT_TYPE):
    accounts = update.message.text.strip()
    if not accounts.isdigit():
        await update.message.reply_text("- يرجى إرسال رقم صحيح لعدد الحسابات:")
        return WAIT_VIP_ACCOUNTS
        
    context.user_data['temp_vip_accounts'] = int(accounts)
    await update.message.reply_text("- ارسل عدد الايام المسموح له :")
    return WAIT_VIP_DAYS


async def receive_vip_days(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text_days = update.message.text.strip()
    if not text_days.isdigit():
        await update.message.reply_text("- يرجى إرسال رقم صحيح لعدد الأيام:")
        return WAIT_VIP_DAYS
        
    days = int(text_days)
    user_id = context.user_data['temp_vip_id']
    accounts = context.user_data['temp_vip_accounts']
    
    expiry_time = time.time() + (days * 86400)
    
    if 'vips' not in context.bot_data:
        context.bot_data['vips'] = {}
        
    if user_id not in context.bot_data['vips']:
        context.bot_data['vips'][user_id] = []
        
    context.bot_data['vips'][user_id].append({
        'accounts': accounts,
        'expiry': expiry_time
    })
    
    await update.message.reply_text(f"تم تفعيل الـ VIP للمستخدم بنجاح.\n- الايدي: {user_id}\n- عدد الحسابات: {accounts}\n- المدة: {days} أيام.")
    
    try:
        await context.bot.send_message(
            chat_id=int(user_id) if user_id.isdigit() else user_id,
            text=f"مبروك! تم تفعيل اشتراك الـ VIP الخاص بك.\n\n"
                 f"✅ تفاصيل الاشتراك:\n"
                 f"- عدد الحسابات المتاحة: {accounts}\n"
                 f"- المدة: {days} أيام\n"
                 f"شكراً لاستخدامك خدماتنا!"
        )
    except Exception:
        await update.message.reply_text("⚠️ - تنبيه: لم أتمكن من مراسلة المستخدم (ربما لم يضغط 'بدء/Start' للبوت).")
    
    context.user_data.pop('temp_vip_id', None)
    context.user_data.pop('temp_vip_accounts', None)
    
    return ConversationHandler.END


async def delete_vip(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.message.text.strip()
    vips_db = context.bot_data.get('vips', {})
    
    if user_id in vips_db:
        del vips_db[user_id]
        await update.message.reply_text(f"- تم حذف المستخدم {user_id} من الـ VIP بنجاح.")
    else:
        await update.message.reply_text("- هذا الايدي غير موجود في قائمة الـ VIP.")
        
    return ConversationHandler.END


async def auto_check_expired_vips(context):
    while True:
        vips_db = context.bot_data.get('vips', {})
        current_time = time.time()
        
        for user_id, subscriptions in list(vips_db.items()):
            for sub in subscriptions[:]: 
                if current_time >= sub['expiry']:
                    subscriptions.remove(sub)
                    
            if not subscriptions:
                del vips_db[user_id]
                
        await asyncio.sleep(60) 



import asyncio
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import ContextTypes, ConversationHandler
from telethon import TelegramClient
from telethon.errors import SessionPasswordNeededError, PhoneCodeInvalidError, PasswordHashInvalidError


async def process_phone(update: Update, context: ContextTypes.DEFAULT_TYPE):
    phone = update.message.text.strip().replace(" ", "")
    user_id = update.effective_user.id
    session_name = f"session_{user_id}"
    
    client = TelegramClient(session_name, API_ID, API_HASH)
    await client.connect()
    try:
        send_code_req = await client.send_code_request(phone)
        context.user_data["phone"] = phone
        context.user_data["phone_code_hash"] = send_code_req.phone_code_hash
        context.user_data["client"] = client
        await update.message.reply_text("- ارسل الآن كود التحقق، مثل : 1 2 3 4 5 .")
        return WAIT_CODE
    except Exception as e:
        await client.disconnect()
        await update.message.reply_text(f"حدث خطأ أثناء إرسال الكود. يرجى المحاولة لاحقاً.")
        return ConversationHandler.END

async def process_code(update: Update, context: ContextTypes.DEFAULT_TYPE):
    code = update.message.text.strip().replace(" ", "")
    client = context.user_data.get("client")
    phone = context.user_data.get("phone")
    phone_code_hash = context.user_data.get("phone_code_hash")
    user_id = update.effective_user.id

    try:
        await client.sign_in(phone=phone, code=code, phone_code_hash=phone_code_hash)
        await complete_sign_in(update, context, client, user_id, phone)
        return ConversationHandler.END
    except SessionPasswordNeededError:
        await update.message.reply_text("- الحساب محمي بالتحقق بخطوتين. أرسل كلمة المرور:")
        return WAIT_PASSWORD
    except PhoneCodeInvalidError:
        await update.message.reply_text("الكود خاطئ، يرجى إعادة المحاولة وارسال الكود الصحيح:")
        return WAIT_CODE
    except Exception as e:
        if client:
            await client.disconnect()
        await update.message.reply_text("حدث خطأ غير متوقع أثناء تسجيل الدخول. يرجى المحاولة من جديد.")
        return ConversationHandler.END

async def process_password(update: Update, context: ContextTypes.DEFAULT_TYPE):
    password = update.message.text.strip()
    client = context.user_data.get("client")
    phone = context.user_data.get("phone")
    user_id = update.effective_user.id

    try:
        await client.sign_in(password=password)
        await complete_sign_in(update, context, client, user_id, phone)
        return ConversationHandler.END
    except PasswordHashInvalidError:
        await update.message.reply_text("كلمة المرور خاطئة. أرسل كلمة المرور الصحيحة:")
        return WAIT_PASSWORD
    except Exception as e:
        if client:
            await client.disconnect()
        await update.message.reply_text("حدث خطأ غير متوقع أثناء إدخال كلمة المرور. أعد المحاولة.")
        return ConversationHandler.END

async def complete_sign_in(update, context, client, user_id, phone):
    me = await client.get_me()
    name = f"{me.first_name or ''} {me.last_name or ''}".strip() or "Telegram User"
    username = me.username
    session_name = f"session_{user_id}"
    
    data["accounts"][str(user_id)] = {
        "phone": phone,
        "session_name": session_name,
        "name": name,
        "username": username
    }
    save_data(data)
    await client.disconnect()
    
    asyncio.create_task(start_user_client(user_id, session_name))
    
    kb = InlineKeyboardMarkup([[InlineKeyboardButton("- رجوع - Back", callback_data="to_main", style="danger")]])
    
    await update.message.reply_text(
        f"<blockquote><b>- تم تنصيب سورس {SOURCE_NAME} بنجاح!</b>\n"
        f"<b>- أرسل <code>.الاوامر</code> لعرض قائمة الأوامر.</b></blockquote>",
        parse_mode="HTML", reply_markup=kb
    )

from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ContextTypes, ConversationHandler

async def process_extract(update: Update, context: ContextTypes.DEFAULT_TYPE):
    target = update.message.text.strip()

    try:
        if not target.isdigit():
            await update.message.reply_text("ارسل ايدي صحيح فقط (Numbers).")
            return ConversationHandler.END

        uid = int(target)

        full_name = "غير متوفر بدون تسجيل دخول"
        username = "غير متوفر بدون تسجيل دخول"

        creation_date = get_creation_date(uid)

        text = (
            "- تم استخراج معلومات الحساب بنجاح ✅\n"
            "— — — — — — — — —\n"
            f"• الآيدي : {uid}\n"
            f"• الاسم : {full_name}\n"
            f"• اليوزر : {username}\n"
            f"• تاريخ الإنشاء : {creation_date}\n"
            "— — — — — — — — —\n"
            f"- تحديثات السورس : @{SOURCE_USER}"
        )

        kb = InlineKeyboardMarkup([
            [InlineKeyboardButton("- رجوع - Back", callback_data="to_main")]
        ])

        await update.message.reply_text(
            text,
            reply_markup=kb
        )

    except Exception as e:
        await update.message.reply_text("حدث خطأ أثناء جلب المعلومات.")

    return ConversationHandler.END

async def process_broadcast(update: Update, context: ContextTypes.DEFAULT_TYPE):
    msg = update.message
    count = 0
    for u in data.get("users", []):
        try:
            await context.bot.copy_message(chat_id=u, from_chat_id=msg.chat_id, message_id=msg.message_id)
            count += 1
        except:
            pass
    await update.message.reply_text(f"تمت الإذاعة بنجاح إلى {count} مستخدم.")
    return ConversationHandler.END

import re
from telegram import (
    Update,
    InlineKeyboardMarkup,
    InlineKeyboardButton,
)
import re
from telegram import (
    Update,
    InlineKeyboardMarkup,
    InlineKeyboardButton,
    MessageOriginChannel,
)
from telegram.ext import ContextTypes, ConversationHandler


async def process_force_channel(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message:
        return ConversationHandler.END

    text = (update.message.text or "").strip()
    chat = None

    if (
        getattr(update.message, "forward_origin", None)
        and isinstance(update.message.forward_origin, MessageOriginChannel)
    ):
        chat = update.message.forward_origin.chat

    if chat is None:
        match = re.search(
            r"(?:https?://)?(?:t(?:elegram)?\.me/|@)([A-Za-z0-9_]{5,32})",
            text,
            re.IGNORECASE,
        )

        if not match:
            await update.message.reply_text(
                "أرسل أحد الخيارات التالية:\n\n"
                "• @username\n"
                "• https://t.me/username\n"
                "• أو قم بتوجيه رسالة من القناة."
            )
            return ConversationHandler.END

        username = match.group(1)

        try:
            chat = await context.bot.get_chat(f"@{username}")
        except Exception:
            await update.message.reply_text(
                "❌ تعذر العثور على القناة.\n"
                "تأكد من صحة اليوزر وأن البوت موجود داخل القناة."
            )
            return ConversationHandler.END

    if chat.type != "channel":
        await update.message.reply_text("❌ المعرف الذي أرسلته ليس قناة.")
        return ConversationHandler.END

    try:
        member = await context.bot.get_chat_member(chat.id, context.bot.id)

        if member.status not in ("administrator", "creator"):
            await update.message.reply_text(
                "❌ يجب رفع البوت مشرفاً في القناة أولاً."
            )
            return ConversationHandler.END

    except Exception:
        await update.message.reply_text(
            "❌ تعذر الوصول للقناة.\n"
            "تأكد أن البوت موجود داخلها ومشرف."
        )
        return ConversationHandler.END

    try:
        invite = await context.bot.create_chat_invite_link(
            chat_id=chat.id,
            creates_join_request=False,
        )
        invite_link = invite.invite_link

    except Exception as e:
        await update.message.reply_text(
            f"❌ تعذر إنشاء رابط الدعوة.\n\n{e}"
        )
        return ConversationHandler.END

    if "force_channels" not in data:
        data["force_channels"] = []

    for c in data["force_channels"]:
        if c["id"] == chat.id:
            await update.message.reply_text("- ⚠️ هذه القناة مضافة مسبقاً.")
            return ConversationHandler.END

    data["force_channels"].append(
        {
            "id": chat.id,
            "title": chat.title,
            "username": chat.username,
            "invite_link": invite_link,
        }
    )

    save_data(data)

    keyboard = InlineKeyboardMarkup(
        [
            [
                InlineKeyboardButton(
                    "رجوع - Back",
                    callback_data="BACK2", style="danger",
                )
            ]
        ]
    )

    await update.message.reply_text(
        f"✅ تمت إضافة القناة بنجاح.\n\n"
        f"📢 {chat.title}\n"
        f"🆔 <code>{chat.id}</code>",
        parse_mode="HTML",
        reply_markup=keyboard,
    )

    return ConversationHandler.END

async def process_restore_backup(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message.document:
        await update.message.reply_text("الرجاء إرسال ملف الـ JSON المنسوخ احتياطياً.")
        return ConversationHandler.END
    
    doc = update.message.document
    if not doc.file_name.endswith(".json"):
        await update.message.reply_text("الملف المرفوع ليس بصيغة JSON.")
        return ConversationHandler.END

    try:
        file = await context.bot.get_file(doc.file_id)
        await file.download_to_drive(DATA_FILE)
        global data
        data = load_data()
        await update.message.reply_text("تم استعادة النسخة الاحتياطية وتحديث بيانات البوت بنجاح!")
    except Exception as e:
        await update.message.reply_text("حدث خطأ أثناء استعادة النسخة الاحتياطية.")
    return ConversationHandler.END

async def process_ban(update: Update, context: ContextTypes.DEFAULT_TYPE):
    target_id = update.message.text.strip()
    if target_id not in data.get("banned_users", []):
        if "banned_users" not in data:
            data["banned_users"] = []
        data["banned_users"].append(target_id)
        save_data(data)
        await update.message.reply_text(f"تم حظر المستخدم {target_id} بنجاح.")
    else:
        await update.message.reply_text("المستخدم محظور بالفعل.")
    return ConversationHandler.END

async def process_unban(update: Update, context: ContextTypes.DEFAULT_TYPE):
    target_id = update.message.text.strip()
    if target_id in data.get("banned_users", []):
        data["banned_users"].remove(target_id)
        save_data(data)
        await update.message.reply_text(f"تم إلغاء حظر المستخدم {target_id} بنجاح.")
    else:
        await update.message.reply_text("المستخدم ليس محظوراً في البوت.")
    return ConversationHandler.END

async def on_post_init(application: Application):
    await restart_all_sessions()

def main():
    application = Application.builder().token(BOT_TOKEN).post_init(on_post_init).build()

    add_acc_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^add_acc$")],
        states={
            WAIT_PHONE: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_phone)],
            WAIT_CODE: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_code)],
            WAIT_PASSWORD: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_password)],
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_main$")],
        per_message=False
    )
    
    extract_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^extract_info$")],
        states={
            WAIT_EXTRACT: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_extract)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_main$")],
        per_message=False
    )

    bc_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^dev_bc$")],
        states={
            WAIT_BROADCAST: [MessageHandler(filters.ALL & ~filters.COMMAND, process_broadcast)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )

    force_ch_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^add_force_ch$")],
        states={
            WAIT_FORCE_CHANNEL: [MessageHandler(filters.FORWARDED, process_force_channel)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^BACK2$")],
        per_message=False
    )

    restore_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^restore_backup$")],
        states={
            WAIT_RESTORE_BACKUP: [MessageHandler(filters.Document.ALL, process_restore_backup)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )

    ban_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^ban_user$")],
        states={
            WAIT_BAN: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_ban)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )

    unban_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^unban_user$")],
        states={
            WAIT_UNBAN: [MessageHandler(filters.TEXT & ~filters.COMMAND, process_unban)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )

    
    vip_add_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^add_vip$")],
        states={
            WAIT_VIP_ID: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_vip_id)],
            WAIT_VIP_ACCOUNTS: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_vip_accounts)],
            WAIT_VIP_DAYS: [MessageHandler(filters.TEXT & ~filters.COMMAND, receive_vip_days)],
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )

    vip_del_conv = ConversationHandler(
        entry_points=[CallbackQueryHandler(inline_buttons_handler, pattern="^del_vip$")],
        states={
            WAIT_DEL_VIP: [MessageHandler(filters.TEXT & ~filters.COMMAND, delete_vip)]
        },
        fallbacks=[CallbackQueryHandler(inline_buttons_handler, pattern="^to_dev$")],
        per_message=False
    )
    
    application.add_handler(CommandHandler("start", start))
    application.add_handler(add_acc_conv)
    application.add_handler(extract_conv)
    application.add_handler(bc_conv)
    application.add_handler(force_ch_conv)
    application.add_handler(restore_conv)
    application.add_handler(ban_conv)
    application.add_handler(unban_conv)
    
    application.add_handler(vip_add_conv)
    application.add_handler(vip_del_conv)
    
    application.add_handler(CallbackQueryHandler(inline_buttons_handler))
    application.add_handler(MessageHandler(filters.ALL, track_messages))

    application.run_polling()
    
    
if __name__ == "__main__":
    print(f"\033[31m" + """
─────▄████▀█▄
───▄█████████████████▄
─▄█████.▼.▼.▼.▼.▼.▼▼▼▼
███████
████████▄▄▲.▲▲▲▲▲▲▲
████████████████████▀▀
""" + "\033[0m" + f"""
• 𝖲𝖮𝖴𝖱𝖢𝖧 𝖩𝖠𝖢𝖪 𝖨𝖲 𝖴𝖯 𝖠𝖭𝖣 𝖱𝖴𝖭𝖭𝖨𝖭𝖦 ...
• 𝖲𝖮𝖴𝖱𝖢𝖤 𝖢𝖧𝖠𝖭𝖭𝖤𝖫 ~ @{SOURCE_USER} .

• 𝖣𝖤𝖵𝖤𝖫𝖮𝖯𝖤𝖱 ~ @{DEV_USER} .
""")
    main()
