import os
import json
import time
import telebot
import threading
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
from datetime import datetime, timedelta
from functools import wraps

TOKEN = "8055928224:AAEYLcoEnmfA-6iAJkcuyuYiHuBKG8iVmQs"
DATA_FILE = "users.json"
ADMIN_CHANNEL_ID = -1003512076663

DEVELOPER_IDS = [6246579902, 7923164784]
CHANNEL_ID = "-1003006093715"
CHANNEL_USERNAME = "t.me/SourceKodo"
CHANNEL2_ID = "-1001762149483"
CHANNEL2_USERNAME = "t.me/K_K_Es"
DEVELOPER_URL = "https://t.me/Evan1_a  "

bot = telebot.TeleBot(TOKEN)

sending_states = {}
pending_hosting_details = {}
private_message_states = {}  # حالة جديدة للرسائل الخاصة
daily_gift_data = {}

SUBSCRIBERS_PER_PAGE = 15

def load_data():
    if not os.path.exists(DATA_FILE):
        return {}
    try:
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    except:
        return {}

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

def ensure_user(data, user_id, name, username=None):
    uid = str(user_id)
    if uid not in data:
        data[uid] = {
            "points": 0,
            "referred_by": None,
            "name": name or "",
            "username": username or "",
            "received_hosting": False,
            "last_daily_gift": None
        }
    else:
        data[uid]["name"] = name or data[uid].get("name", "")
        if username:
            data[uid]["username"] = username
        if "received_hosting" not in data[uid]:
            data[uid]["received_hosting"] = False
        if "last_daily_gift" not in data[uid]:
            data[uid]["last_daily_gift"] = None
    return data

def developer_only(func):
    @wraps(func)
    def wrapped(message, *args, **kwargs):
        if message.from_user.id not in DEVELOPER_IDS:
            bot.reply_to(message, "⊱ *عذراً، هذا الأمر مخصص للمطورين فقط*.", parse_mode='Markdown')
            return
        return func(message, *args, **kwargs)
    return wrapped

def developer_callback_only(func):
    @wraps(func)
    def wrapped(call, *args, **kwargs):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        return func(call, *args, **kwargs)
    return wrapped

def _is_member_of(chat_identifier, user_id):
    try:
        member = bot.get_chat_member(chat_identifier, user_id)
        return member.status in ['member', 'administrator', 'creator']
    except Exception:
        return False

def subscription_status(user_id):
    status1 = _is_member_of(CHANNEL_ID, user_id)
    status2 = _is_member_of(CHANNEL2_ID, user_id)
    return {'ch1': status1, 'ch2': status2}

def check_subscription(user_id):
    s = subscription_status(user_id)
    return s['ch1'] and s['ch2']

def escape_underscore_for_markdown(text: str) -> str:
    if not isinstance(text, str):
        return text
    return text.replace('_', '\\_')

def subscription_required(func):
    @wraps(func)
    def wrapped(message, *args, **kwargs):
        if message.from_user.id in DEVELOPER_IDS:
            return func(message, *args, **kwargs)
        status = subscription_status(message.from_user.id)
        if not status['ch1']:
            channel_link = CHANNEL_USERNAME if CHANNEL_USERNAME.startswith("http") else f"https://{CHANNEL_USERNAME}"
            channel_link_md = escape_underscore_for_markdown(channel_link)
            bot.send_message(message.chat.id, f"⊱ *يجب عليك الاشتراك في القناة قبل استخدام البوت*:\n{channel_link_md}", parse_mode='Markdown')
            return
        if not status['ch2']:
            channel2_link = CHANNEL2_USERNAME if CHANNEL2_USERNAME.startswith("http") else f"https://{CHANNEL2_USERNAME}"
            channel2_link_md = escape_underscore_for_markdown(channel2_link)
            bot.send_message(message.chat.id, f"⊱ *مبروك! تم التحقق من اشتراكك في القناة الأولى.*\n⊱ *الخطوة التالية: الاشتراك في القناة الثانية قبل استخدام البوت*:\n{channel2_link_md}", parse_mode='Markdown')
            return
        return func(message, *args, **kwargs)
    return wrapped

def callback_subscription_required(func):
    @wraps(func)
    def wrapped(call, *args, **kwargs):
        if call.from_user.id in DEVELOPER_IDS:
            return func(call, *args, **kwargs)
        status = subscription_status(call.from_user.id)
        if not status['ch1']:
            channel_link = CHANNEL_USERNAME if CHANNEL_USERNAME.startswith("http") else f"https://{CHANNEL_USERNAME}"
            channel_link_md = escape_underscore_for_markdown(channel_link)
            bot.send_message(call.message.chat.id, f"⊱ *يجب عليك الاشتراك في القناة قبل استخدام البوت*:\n{channel_link_md}", parse_mode='Markdown')
            return
        if not status['ch2']:
            channel2_link = CHANNEL2_USERNAME if CHANNEL2_USERNAME.startswith("http") else f"https://{CHANNEL2_USERNAME}"
            channel2_link_md = escape_underscore_for_markdown(channel2_link)
            bot.send_message(call.message.chat.id, f"⊱ *مبروك! تم التحقق من اشتراكك في القناة الأولى.*\n⊱ *الخطوة التالية: الاشتراك في القناة الثانية قبل استخدام البوت*:\n{channel2_link_md}", parse_mode='Markdown')
            return
        return func(call, *args, **kwargs)
    return wrapped

def build_main_menu(points):
    kb = InlineKeyboardMarkup(row_width=2)
    kb.row(InlineKeyboardButton(text=f"نقاطي: {points}", callback_data="points"))
    kb.row(
        InlineKeyboardButton(text="استضافة مجانية 🎗️", callback_data="free_hosting"),
        InlineKeyboardButton(text="استضافة مدفوعة 💸", callback_data="paid_hosting")
    )
    kb.row(
        InlineKeyboardButton(text="خادم  VPS مجاني 🎗️", callback_data="free_vps"),
        InlineKeyboardButton(text="خادم VPS مدفوع 💸", callback_data="paid_vps")
    )
    kb.row(InlineKeyboardButton(text="تجميع نقاط 💎", callback_data="collect_points"))
    kb.row(
        InlineKeyboardButton(text="هدية يومية 🎁", callback_data="daily_gift"),
        InlineKeyboardButton(text="التعليمات 📍", callback_data="help_menu")
    )
    kb.row(
        InlineKeyboardButton(text="سورس Kodo", url="https://t.me/SourceKodo"),
        InlineKeyboardButton(text="الدعم الفني", url="https://t.me/helpKodoBot?start=help")
    )
    return kb

def build_country_selection(service_type):
    kb = InlineKeyboardMarkup(row_width=2)
    kb.row(
        InlineKeyboardButton(text="امستردام 🇳🇱", callback_data=f"country_{service_type}_amsterdam"),
        InlineKeyboardButton(text="استراليا 🇦🇺", callback_data=f"country_{service_type}_australia")
    )
    kb.row(
        InlineKeyboardButton(text="امريكا 🇺🇸", callback_data=f"country_{service_type}_america"),
        InlineKeyboardButton(text="المانيا 🇩🇪", callback_data=f"country_{service_type}_germany")
    )
    kb.row(
        InlineKeyboardButton(text="نيجيريا 🇳🇬", callback_data=f"country_{service_type}_nigeria"),
        InlineKeyboardButton(text="روسيا 🇷🇺", callback_data=f"country_{service_type}_russia")
    )
    kb.row(
        InlineKeyboardButton(text="سنغافورة 🇸🇬", callback_data=f"country_{service_type}_singapore"),
        InlineKeyboardButton(text="فرنسا 🇫🇷", callback_data=f"country_{service_type}_france")
    )
    kb.row(
        InlineKeyboardButton(text="كندا 🇨🇦", callback_data=f"country_{service_type}_canada"),
        InlineKeyboardButton(text="فنلندا 🇫🇮", callback_data=f"country_{service_type}_finland")
    )
    kb.row(InlineKeyboardButton(text="رجوع", callback_data="back_to_menu"))
    return kb

def build_collect_points_menu():
    kb = InlineKeyboardMarkup(row_width=1)
    kb.row(InlineKeyboardButton(text="انشاء رابط احالة", callback_data="create_referral"))
    kb.row(InlineKeyboardButton(text="رجوع", callback_data="back_to_menu"))
    return kb

def build_back_button():
    kb = InlineKeyboardMarkup()
    kb.row(InlineKeyboardButton(text="رجوع", callback_data="back_to_menu"))
    return kb

def build_paid_vps_menu(country_name, country_code):
    kb = InlineKeyboardMarkup(row_width=2)
    
    kb.row(
        InlineKeyboardButton(text="VPS 1", callback_data=f"paid_vps_{country_code}_1"),
        InlineKeyboardButton(text="Ram: 8 | vCPU: 4 | Pr: 15$", callback_data=f"paid_vps_{country_code}_1")
    )
    
    kb.row(
        InlineKeyboardButton(text="VPS 2", callback_data=f"paid_vps_{country_code}_2"),
        InlineKeyboardButton(text="Ram: 12 | vCPU: 6 | Pr: 20$", callback_data=f"paid_vps_{country_code}_2")
    )
    
    kb.row(
        InlineKeyboardButton(text="VPS 3", callback_data=f"paid_vps_{country_code}_3"),
        InlineKeyboardButton(text="Ram: 24 | vCPU: 8 | Pr: 30$", callback_data=f"paid_vps_{country_code}_3")
    )
    
    kb.row(
        InlineKeyboardButton(text="VPS 4", callback_data=f"paid_vps_{country_code}_4"),
        InlineKeyboardButton(text="Ram: 48 | vCPU: 12 | Pr: 50$", callback_data=f"paid_vps_{country_code}_4")
    )
    
    kb.row(InlineKeyboardButton(text="رجوع", callback_data="back_to_menu"))
    return kb

def dev_menu_markup():
    markup = InlineKeyboardMarkup()
    markup.row(
        InlineKeyboardButton("الإحصائيات", callback_data='dev_stats'),
        InlineKeyboardButton("إذاعة بالخاص", callback_data='dev_broadcast_start')
    )
    markup.row(
        InlineKeyboardButton("المشتركين", callback_data='dev_subscribers'),
        InlineKeyboardButton("رسالة خاصة", callback_data='dev_private_message')
    )
    markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
    return markup

def send_dev_menu(chat_id, message_id=None):
    text = "عزيزي هذه لوحة المطور الخاصة بك:"
    markup = dev_menu_markup()
    if message_id:
        try:
            bot.edit_message_text(text, chat_id, message_id, reply_markup=markup)
        except:
            bot.send_message(chat_id, text, reply_markup=markup)
    else:
        bot.send_message(chat_id, text, reply_markup=markup)

def build_private_message_back_button():
    """زر الرجوع لحالات الرسائل الخاصة"""
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton("الغاء العملية والرجوع", callback_data='dev_menu'))
    return markup

def get_subscribers_list():
    data = load_data()
    subscribers = []
    for user_id, user_data in data.items():
        if user_data.get("points", 0) != user_data.get("original_points", user_data.get("points", 0)):
            received = user_data.get("received_hosting", False)
            subscribers.append({
                'user_id': user_id,
                'name': user_data.get('name', 'مستخدم غير معروف'),
                'username': user_data.get('username', ''),
                'received': received
            })
    return subscribers

def build_subscribers_keyboard(page=0):
    subscribers = get_subscribers_list()
    total_subscribers = len(subscribers)
    
    start_idx = page * SUBSCRIBERS_PER_PAGE
    end_idx = min(start_idx + SUBSCRIBERS_PER_PAGE, total_subscribers)
    
    current_page_subscribers = subscribers[start_idx:end_idx]
    
    markup = InlineKeyboardMarkup()
    
    for subscriber in current_page_subscribers:
        if subscriber.get('username'):
            display_label = f"@{subscriber['username']}"
        else:
            display_label = subscriber.get('name', subscriber['user_id'])
        status_emoji = "🟢" if subscriber['received'] else "🔴"
        status_text = "مستلم" if subscriber['received'] else "غير مستلم"
        btn_name = InlineKeyboardButton(display_label, callback_data=f"subscriber_name_{subscriber['user_id']}_{page}")
        btn_status = InlineKeyboardButton(f"{status_text} {status_emoji}", callback_data=f"subscriber_status_{subscriber['user_id']}_{page}")
        markup.row(btn_name, btn_status)
    
    navigation_buttons = []
    
    if page > 0:
        navigation_buttons.append(InlineKeyboardButton("◀️ السابق", callback_data=f"dev_subscribers_page_{page-1}"))
    
    if end_idx < total_subscribers:
        navigation_buttons.append(InlineKeyboardButton("التالي ▶️", callback_data=f"dev_subscribers_page_{page+1}"))
    
    if navigation_buttons:
        markup.row(*navigation_buttons)
    
    page_info = f"📄 الصفحة {page + 1} من {((total_subscribers - 1) // SUBSCRIBERS_PER_PAGE) + 1}"
    markup.add(InlineKeyboardButton(page_info, callback_data="noop"))
    
    markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
    return markup, total_subscribers

def build_subscriber_actions_keyboard(user_id, page=0):
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton("إرسال الاستضافة", callback_data=f"send_hosting_{user_id}_{page}"))
    markup.add(InlineKeyboardButton("رجوع الى القائمة", callback_data=f'dev_subscribers_page_{page}'))
    return markup

def countdown_and_send(chat_id, message_id, user_id, hosting_details):
    for i in range(5, 0, -1):
        if sending_states.get(chat_id, {}).get('cancelled', False):
            return
        markup = InlineKeyboardMarkup()
        markup.add(InlineKeyboardButton("الغاء العملية", callback_data=f"cancel_sending_{user_id}"))
        try:
            bot.edit_message_text(
                f"⊱ *جاري ارسال المعلومات يرجى الانتضار الوقت المتبقي*: {i}",
                chat_id,
                message_id,
                reply_markup=markup,
                parse_mode='Markdown'
            )
        except:
            pass
        time.sleep(1)
    if sending_states.get(chat_id, {}).get('cancelled', False):
        return
    try:
        bot.send_message(int(user_id), hosting_details)
        data = load_data()
        if user_id not in data:
            data[user_id] = {"points": 0, "referred_by": None, "name": "", "username": "", "received_hosting": True}
        else:
            data[user_id]['received_hosting'] = True
        save_data(data)
        try:
            bot.delete_message(chat_id, message_id)
        except:
            pass
        bot.send_message(chat_id, "⊱ *تم ارسال معلومات الاستضافة الى المستخدم المطلوب*.", parse_mode='Markdown')
    except Exception as e:
        bot.send_message(chat_id, f"⊱ *حدث خطأ في إرسال المعلومات*: {str(e)}")
    if chat_id in sending_states:
        del sending_states[chat_id]
    if chat_id in pending_hosting_details:
        del pending_hosting_details[chat_id]

def edit_or_replace_message(chat_id, message_id, text, reply_markup=None, parse_mode=None):
    try:
        bot.edit_message_text(text, chat_id, message_id, reply_markup=reply_markup, parse_mode=parse_mode)
        return None
    except:
        try:
            bot.delete_message(chat_id, message_id)
        except:
            pass
        try:
            msg = bot.send_message(chat_id, text, reply_markup=reply_markup, parse_mode=parse_mode)
            return msg
        except:
            return None

def can_claim_daily_gift(user_id):
    data = load_data()
    uid = str(user_id)
    if uid not in data:
        return True
    last_gift = data[uid].get("last_daily_gift")
    if not last_gift:
        return True
    last_time = datetime.fromisoformat(last_gift)
    now = datetime.utcnow()
    return (now - last_time).total_seconds() >= 86400

def claim_daily_gift(user_id):
    data = load_data()
    uid = str(user_id)
    if uid not in data:
        return False
    data[uid]["points"] = data[uid].get("points", 0) + 10
    data[uid]["last_daily_gift"] = datetime.utcnow().isoformat()
    save_data(data)
    return True

@bot.message_handler(commands=["start"])
@subscription_required
def handle_start(message):
    data = load_data()
    user_id = message.from_user.id
    user_name = message.from_user.first_name or message.from_user.username or "المستخدم"
    user_username = message.from_user.username or ""
    payload = None
    parts = (message.text or "").split()
    if len(parts) > 1:
        payload = parts[1].strip()
    data = ensure_user(data, user_id, user_name, user_username)
    if payload:
        try:
            referrer_id = int(payload)
        except:
            referrer_id = None
        if referrer_id and referrer_id != user_id:
            ref_uid = str(referrer_id)
            if data[str(user_id)].get("referred_by") is None:
                if ref_uid in data:
                    data[str(user_id)]["referred_by"] = referrer_id
                    data[ref_uid]["points"] = int(data[ref_uid].get("points", 0)) + 10
                    save_data(data)
                    new_user_name = user_name
                    try:
                        bot.send_message(
                            referrer_id,
                            f"⊱ *حصلت على 10 نقاط من رابط الدعوة 🎉*\n⊱ *من المستخدم*: {new_user_name}\n⊱ *شارك رابط الدعوة لإصدقائك للحصول على اكبر عدد من النقاط*.",
                            parse_mode="Markdown"
                        )
                    except:
                        pass
                else:
                    data[str(user_id)]["referred_by"] = referrer_id
                    save_data(data)
    save_data(data)
    points = data[str(user_id)].get("points", 0)
    text = f"⊱ *مرحباً: {user_name}* 👋🏻.\n\n⊱ *نقدم لك بوت الاستضافة المجانية بالكامل مع دومين خاص بك ولوحة تحكم خاصة بك*.\n⊱ *كيفية عمل البوت* ⬇️:\n⊱ *يمكنك إنشاء رابط دعوة وارسال الرابط إلى 10 مستخدمين*.\n⊱ *يمكنك شراء أي استضافة من أي موقع، مع دومين خاص بك ولوحة تحكم خاصة بك بمجرد جمع النقاط*."
    kb = build_main_menu(points)
    try:
        bot.send_message(
            message.chat.id,
            text=text,
            reply_markup=kb,
            parse_mode="Markdown"
        )
    except:
        bot.send_message(message.chat.id, text, reply_markup=kb)
    return

@bot.message_handler(commands=['dev'])
@developer_only
def handle_dev(message):
    send_dev_menu(message.chat.id)

@bot.message_handler(func=lambda message: message.from_user.id in DEVELOPER_IDS and message.chat.id in pending_hosting_details)
def handle_hosting_details(message):
    chat_id = message.chat.id
    entry = pending_hosting_details.get(chat_id)
    if not entry:
        return
    user_id = entry['user_id']
    page = entry.get('page', 0)
    hosting_details = message.text
    sending_states[chat_id] = {'cancelled': False}
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton("الغاء العملية", callback_data=f"cancel_sending_{user_id}_{page}"))
    sent_message = bot.send_message(
        chat_id,
        "جاري ارسال المعلومات يرجى الانتضار الوقت المتبقي: 5",
        reply_markup=markup
    )
    thread = threading.Thread(
        target=countdown_and_send,
        args=(chat_id, sent_message.message_id, user_id, hosting_details)
    )
    thread.start()

# معالج جديد للرسائل الخاصة من المطور
@bot.message_handler(func=lambda message: message.from_user.id in DEVELOPER_IDS and message.chat.id in private_message_states)
def handle_private_message_text(message):
    chat_id = message.chat.id
    state_data = private_message_states.get(chat_id)
    
    if not state_data:
        return
    
    if state_data['state'] == 'awaiting_user_id':
        # استلام معرف المستخدم
        user_id = message.text.strip()
        
        try:
            # التحقق من أن المعرف رقم
            user_id_int = int(user_id)
            state_data['target_user_id'] = user_id_int
            state_data['state'] = 'awaiting_message_text'
            
            markup = build_private_message_back_button()
            bot.send_message(
                chat_id,
                f"تم استلام معرف المستخدم: {user_id}\n\nالآن أرسل نص الرسالة التي تريد إرسالها لهذا المستخدم.",
                reply_markup=markup
            )
        except ValueError:
            markup = build_private_message_back_button()
            bot.send_message(
                chat_id,
                "خطأ: يجب أن يكون معرف المستخدم رقمًا صحيحًا.\n\nأرسل معرف المستخدم مرة أخرى:",
                reply_markup=markup
            )
    
    elif state_data['state'] == 'awaiting_message_text':
        # استلام نص الرسالة
        message_text = message.text
        
        try:
            # إرسال الرسالة للمستخدم المستهدف
            bot.send_message(state_data['target_user_id'], message_text)
            
            # إعلام المطور بنجاح الإرسال
            markup = InlineKeyboardMarkup()
            markup.add(InlineKeyboardButton("العودة للوحة المطور", callback_data='dev_menu'))
            bot.send_message(
                chat_id,
                f"✅ تم إرسال الرسالة بنجاح إلى المستخدم (ID: {state_data['target_user_id']})",
                reply_markup=markup
            )
            
            # تسجيل في قناة الإدارة
            try:
                bot.send_message(
                    ADMIN_CHANNEL_ID,
                    f"📨 تم إرسال رسالة خاصة من المطور إلى المستخدم {state_data['target_user_id']}\n\nالرسالة: {message_text[:500]}..."
                )
            except:
                pass
            
        except Exception as e:
            markup = build_private_message_back_button()
            bot.send_message(
                chat_id,
                f"❌ فشل في إرسال الرسالة إلى المستخدم (ID: {state_data['target_user_id']})\n\nالخطأ: {str(e)}",
                reply_markup=markup
            )
        
        # مسح حالة الرسالة الخاصة
        if chat_id in private_message_states:
            del private_message_states[chat_id]

@bot.callback_query_handler(func=lambda c: True)
def handle_callbacks(call):
    data = load_data()
    uid = str(call.from_user.id)
    callback = call.data

    if callback.startswith('dev_'):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        bot.answer_callback_query(call.id)
        chat_id = call.message.chat.id
        message_id = getattr(call.message, 'message_id', None)
        
        if callback == 'dev_menu':
            bot.clear_step_handler_by_chat_id(chat_id)
            if chat_id in sending_states:
                del sending_states[chat_id]
            if chat_id in pending_hosting_details:
                del pending_hosting_details[chat_id]
            if chat_id in private_message_states:
                del private_message_states[chat_id]
            send_dev_menu(chat_id, message_id)
            return
        
        elif callback == 'dev_stats':
            users = load_data()
            count = len(users)
            text = f"**الاحصائيات**:\n\nعدد المستخدمين: *{count}* مستخدم."
            markup = InlineKeyboardMarkup()
            markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
            try:
                if message_id is not None:
                    bot.edit_message_text(text, chat_id, message_id, reply_markup=markup, parse_mode='Markdown')
                else:
                    bot.send_message(chat_id, text, reply_markup=markup, parse_mode='Markdown')
            except:
                bot.send_message(chat_id, text, reply_markup=markup, parse_mode='Markdown')
        
        elif callback == 'dev_broadcast_start':
            text = "أرسل الآن الرسالة التي تريد بثها لجميع المستخدمين."
            markup = InlineKeyboardMarkup()
            markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
            try:
                if message_id is not None:
                    bot.edit_message_text(text, chat_id, message_id, reply_markup=markup)
                else:
                    bot.send_message(chat_id, text, reply_markup=markup)
            except:
                bot.send_message(chat_id, text, reply_markup=markup)
            bot.register_next_step_handler(call.message, lambda msg: process_broadcast_message(msg, message_id))
        
        elif callback == 'dev_subscribers':
            markup, total_subscribers = build_subscribers_keyboard(page=0)
            text = f"*عزيزي المطور، هذه قائمة المشتركين*\nإجمالي المشتركين: {total_subscribers}"
            try:
                if message_id is not None:
                    bot.edit_message_text(text, chat_id, message_id, reply_markup=markup, parse_mode='Markdown')
                else:
                    bot.send_message(chat_id, text, reply_markup=markup, parse_mode='Markdown')
            except:
                bot.send_message(chat_id, text, reply_markup=markup, parse_mode='Markdown')
        
        elif callback == 'dev_private_message':
            # بدء عملية إرسال رسالة خاصة
            private_message_states[chat_id] = {
                'state': 'awaiting_user_id',
                'target_user_id': None
            }
            
            markup = build_private_message_back_button()
            try:
                if message_id is not None:
                    bot.edit_message_text(
                        "🔹 **مرحلة 1 من 2**\n\nأرسل معرف المستخدم (User ID) الذي تريد إرسال رسالة له:\n\n*ملاحظة:* يمكنك الحصول على معرف المستخدم من قائمة المشتركين",
                        chat_id,
                        message_id,
                        reply_markup=markup,
                        parse_mode='Markdown'
                    )
                else:
                    bot.send_message(
                        chat_id,
                        "🔹 **مرحلة 1 من 2**\n\nأرسل معرف المستخدم (User ID) الذي تريد إرسال رسالة له:\n\n*ملاحظة:* يمكنك الحصول على معرف المستخدم من قائمة المشتركين",
                        reply_markup=markup,
                        parse_mode='Markdown'
                    )
            except:
                bot.send_message(
                    chat_id,
                    "🔹 **مرحلة 1 من 2**\n\nأرسل معرف المستخدم (User ID) الذي تريد إرسال رسالة له:\n\n*ملاحظة:* يمكنك الحصول على معرف المستخدم من قائمة المشتركين",
                    reply_markup=markup,
                    parse_mode='Markdown'
                )
            return
        
        return
    
    # معالجة تصفح صفحات المشتركين
    if callback.startswith('dev_subscribers_page_'):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        bot.answer_callback_query(call.id)
        try:
            page = int(callback.split('_')[3])
        except:
            page = 0
        
        markup, total_subscribers = build_subscribers_keyboard(page=page)
        text = f"*عزيزي المطور، هذه قائمة المشتركين*\nإجمالي المشتركين: {total_subscribers}"
        try:
            bot.edit_message_text(
                text, 
                call.message.chat.id, 
                call.message.message_id, 
                reply_markup=markup, 
                parse_mode='Markdown'
            )
        except:
            pass
        return

    if callback.startswith('subscriber_name_') or callback.startswith('subscriber_status_'):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        bot.answer_callback_query(call.id)
        
        parts = callback.split('_')
        user_id = parts[2]
        page = int(parts[3]) if len(parts) > 3 else 0
        
        data = load_data()
        user_data = data.get(user_id, {})
        user_name = user_data.get('name', 'مستخدم غير معروف')
        username = user_data.get('username', '')
        received = user_data.get('received_hosting', False)
        if username:
            display = f"@{username}"
        else:
            display = user_name
        
        if received:
            markup = InlineKeyboardMarkup()
            markup.add(InlineKeyboardButton("رجوع الى القائمة", callback_data=f'dev_subscribers_page_{page}'))
            bot.edit_message_text(
                f"المستخدم: {display} مستلم 🟢\n\nهذا المستخدم استلم تفاصيل الاستضافة بالفعل.",
                call.message.chat.id,
                call.message.message_id,
                reply_markup=markup
            )
        else:
            markup = build_subscriber_actions_keyboard(user_id, page)
            bot.edit_message_text(
                f"المستخدم: {display} غير مستلم 🔴",
                call.message.chat.id,
                call.message.message_id,
                reply_markup=markup
            )
        return

    if callback.startswith('send_hosting_'):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        bot.answer_callback_query(call.id)
        
        parts = callback.split('_')
        user_id = parts[2]
        page = int(parts[3]) if len(parts) > 3 else 0
        
        pending_hosting_details[call.message.chat.id] = {'user_id': user_id, 'page': page}
        
        markup = InlineKeyboardMarkup()
        markup.add(InlineKeyboardButton("رجوع الى القائمة", callback_data=f'dev_subscribers_page_{page}'))

        chat_id = call.message.chat.id
        message_id = getattr(call.message, 'message_id', None)

        try:
            if message_id is not None:
                bot.edit_message_text(
                    f"عزيزي المطور من فضلك ارسل تفاصيل الاستضافة للمستخدم.\nالصفحة الحالية: {page + 1}",
                    chat_id,
                    message_id,
                    reply_markup=markup
                )
            else:
                bot.send_message(chat_id, f"عزيزي المطور من فضلك ارسل تفاصيل الاستضافة للمستخدم.\nالصفحة الحالية: {page + 1}", reply_markup=markup)
        except Exception:
            try:
                bot.send_message(chat_id, f"عزيزي المطور من فضلك ارسل تفاصيل الاستضافة للمستخدم.\nالصفحة الحالية: {page + 1}", reply_markup=markup)
            except:
                pass
        return

    if callback.startswith('cancel_sending_'):
        if call.from_user.id not in DEVELOPER_IDS:
            bot.answer_callback_query(call.id, "⊱ عذراً، هذا الأمر مخصص للمطورين فقط.", show_alert=True)
            return
        bot.answer_callback_query(call.id)
        
        parts = callback.split('_')
        user_id = parts[2]
        page = int(parts[3]) if len(parts) > 3 else 0
        
        chat_id = call.message.chat.id
        if chat_id in sending_states:
            sending_states[chat_id]['cancelled'] = True
        if chat_id in pending_hosting_details:
            del pending_hosting_details[chat_id]
        
        markup, total_subscribers = build_subscribers_keyboard(page=page)
        text = f"*عزيزي المطور، هذه قائمة المشتركين*\nإجمالي المشتركين: {total_subscribers}"
        try:
            bot.edit_message_text(text, chat_id, call.message.message_id, reply_markup=markup, parse_mode='Markdown')
        except:
            bot.send_message(chat_id, text, reply_markup=markup, parse_mode='Markdown')
        return

    if callback == "noop":
        bot.answer_callback_query(call.id)
        return

    @callback_subscription_required
    def handle_regular_callback(call):
        if callback == "points":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            user_points = int(data.get(uid, {}).get("points", 0))
            bot.send_message(call.message.chat.id, f"نقاطك الحالية: {user_points}")
            return

        if callback == "free_hosting":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "عزيزي المستخدم يرجى اختيار موقع الاستضافة ادناه 🔻:"
            kb = build_country_selection("free_hosting")
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback == "paid_hosting":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "عزيزي المستخدم، سيتم إضافة هذا القسم قريباً 🔺."
            kb = build_back_button()
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback == "free_vps":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "عزيزي المستخدم يرجى اختيار موقع الخادم ادناه 🔻:"
            kb = build_country_selection("free_vps")
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback == "paid_vps":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "عزيزي المستخدم يرجى اختيار موقع الخادم ادناه 🔻:"
            kb = build_country_selection("paid_vps")
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback.startswith("country_"):
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            parts = callback.split("_")
            service_type = parts[1] + "_" + parts[2] if len(parts) >= 3 else parts[1]
            country = parts[3] if len(parts) >= 4 else "unknown"
            
            country_names = {
                "amsterdam": "امستردام 🇳🇱",
                "australia": "استراليا 🇦🇺",
                "america": "امريكا 🇺🇸",
                "germany": "المانيا 🇩🇪",
                "nigeria": "نيجيريا 🇳🇬",
                "russia": "روسيا 🇷🇺",
                "singapore": "سنغافورة 🇸🇬",
                "france": "فرنسا 🇫🇷",
                "canada": "كندا 🇨🇦",
                "finland": "فنلندا 🇫🇮"
            }
            country_name = country_names.get(country, country)
            
            if service_type in ["free_hosting", "free_vps"]:
                kb_back = build_back_button()
                result_msg = edit_or_replace_message(call.message.chat.id, call.message.message_id, "⊱ *يتم التحقق من النقاط الحالية الخاصة بك*. . .", reply_markup=kb_back, parse_mode='Markdown')
                if result_msg:
                    target_message_id = result_msg.message_id
                else:
                    target_message_id = call.message.message_id
                
                time.sleep(2)
                
                data_local = load_data()
                user_points = int(data_local.get(uid, {}).get("points", 0))
                
                if user_points < 100:
                    kb = InlineKeyboardMarkup(row_width=2)
                    kb.add(InlineKeyboardButton(text="انشاء رابط احالة", callback_data="create_referral"),
                           InlineKeyboardButton(text="رجوع الى القائمة", callback_data="back_to_menu"))
                    try:
                        bot.edit_message_text(
                            "المعذرة، نقاطك الحالية غير كافية يجب ان تكون نقاطك 100 أو اكثر",
                            call.message.chat.id,
                            target_message_id,
                            reply_markup=kb
                        )
                    except:
                        bot.send_message(call.message.chat.id,
                                         "المعذرة، نقاطك الحالية غير كافية يجب ان تكون نقاطك 100 أو اكثر",
                                         reply_markup=kb)
                else:
                    kb = InlineKeyboardMarkup(row_width=2)
                    kb.add(InlineKeyboardButton(text="تأكيد", callback_data=f"confirm|{service_type}|{country}"),
                           InlineKeyboardButton(text="رجوع الى القائمة", callback_data="back_to_menu"))
                    
                    service_label = "الاستضافة" if "hosting" in service_type else "الخادم"
                    confirmation_text = f"⊱ *الموقع*: {country_name}\n⊱ *المعالج*: 1 CPU\n⊱ *الرام*: 1 GB\n\n⊱ *يرجى تأكيد شراء {service_label} الخاصة بك*:"
                    
                    try:
                        bot.edit_message_text(
                            confirmation_text,
                            call.message.chat.id,
                            target_message_id,
                            reply_markup=kb,
                            parse_mode='Markdown'
                        )
                    except:
                        bot.send_message(call.message.chat.id,
                                         confirmation_text,
                                         reply_markup=kb,
                                         parse_mode='Markdown')
            
            elif service_type == "paid_vps":
                text = f"عزيزي المستخدم يرجى اختيار معلومات الخادم الخاصة بك 🔻:"
                kb = build_paid_vps_menu(country_name, country)
                edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            
            elif service_type == "paid_hosting":
                text = "عزيزي المستخدم، سيتم إضافة هذا القسم قريباً 🔺."
                kb = build_back_button()
                edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback.startswith("paid_vps_"):
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            
            parts = callback.split("_")
            country_code = parts[2]
            vps_type = parts[3]
            
            country_names = {
                "amsterdam": "امستردام 🇳🇱",
                "australia": "استراليا 🇦🇺",
                "america": "امريكا 🇺🇸",
                "germany": "المانيا 🇩🇪",
                "nigeria": "نيجيريا 🇳🇬",
                "russia": "روسيا 🇷🇺",
                "singapore": "سنغافورة 🇸🇬",
                "france": "فرنسا 🇫🇷",
                "canada": "كندا 🇨🇦",
                "finland": "فنلندا 🇫🇮"
            }
            country_name = country_names.get(country_code, country_code)
            
            vps_details = {
                "1": {"ram": "8 GB", "vcpu": "4", "price": "15$"},
                "2": {"ram": "12 GB", "vcpu": "6", "price": "25$"},
                "3": {"ram": "24 GB", "vcpu": "8", "price": "$35"},
                "4": {"ram": "48 GB", "vcpu": "12", "price": "60$"}
            }
            
            details = vps_details.get(vps_type, {"ram": "N/A", "vcpu": "N/A", "price": "N/A"})
            
            order_summary = f"""عزيزي المستخدم، اليك ملخص الطلب 🔻:

⊱ الخدمة: خادم VPS مدفوع
⊱ الموقع: {country_name}
⊱ المعالج: {details['vcpu']} vCPU
⊱ الرام: {details['ram']}
⊱ المدة: شهر واحد
⊱ السعر: {details['price']}

⊱ يرجى التواصل مع مطور البوت للحصول على الخدمة:
- @DevKodo"""

            kb = build_back_button()
            edit_or_replace_message(call.message.chat.id, call.message.message_id, order_summary, reply_markup=kb)
            return

        if callback == "collect_points":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "عزيزي المستخدم يمكنك تجميع النقاط بواسطة الطرق التالية 🔻:"
            kb = build_collect_points_menu()
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback == "create_referral":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            data_local = load_data()
            user_points = int(data_local.get(uid, {}).get("points", 0))
            
            try:
                me = bot.get_me()
                bot_username = me.username
            except:
                bot_username = None
            if bot_username:
                link = f"https://t.me/{bot_username}?start={call.from_user.id}"
            else:
                link = f"t.me/username?start={call.from_user.id}"
            
            kb_back = build_back_button()
            
            referral_text = f"⊱ *عدد نقاطك الحالي*: {user_points}\n⊱ *شارك رابط الإحالة للحصول على نقاط*.\n⊱ *هذا هو رابط الإحالة الخاص بك*:\n{link}"
            
            result_msg = edit_or_replace_message(call.message.chat.id, call.message.message_id, referral_text, reply_markup=kb_back, parse_mode='Markdown')
            if result_msg:
                pass
            return

        if callback == "daily_gift":
            if can_claim_daily_gift(call.from_user.id):
                if claim_daily_gift(call.from_user.id):
                    bot.answer_callback_query(
                        call.id,
                        "🎉 تهانينا!\n\nلقد حصلت على 10 نقاط كهدية يومية.",
                        show_alert=True
                    )
                    text = "تهانينا ربحت 10 نقاط كهدية يومية 🎉 ."
                    kb = build_back_button()
                    edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
                else:
                    bot.answer_callback_query(
                        call.id,
                        "حدث خطأ\n\nيرجى المحاولة مرة أخرى لاحقاً.",
                        show_alert=True
                    )
            else:
                bot.answer_callback_query(
                    call.id,
                    "⏳ مهلاً\nلقد حصلت على الهدية اليومية بالفعل.\nيمكنك المطالبة بها مرة أخرى بعد 24 ساعة من آخر هدية.",
                    show_alert=True
                )
            return

        if callback == "help_menu":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            text = "مرحباً بك، يمكنك عبر هذا البوت الحصول على خدمات استضافة وسيرفرات VPS مجانية ومدفوعة من خلال تجميع النقاط أو الشراء المباشر.\n\nلتجميع النقاط، اضغط على زر 'تجميع نقاط' وشارك رابط الإحالة الخاص بك.\n\nكل صديق يشترك عبر رابطك يمنحك 10 نقاط."
            kb = build_back_button()
            edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb)
            return

        if callback.startswith("confirm|"):
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            parts = callback.split("|")
            service_type = parts[1] if len(parts) > 1 else "unknown"
            country = parts[2] if len(parts) > 2 else "unknown"
            
            country_names = {
                "amsterdam": "امستردام 🇳🇱",
                "australia": "استراليا 🇦🇺",
                "america": "امريكا 🇺🇸",
                "germany": "المانيا 🇩🇪",
                "nigeria": "نيجيريا 🇳🇬",
                "russia": "روسيا 🇷🇺",
                "singapore": "سنغافورة 🇸🇬",
                "france": "فرنسا 🇫🇷",
                "canada": "كندا 🇨🇦",
                "finland": "فنلندا 🇫🇮"
            }
            country_name = country_names.get(country, country)
            
            data_local = load_data()

            if uid not in data_local:
                uname = call.from_user.username or ""
                data_local[uid] = {"points": 0, "referred_by": None, "name": call.from_user.first_name or "", "username": uname, "received_hosting": False}

            current_points = int(data_local.get(uid, {}).get("points", 0))
            if "original_points" not in data_local[uid]:
                data_local[uid]["original_points"] = current_points
            remaining = current_points - 100
            if remaining < 0:
                remaining = 0
            data_local[uid]["points"] = remaining

            data_local[uid]["received_hosting"] = False

            save_data(data_local)
            
            try:
                bot.delete_message(call.message.chat.id, call.message.message_id)
            except:
                pass
                
            now = datetime.utcnow() + timedelta(hours=3)
            purchase_date = now.strftime("%d/%m/%Y")
            expiry = (now + timedelta(days=60)).strftime("%d/%m/%Y")
            
            service_label = "الاستضافة" if "hosting" in service_type else "الخادم"
            purchase_text = f"⊱ *تم شراء الخدمة، اليك التفاصيل*:\n\n⊱ *نوع الخدمة*: {service_label}\n⊱ *الموقع*: {country_name}\n⊱ *الرام*: 1GB\n⊱ *الذاكرة*: 1CPU\n⊱ *تاريخ الشراء*: {purchase_date}\n⊱ *تاريخ الانتهاء*: {expiry}\n⊱ *المدة الكاملة: 60 يوم*\n\n⊱ *الرجاء الانتضار حتى يتم ارسال معلومات {service_label} الخاصة بك*"
            
            bot.send_message(call.message.chat.id, purchase_text, parse_mode='Markdown')
            try:
                admin_username = data_local.get(uid, {}).get('username', '')
                username_display = f"@{admin_username}" if admin_username else "غير متوفر"
                bot.send_message(ADMIN_CHANNEL_ID,
                                 f"طلب شراء جديد:\n\nالمستخدم: {data_local.get(uid,{}).get('name','')}\nاسم المستخدم: {username_display}\nمعرف المستخدم: {uid}\nنوع الخدمة: {service_label}\nالموقع: {country_name}\nالرام: 1GB\nالذاكرة: 1CPU\nتاريخ الشراء: {purchase_date}\nتاريخ الانتهاء: {expiry}\nالمدة: 60 يوم")
            except:
                pass
            return

        if callback == "back_to_menu":
            try:
                bot.answer_callback_query(call.id)
            except:
                pass
            if call.from_user.id in DEVELOPER_IDS:
                chat_id = call.message.chat.id
                if chat_id in sending_states:
                    del sending_states[chat_id]
                if chat_id in pending_hosting_details:
                    del pending_hosting_details[chat_id]
                if chat_id in private_message_states:
                    del private_message_states[chat_id]
            data_local = load_data()
            points = int(data_local.get(uid, {}).get("points", 0))
            name = data_local.get(uid, {}).get("name", call.from_user.first_name or "المستخدم")
            text = f"⊱ *مرحباً: {name}* 👋🏻.\n\n⊱ *نقدم لك بوت الاستضافة المجانية بالكامل مع دومين خاص بك ولوحة تحكم خاصة بك*.\n⊱ *كيفية عمل البوت* ⬇️:\n⊱ *يمكنك إنشاء رابط دعوة وارسال الرابط إلى 10 مستخدمين*.\n⊱ *يمكنك شراء أي استضافة من أي موقع، مع دومين خاص بك ولوحة تحكم خاصة بك بمجرد جمع النقاط*."
            kb = build_main_menu(points)
            result_msg = edit_or_replace_message(call.message.chat.id, call.message.message_id, text, reply_markup=kb, parse_mode='Markdown')
            if result_msg:
                pass
            return
    
    handle_regular_callback(call)

def process_broadcast_message(message, message_id_to_edit):
    chat_id = message.chat.id
    if message.from_user.id not in DEVELOPER_IDS:
        bot.send_message(chat_id, "تم إلغاء العملية. هذا الأمر مخصص للمطورين فقط.")
        return
    broadcast_text = message.text
    if not broadcast_text:
        markup = InlineKeyboardMarkup()
        markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
        try:
            bot.edit_message_text("لم يتم إرسال نص. تم إلغاء الإذاعة.", chat_id, message_id_to_edit, reply_markup=markup)
        except:
            bot.send_message(chat_id, "لم يتم إرسال نص. تم إلغاء الإذاعة.", reply_markup=markup)
        return
    data = load_data()
    total_users = len(data)
    sent_count = 0
    failed_count = 0
    try:
        bot.edit_message_text(f"بدء عملية الإذاعة لـ {total_users} مستخدم...", chat_id, message_id_to_edit)
    except:
        pass
    for user_id_str, user_info in data.items():
        try:
            bot.send_message(int(user_id_str), broadcast_text, parse_mode='Markdown')
            sent_count += 1
            time.sleep(1)
        except Exception:
            failed_count += 1
    result_text = f"**انتهت عملية الإذاعة**:\n\nتم الإرسال بنجاح إلى: *{sent_count}* مستخدم.\nفشل الإرسال إلى: *{failed_count}* مستخدم."
    markup = InlineKeyboardMarkup()
    markup.add(InlineKeyboardButton("الرجوع للقائمة الرئيسية", callback_data='dev_menu'))
    try:
        bot.edit_message_text(result_text, chat_id, message_id_to_edit, reply_markup=markup, parse_mode='Markdown')
    except:
        bot.send_message(chat_id, result_text, reply_markup=markup, parse_mode='Markdown')

if __name__ == "__main__":
    print("starting bot...")
    bot.set_my_commands(
        [
            telebot.types.BotCommand("start", "Start Chat"),
            telebot.types.BotCommand("help", "Request assistance"),
            telebot.types.BotCommand("dev", "Developer Panel"),
        ]
    )
    bot.delete_webhook()
    bot.polling(none_stop=True)
