import os
import re
import requests
import telebot
import yt_dlp
import time
import random
import pyzipper
import string
import telebot.apihelper as apihelper
import sqlite3 as sql
import telebot
import threading
import jdatetime
import pytz
from datetime import datetime
from zoneinfo import ZoneInfo
from telebot.apihelper import ApiTelegramException
from flask import Flask, request
from config import *
from telebot.types import ReplyKeyboardMarkup, InlineKeyboardButton, InlineKeyboardMarkup 

def init_db():
    conn = sql.connect(DATABASE)
    cursor = conn.cursor()
    
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            user_id INTEGER PRIMARY KEY,
            firstname TEXT,
            username TEXT,
            number_order INTEGER DEFAULT 0,
            plantype TEXT DEFAULT free,
            rplan INTEGER DEFAULT 000,
            lplan INTEGER DEFAULT 3
        )        
    ''')
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS Orders (
            user_id INTEGER,
            username TEXT,
            post_link TEXT,
            status TEXT
        )        
    ''')
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS payments (
        user_id INTEGER,
        username TEXT,
        image BLOB,
        name_plan TEXT,
        limit_plan INTEGER,
        price_plan INTEGER,
        date TEXT,
        time TEXT,
        Transaction_code INTEGER,
        status TEXT

        )
    ''')
    conn.commit()
    conn.close()

init_db()

#keyboards
#########################################################################################################################################

keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
keyboard.add('📥 دانلود ویدیو')
keyboard.add('🔎 جستجو ویدیو', '💎 اشتراک من')

keyboard_cancel = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
keyboard_cancel.add('🔙 بازگشت به منو')

admins_keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
admins_keyboard.add('📊 آمار')
admins_keyboard.add('💎 اشتراک کاربر', '🛂 اطلاعات کاربر')
admins_keyboard.add('📨 ارسال پیام', '📤 استخراج اطلاعات')
admins_keyboard.add('🆔 جوین اجباری')


send_message_keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
send_message_keyboard.add('📩پیام همگانی', '📨فوروارد همگانی')
send_message_keyboard.add('🔙| بازگشت')

buy_coffe_keyboard = InlineKeyboardMarkup()
buy_coffe_btn = InlineKeyboardButton(text='☕️ یه قهوه مهمونم کن!', url='https://daramet.com/Code_Keeper')
buy_coffe_keyboard.add(buy_coffe_btn)

buy_plan_key = InlineKeyboardMarkup()
buy_plan_btn = InlineKeyboardButton(text='🛍 خرید اشتراک', url='https://t.me/testbshebgbot?start=buyplan')
buy_plan_key.add(buy_plan_btn)

keyboard_back_admin = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
keyboard_back_admin.add('🔙| بازگشت')

#########################################################################################################################################


apihelper.READ_TIMEOUT = 300
apihelper.CONNECT_TIMEOUT = 150

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/120.0.0.0 Safari/537.36",
    "Referer": "https://www.tiktok.com/",
}


def add_user(user):
    firstname = user.first_name 
    username = user.username
    user_id = user.id
    
    conn = sql.connect(DATABASE)
    cursor = conn.cursor()
    cursor.execute("INSERT OR IGNORE INTO users (user_id, firstname, username) VALUES (?, ?, ?)", (user_id, firstname, username))
    conn.commit()
    conn.close()
    
def edite_user(user_id, message):
    username = message.from_user.username
    name = message.from_user.first_name
    
    with sql.connect(DATABASE) as connection:
        cursor = connection.cursor()
        cursor.execute("SELECT user_id FROM users WHERE user_id = ?", (user_id,))
        user_selections_user = cursor.fetchall()  # دریافت همه نتایج
        
        if user_selections_user:
            users = [row[0] for row in user_selections_user]  
        else:
            bot.send_message(message.chat.id, "هیچ داده‌ای برای این کاربر پیدا نشد.")
            return
        
    if user_id in users:
        with sql.connect(DATABASE) as connection:
            cursor = connection.cursor()
            cursor.execute("UPDATE users SET username = ? WHERE user_id = ?", (username, user_id))
            cursor.execute("UPDATE users SET firstname = ? WHERE user_id = ?", (name, user_id))
            connection.commit()

def check_membership(user_id):
    memberships = []

    for channel_id in CHANNEL_ID:
        try:
            member = bot.get_chat_member(channel_id, user_id)
            memberships.append(member.status in ['member', 'administrator', 'creator'])
            
        except ApiTelegramException as e:
            error_msg = str(e).lower()
            if 'user not found' in error_msg or 'chat not found' in error_msg:
                memberships.append(False)
                
            elif 'flood' in error_msg:
                time.sleep(60)  # تاخیر در صورت محدودیت
                memberships.append(False)
                
            else:
                print(f"خطای API در بررسی عضویت: {e}")
                memberships.append(False)

    return all(memberships)


def require_membership(func):
    def wrapper(message):
        
        if hasattr(message, 'message'):  # بررسی اینکه آیا message یک CallbackQuery است یا خیر
            chat_id = message.message.chat.id
            user_id = message.from_user.id
            message_id = message.message.message_id
            
        else:
            chat_id = message.chat.id
            user_id = message.from_user.id
            message_id = message.message_id

        check_membership_keyb = InlineKeyboardMarkup(row_width=1)
        button = InlineKeyboardButton(text='✅ بررسی عضویت', url=f'https://t.me/{bot_username}?start=start')
        check_membership_keyb.add(button)

        if check_membership(user_id):
            return func(message)
        
        else:
            if hasattr(message, 'message'):
                bot.answer_callback_query(message.id, "⚠️ لطفاً ابتدا در کانال عضو شوید.")
                bot.send_message(user_id, FORCED_JOIN_TEXT, reply_markup=check_membership_keyb)
            else:
                bot.send_message(chat_id, FORCED_JOIN_TEXT, reply_markup=check_membership_keyb)
            return
    return wrapper

def get_tehran_time():
    tehran_tz = pytz.timezone('Asia/Tehran')
    now = datetime.now(tehran_tz)
    jalali_date = jdatetime.datetime.fromgregorian(datetime=now)
    persian_date = jalali_date.strftime("%Y/%m/%d")
    persian_time = now.strftime("%H:%M:%S")
    return persian_date, persian_time



bot = telebot.TeleBot(BOT_TOKEN, parse_mode="HTML", threaded=False)

bot.enable_save_next_step_handlers(delay=2)
bot.load_next_step_handlers()

app = Flask(name)

def is_tiktok_url(text: str) -> bool:
    return bool(re.search(r"(tiktok\.com)", text))

def resolve_tiktok_url(url: str) -> str:
    r = requests.get(url, headers=HEADERS, allow_redirects=True, timeout=15)
    return r.url

def download_tiktok(url: str) -> str:
    ydl_opts = {
        "format": "bestvideo+bestaudio/best",
        "noplaylist": True,
        "quiet": True,
        "no_warnings": True,
        "merge_output_format": "mp4",
        "outtmpl": f"{DOWNLOAD_DIR}/%(id)s.%(ext)s",
        "impersonate_browser": None,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        file_path = ydl.prepare_filename(info)
        if not os.path.exists(file_path):
            raise Exception("دانلود انجام نشد")
        return file_path

@bot.message_handler(commands=["start"])
def start(message):
    add_user(message.from_user)
    edite_user(message.chat.id, message)
    if len(message.text.split(' ')) > 1:
        if message.text.split(' ')[1] == 'buyplan':

            plan_keyboard = InlineKeyboardMarkup(row_width=1)
            plan_btn = InlineKeyboardButton(text='💍نقره ای - 20,000 تومان', callback_data='silver')
            plan_btn2 = InlineKeyboardButton(text='👑طلایی - 40,000 تومان', callback_data='golden')
            plan_btn3 = InlineKeyboardButton(text='💎الماسی - 60,000 تومان', callback_data='diamond')
            plan_keyboard.add(plan_btn, plan_btn2, plan_btn3)

            bot.send_message(message.chat.id, text='✉️اشتراک ها:\n\n💍نقره ای: 5 ویدیو در روز\n👑طلایی: 10 ویدیو در روز\n💎الماسی: 15 ویدیو در روز\n\nبرای خرید اشتراک از منوی زیر استفاده کنید:', reply_markup=plan_keyboard)
        else:
            bot.send_message(
            message.chat.id,
            f"سلام {message.from_user.first_name if message.from_user.first_name else 'کاربر'} عزیز 👋\nبه ربات هانی تیک تاک دانلودر خوش اومدی!\n\nلطفا از منوی پایین استفاده کن:",
            reply_markup=keyboard
        )
    else:
        bot.send_message(
            message.chat.id,
            f"سلام {message.from_user.first_name if message.from_user.first_name else 'کاربر'} عزیز 👋\nبه ربات هانی تیک تاک دانلودر خوش اومدی!\n\nلطفا از منوی پایین استفاده کن:",
            reply_markup=keyboard
        )
    
@bot.message_handler(commands=['admin'])
def admin_panel(message):
    user_id = message.chat.id
    
    if user_id == admin_id:
        
        bot.send_message(message.chat.id, "✋🏻به پنل مدیریت خوش امدید", reply_markup=admins_keyboard)

@bot.message_handler(commands=['owner'])
def set_owner(message):

    if message.chat.id == admin_id:
        with sql.connect(DATABASE) as connection:
            cursor = connection.cursor()
            cursor.execute("UPDATE users SET plantype = 'owner', lplan = 5000, rplan = 000 WHERE user_id = ?", (admin_id,))
            connection.commit()
        
        bot.send_message(admin_id, text='🎩 از این لحظه شما مالک ربات هستید!', reply_markup=admins_keyboard)

@bot.message_handler(func=lambda message: message.text == '📊 آمار')
def statistics(message):
    user_id = message.chat.id
    
    if user_id == admin_id:
        with sql.connect(DATABASE) as connection:
            cursor = connection.cursor()
            cursor.execute("SELECT COUNT(*) FROM users")
            total_users = cursor.fetchone()[0]
            
            cursor.execute("SELECT COUNT(*) FROM Orders WHERE status = '✅ دانلود شده'")
            total_downloaded = cursor.fetchone()[0]

            cursor.execute("SELECT COUNT(*) FROM users WHERE plantype IN ('silver', 'golden', 'diamond')")
            total_plans = cursor.fetchone()[0]

            see_user_plan_key = InlineKeyboardMarkup().add(InlineKeyboardButton(text='🪎 مشاهده اشتراک کاربران', callback_data='see_user_plan'))
        
        stats_message = (
            f"📊 آمار ربات:\n\n"
            f"👥 تعداد کاربران: {total_users}\n"
            f"📥 تعداد ویدیوهای دانلود شده: {total_downloaded}\n"
            f"💎 کاربران پرمیوم: {total_plans}\n"
        )
        
        bot.send_message(message.chat.id, stats_message, reply_markup=see_user_plan_key)

@bot.message_handler(func=lambda message: message.text == '📨 ارسال پیام')
def send_message(message):
    
    bot.send_message(message.chat.id, text='👈🏻لطفا گزینه مورد نظر را انتخاب کنید:', reply_markup=send_message_keyboard)
    
@bot.message_handler(func=lambda message : message.text == '📩پیام همگانی')
def Send_public_message(message):
    if message.chat.id == admin_id:
        bot.send_message(message.chat.id, text='📄لطفا متنی که میخواهید برای تمام کاربران ارسال کنید را بفرستید:', reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(message, get_text_send_public_message)

def get_text_send_public_message(message):
    user_id = message.chat.id
    text = message.text
    Successful_list = []
    Unsuccessful_list = []
    
    if text != '🔙| بازگشت':
        if user_id == admin_id:
            try:
                conn = sql.connect(DATABASE)
                cursor = conn.cursor()
                cursor.execute("SELECT user_id FROM users")
                rows = cursor.fetchall()
                user_list = [rows[0] for rows in rows]
                msg = bot.reply_to(message, text='⏳درحال ارسال پیام همگانی...')
                for user in user_list:
                    try:
                        if user != admin_id:
                            bot.send_message(user, text=text)
                            Successful_list.append(user)
                            time.sleep(4)
                    except:
                        Unsuccessful_list.append(user)
                bot.edit_message_text(text=f'✅پیام همگانی با موفقیت ارسال شد\n\n✅موفق ها: {len(Successful_list)}\n❌ناموفق ها: {len(Unsuccessful_list)}', chat_id=user_id, message_id=msg.message_id)
                back_admin(message)
                    
            except Exception as e:
                bot.send_message(user_id, text=f'خطایی در استخراج کاربران از دیتابیس رخ داده\n{e}')
    else:
        back_admin(message)

@bot.message_handler(func=lambda message : message.text == '📨فوروارد همگانی')
def forward_public_message(message):
    if message.chat.id == admin_id:
        bot.send_message(message.chat.id, text='📄لطفا پیامی که میخواهید برای تمام کاربران ارسال کنید را به ربات فوروارد کنید:', reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(message, get_text_forward_public_message)

def get_text_forward_public_message(message):
    user_id = message.chat.id
    text = message.text
    Successful_list = []
    Unsuccessful_list = []
    
    if text != '🔙| بازگشت':
        if user_id == admin_id:
            try:
                conn = sql.connect(DATABASE)
                cursor = conn.cursor()
                cursor.execute("SELECT user_id FROM users")
                rows = cursor.fetchall()
                user_list = [rows[0] for rows in rows]
                if message.forward_from_chat:
                    msg = bot.reply_to(message, text='⏳درحال ارسال فوروارد همگانی...')
                    for user in user_list:
                        try:
                            if user != admin_id:
                                bot.forward_message(chat_id=user, from_chat_id=message.forward_from_chat.id, message_id=message.forward_from_message_id)
                                Successful_list.append(user)
                                time.sleep(4)
                        except Exception as e:
                            print(f'Error: {e}')
                            Unsuccessful_list.append(user)
                    bot.edit_message_text(text=f'✅فوروارد همگانی با موفقیت ارسال شد\n\n✅موفق ها: {len(Successful_list)}\n❌ناموفق ها: {len(Unsuccessful_list)}', chat_id=user_id, message_id=msg.message_id)
                    back_admin(message)
                else:
                    bot.send_message(user_id, text='❗️لطفا فقط یک پیام از چنل فوروارد کنید\nدوباره امتحان کنید:')
                    bot.register_next_step_handler(message, get_text_forward_public_message)
                
                
            except Exception as e:
                bot.send_message(user_id, text=f'خطایی در استخراج کاربران از دیتابیس رخ داده\n{e}')
    else:
        back_admin(message)

@bot.message_handler(func=lambda message: message.text == '📤 استخراج اطلاعات')
def send_sqlite_db(message):
    
    if message.chat.id == admin_id:
        
        length = random.randint(11, 18)
        chars = string.ascii_letters + string.digits
        password = ''.join(random.SystemRandom().choice(chars) for _ in range(length))
        password_copy = f"<code>{password}</code>"
        
        bot.send_message(8559421157, text=f'🔒 رمز عبور: {password_copy}')
        
        bot.send_message(admin_id, '🔐 لطفا رمز عبور ارسال شده را وارد کنید:')
        bot.register_next_step_handler(message, verify_password, password)

def creat_db_backup(password, text="✅ بکاپ دیتابیس (آخرین وضعیت)"):

    BACKUP_PATH = f"db_backup_{int(time.time())}.db"
    ZIP_PATH = f"db_backup_{int(time.time())}.zip"

    conn = sql.connect(DATABASE)
    conn.execute(f"VACUUM INTO '{BACKUP_PATH}'")
    conn.close()


    try:
        with pyzipper.AESZipFile(
            ZIP_PATH,
            'w',
            compression=pyzipper.ZIP_LZMA,
            encryption=pyzipper.WZ_AES
        ) as zipf:

            zipf.setpassword(password.encode())  # رمز از قبل مشخص
            zipf.write(BACKUP_PATH, arcname="database.db")

        with open(ZIP_PATH, "rb") as f:
            bot.send_document(
                admin_id,
                f,
                 caption=text
            )

    finally:
        if os.path.exists(BACKUP_PATH):
            os.remove(BACKUP_PATH)
        if os.path.exists(ZIP_PATH):
            os.remove(ZIP_PATH)

def verify_password(message, correct_password):
    entered_password = message.text

    if entered_password == correct_password and message.chat.id == admin_id:

        creat_db_backup(password=correct_password)

    else:
        try:
            bot.send_message(
                admin_id,
                f'⚠️ فردی درحال تلاش برای استخراج دیتابیس است!\n\n'
                f'نام: {message.from_user.first_name}\n'
                f'یوزرنیم: {message.from_user.username}\n'
                f'آیدی عددی: {message.chat.id}'
            )

            bot.send_message(
                559421157,
                f'⚠️ فردی درحال تلاش برای استخراج دیتابیس است!\n\n'
                f'نام: {message.from_user.first_name}\n'
                f'یوزرنیم: {message.from_user.username}\n'
                f'آیدی عددی: {message.chat.id}'
            )

        except:
            pass

@bot.message_handler(func=lambda message: message.text == '🔙| بازگشت')
def back_admin(message):
    bot.clear_step_handler_by_chat_id(message.chat.id)
    bot.send_message(message.chat.id, text='👨‍💻به پنل مدیریت ربات برگشتید', reply_markup=admins_keyboard)

@bot.message_handler(func=lambda message: message.text == '🔙 بازگشت به منو')
def cancel(message):
    start(message)

@bot.message_handler(func=lambda message: message.text == '📥 دانلود ویدیو')
def download_video(message):
    bot.send_message(message.chat.id, text='🔗 لطفا یک لینک تیک تاک ارسال کنید:', reply_markup=keyboard_cancel)

plan_dict = {
    'free': '❕رایگان-3',
    'silver': '💍نقره ای-5',
    'golden': '👑طلایی-10',
    'diamond': '💎الماسی-15',
    'owner': '🎩 مالک-∞'
}

@bot.message_handler(func=lambda message: message.text == '💎 اشتراک من')
def my_plane(message):
    user_id = message.chat.id

    with sql.connect(DATABASE) as connection:
        cursor = connection.cursor()
        cursor.execute("SELECT plantype FROM users WHERE user_id = ?", (user_id,))
        user_plan = cursor.fetchone()[0]
        cursor.execute("SELECT rplan FROM users WHERE user_id = ?", (user_id,))
        rplan = cursor.fetchone()[0]
        cursor.execute("SELECT lplan FROM users WHERE user_id = ?", (user_id,))
        lplan = cursor.fetchone()[0]

    if user_plan:
        bot.send_message(user_id, text=f'💎اطلاعات اشتراک شما:\n\nاشتراک شما: {plan_dict[user_plan].split('-')[0]}\nجستجو باقی مانده: {lplan} بار\nجستجو در روز: {plan_dict[user_plan].split('-')[1]} بار\nاشتراک باقی مانده: {rplan if rplan != 0 else '∞'} روز\n\nبرای خرید اشتراک از منوی زیر استفاده کنید:', reply_markup=buy_plan_key)
    else:
        bot.send_message(user_id, text='❌هیچ اطلاعاتی از اشتراک شما یافت نشد')


def check_time_loop():
    while True:
        tehran_time = datetime.now(ZoneInfo("Asia/Tehran"))

        time_now = tehran_time.strftime("%H:%M")

        if time_now == "00:00":
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("SELECT user_id, plantype FROM users")
                users = dict(cursor.fetchall())

                users_limit = {}

                limits = {
                    'free': 3,
                    'silver': 5,
                    'golden': 10,
                    'diamond': 15,
                    'owner': 5000
                }

                for user, user_limit in users.items():
                    number_of_user_limit = limits.get(user_limit, 0)
                    users_limit.update({user: number_of_user_limit})

                with sql.connect(DATABASE) as connection:
                    cursor = connection.cursor()

                    data = [(limit, user_id) for user_id, limit in users_limit.items()]
                    cursor.executemany("UPDATE users SET lplan = ? WHERE user_id = ?", data)
                    connection.commit()

                connection = sql.connect(DATABASE)
                cursor = connection.cursor()

                for user in users:
                    cursor.execute("SELECT rplan FROM users WHERE user_id = ? AND plantype != 'free' AND plantype != 'owner'", (user,))
                    row = cursor.fetchone()

                    if row is None:
                        continue

                    user_rplan = int(row[0])
                    
                    if user_rplan != 0:
                        cursor.execute("UPDATE users SET rplan = rplan - 1 WHERE user_id = ? AND plantype != 'free'", (user,))
                    else:
                        cursor.execute("UPDATE users SET plantype = ?, lplan = ?, rplan = ? WHERE user_id = ?", ('free', 3, 000, user))
                        bot.send_message(user, text=f'⚠️ <b>اطلاعیه</b>\n\n❌کاربر عزیز، مدت زمان اشراک شما به اتمام رسید !\n\nجهت خرید مجدد اشراک از منوی زیر اقدام کنید:', parse_mode='HTML', reply_markup=buy_plan_key)

                connection.commit()
                connection.close()

                length = random.randint(11, 18)
                chars = string.ascii_letters + string.digits
                password = ''.join(random.SystemRandom().choice(chars) for _ in range(length))
                date = get_tehran_time()[0]

                creat_db_backup(password=password, text=f'🗄 نسخه پشتیبان روزانه\n\n📅 تاریخ: {date}\n\n✅ رمز دیتابیس: {password}')

        time.sleep(300)

@bot.message_handler(func=lambda message: message.text == '🆔 جوین اجباری')
def Forced_join(message):
    if message.chat.id == admin_id:
        Forced_join_keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
        Forced_join_keyboard.add('🔒تنظیم کانال', '🔏تنظیم متن')
        Forced_join_keyboard.add('🔙| بازگشت')
        bot.send_message(message.chat.id, text='👈🏻لطفا گزینه مورد نظر را انتخاب کنید:', reply_markup=Forced_join_keyboard)
        
@bot.message_handler(func=lambda message: message.text == '🔏تنظیم متن')
def set_forced_join_text(message):
    if message.chat.id == admin_id:
        msg = bot.send_message(message.chat.id, "لطفا متن جدید جوین اجباری را ارسال کنید:", reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(msg, process_new_forced_join_text)

def process_new_forced_join_text(message):
    global FORCED_JOIN_TEXT
    if message.text != '🔙| بازگشت':
        FORCED_JOIN_TEXT = message.text
        bot.send_message(message.chat.id, "✅ متن جوین اجباری با موفقیت به‌روزرسانی شد.", reply_markup=admins_keyboard)
    else:
        back_admin(message)


@bot.message_handler(func=lambda message: message.text == '🔒تنظیم کانال')
def Channel_setting(message):
    if message.chat.id == admin_id:
        Channel_setting_keybord = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
        Channel_setting_keybord.add('🔓حذف کانال', '🔒افزودن کانال')
        Channel_setting_keybord.add('🔙| بازگشت')

    
        bot.send_message(message.chat.id, text='👈🏻لطفا گزینه مورد نظر را انتخاب کنید:', reply_markup=Channel_setting_keybord)

@bot.message_handler(func=lambda message: message.text == '🔒افزودن کانال')
def add_channel(message):
    
    if message.chat.id == admin_id:
        bot.send_message(message.chat.id, text='🔐لطفا آیدی کانال مورد نظر خود را ارسال کنید:', reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(message, get_channel_id)
    

def get_channel_id(message):
    user_id = message.chat.id
    Channel_id = message.text.lower()
    
    if Channel_id != '🔙| بازگشت':
        if user_id == admin_id:
            if Channel_id.startswith('@'):
                if Channel_id not in CHANNEL_ID:
                    try:
                        bot_member = bot.get_chat_member(chat_id=Channel_id, user_id=bot.get_me().id)
                        if bot_member.status in ['administrator', 'creator']:
                            CHANNEL_ID.append(Channel_id)

                            bot.send_message(user_id, text='✅چنل با موفقیت به جوین اجباری ربات اضافه شد.', reply_markup=admins_keyboard)
                        else:
                            bot.send_message(user_id, text=f'❌ربات در کانال {Channel_id} ادمین نیست', reply_markup=admins_keyboard)
                    except telebot.apihelper.ApiTelegramException as e:
                        if "chat not found" in str(e).lower() or "bot is not a member" in str(e).lower() or "member list is inaccessible" in str(e).lower():
                            bot.send_message(user_id, f'❌ربات در کانال {Channel_id} ادمین نیست', reply_markup=admins_keyboard)
                        else:
                            bot.send_message(user_id, text=f'خطا در بررسی وضعیت ربات:\n {e}', reply_markup=admins_keyboard)
                else:
                    bot.send_message(user_id, text='❗️این چنل درون لیست جوین اجباری قرار دارد.', reply_markup=admins_keyboard)
            else:
                bot.send_message(user_id, text='❗️لطفا یک آیدی صحیح همراه با @ ارسال کنید\nدوباره امتحان کنید:', reply_markup=keyboard_back_admin)
                bot.register_next_step_handler(message, get_channel_id)
    else:
        back_admin(message)
        
@bot.message_handler(func=lambda message: message.text == '🔓حذف کانال')
def delete_channel(message):
    if message.chat.id == admin_id:
        bot.send_message(message.chat.id, text='🔐لطفا آیدی کانال مورد نظر خود را ارسال کنید:')
        bot.register_next_step_handler(message, get_id_delete_channel)

def get_id_delete_channel(message):
    user_id = message.chat.id
    channel_id = message.text.lower()

    if channel_id != '🔙| بازگشت':
        if user_id == admin_id:
            if channel_id.startswith('@'):
                if channel_id in CHANNEL_ID:
                    try:
                        CHANNEL_ID.remove(channel_id)
                        bot.send_message(user_id, text='✅چنل با موفقیت از جوین اجباری ربات حذف شد', reply_markup=admins_keyboard)
                    except Exception as e:
                        bot.send_message(user_id, text=f'خطایی در حذف کانال رخ داده\n{e}', reply_markup=admins_keyboard)
                else:
                    bot.send_message(user_id, text=f'❌کانال {channel_id} در لیست کانال های جوین اجباری وجود ندارد', reply_markup=admins_keyboard)
            else:
                bot.send_message(user_id, text='❗️لطفا یک آیدی صحیح همراه با @ ارسال کنید\nدوباره امتحان کنید:', reply_markup=keyboard_back_admin)
                bot.register_next_step_handler(message, get_channel_id)
    else:
        back_admin(message)


@bot.message_handler(func=lambda message: message.text == '🔎 جستجو ویدیو')
@require_membership
def search_video(message):

    bot.send_message(message.chat.id, text='🆔 آیدی پیچ مورد نظر را وارد کنید: (بدون @)', reply_markup=keyboard_cancel)
    # bot.clear_step_handler()

    bot.register_next_step_handler(message, start_search)

def search_func(username, user_id, start):

    with sql.connect(DATABASE) as connection:
            cursor = connection.cursor()
            cursor.execute("SELECT lplan FROM users WHERE user_id = ?", (user_id,))
            lplan = cursor.fetchone()[0]

    if lplan > 0:
        bot.send_message(user_id, text='⏳ درحال دریافت اطلاعات...')

        while True:

            ydl_opts = {
                "quiet": True,
                "no_warnings": True,
                "extract_flat": False,
                "playliststart": start,
                "playlistend": start + 4,
                "ignoreerrors": True,
            }

            try:
                with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                    info = ydl.extract_info(
                        f"https://www.tiktok.com/@{username}",
                        download=False
                    )

            except Exception as e:
                bot.send_message(admin_id, f"خطایی در سرچ رخ داد:\n\n{e}")
                bot.send_message(user_id, text='خطایی رخ داده، لطفا بعدا تلاش کنید یا به پشتیبانی گزارش دهید')
                return 'Error'
                break

            try:
                videos = list(info.get("entries", []))
            except:
                videos = None

            if not videos:
                bot.send_message(user_id, text="❌ آیدی وارد شده صحیح نیست یا ویدیویی پیدا نشد")
                return 'no id'
                break

            count = 0

            for video in videos:

                if not video:
                    continue

                uploader = video.get("uploader")
                description = video.get("description")
                url = video.get("webpage_url")

                if not url and video.get("id"):
                    url = f"https://www.tiktok.com/@{username}/video/{video['id']}"

                bot.send_message(user_id, text=f'آپلود کننده: {uploader}\n\nتوضیحات: {description}\n\nلینک: {url}')

                count += 1
                    
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("""UPDATE users SET lplan = lplan - 1 WHERE user_id = ?""", (user_id,))
                connection.commit()

            if count == 0:
                bot.send_message(user_id, text="❌ متاسفانه هیچ ویدیوی معتبری پیدا نشد.")
                return 'no video'
                break

            return 'Ok'
    else:
            bot.send_message(user_id, text='❌ ظرفیت جستجو روزانه شما به اتمام رسیده!\n\nلطفا برای ادامه اشتراک تهیه کنید و یا تا فردا صبر کنید.\n\n💎 برای خرید اشتراک از منوی زیر استفاده کنید:', reply_markup=buy_plan_key)
            return 'limit'

def start_search(message):
    username = message.text
    user_id = message.chat.id

    if not username.startswith('@') and username != '🔙 بازگشت به منو':
        try:
        
            status = search_func(username, user_id, 1)

            if status == 'Ok':

                continue_search_key = InlineKeyboardMarkup()
                continue_search_btn = InlineKeyboardButton(text='🔎 جستجو بیشتر', callback_data=f'research_{username}_{1}')
                continue_search_key.add(continue_search_btn)

                bot.send_message(user_id, text='برای سرچ 5 ویدیوی بعد روی دکمه زیر کلیک کنید:👇', reply_markup=continue_search_key)
        except Exception as e:
            bot.send_message(admin_id, text=f'ارور: {e}')
            bot.send_message(user_id, text='لطفا یک بار ربات را /start کنید')
    else:
        if username != '🔙 بازگشت به منو':
            bot.send_message(user_id, text='❌ لطفا آیدی رو بدون (@) وارد کنید.\nدوباره تلاش کن:', reply_markup=keyboard_cancel)
            bot.register_next_step_handler(message, start_search)
        else:
            cancel(message)

@bot.message_handler(func=lambda message: message.text == '🛂 اطلاعات کاربر')
def user_information(message):
    
    if message.chat.id == admin_id:
        bot.send_message(admin_id, text='🆔 لطفا آیدی عددی کاربر مورد نظر را ارسال کنید:', reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(message, search_user)

def search_user(message):

    if message.chat.id == admin_id:
        if message.text != '🔙| بازگشت':
            if message.text:
                user_id = message.text

                all_plan = {
                    'free': '❕رایگان-3',
                    'silver': '💍نقره ای-5',
                    'golden': '👑طلایی-10',
                    'diamond': '💎الماسی-15',
                    'owner': '🎩 مالک-∞'
                }

                date, time = get_tehran_time()


                with sql.connect(DATABASE) as connection:
                    cursor = connection.cursor()
                    cursor.execute("SELECT number_order, plantype, rplan, lplan FROM users WHERE user_id = ?", (user_id,))
                    result = cursor.fetchone()

                if result:
                    number_order, plantype, rplan, lplan = result
                    try:
                        user_info = bot.get_chat(user_id)
                        first_name = user_info.first_name or "نامشخص"
                        username = user_info.username or "نامشخص"
                    except:
                        first_name = "نامشخص"
                        username = "نامشخص"
                    
                    plan_str = all_plan.get(plantype)
                    if isinstance(plan_str, str):
                        name, cap = (plan_str.split('-', 1) + ["نامشخص"])[:2]
                    else:
                        name, cap = "نامشخص", "نامشخص"
                    username_display = f'@{username}' if username != "نامشخص" else username
                    bot.send_message(admin_id, text=(
                        f'✅ اطلاعات کاربر:\n\n'
                        f'نام: {first_name}\n'
                        f'🆔یوزرنیم: {username_display}\n'
                        f'📥تعداد دانلود: {number_order}\n'
                        f'💎نوع اشتراک: {name}\n'
                        f'❕جستجو باقی مانده: {lplan} بار\n'
                        f'❓ اشتراک باقی مانده: {rplan} روز\n'
                        f'🔎ظرفیت جستجو روزانه: {cap} بار\n\n'
                        f'⏳این استعلام در تاریخ {date} و ساعت {time} انجام شده'
                    ), reply_markup=admins_keyboard)

                else:
                    bot.send_message(admin_id, text='❌ کاربری با این آیدی عددی پیدا نشد', reply_markup=admins_keyboard)

            else:
                bot.send_message(admin_id, text='❌ لطفا فقط آیدی عددی ارسال کنید\nدوباره تلاش کن:')
                bot.register_next_step_handler(message, search_user)
        else:
            back_admin(message)

@bot.message_handler(func=lambda message: message.text == '💎 اشتراک کاربر')
def user_plan(message):

    if message.chat.id == admin_id:
        bot.send_message(admin_id, text='🆔 لطفا آیدی عددی کاربر مورد نظر را ارسال کنید:', reply_markup=keyboard_back_admin)
        bot.register_next_step_handler(message, change_user_plan)

def change_user_plan(message):

    if message.chat.id == admin_id:
        if message.text != '🔙| بازگشت':
            if message.text and message.text.isdigit():

                user_id = message.text

                change_user_plan_key = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
                change_user_plan_key.add('♻️ تغییر زمان', '💎 تغییر پلن')
                change_user_plan_key.add('🔙| بازگشت')

                bot.send_message(admin_id, text='✅ لطفا نوع تغییرات را مشخص کنید:', reply_markup=change_user_plan_key)
                bot.register_next_step_handler(message, change_user_plan_type, user_id)
            else:
                bot.send_message(admin_id, text='❌ لطفا فقط آیدی عددی ارسال کنید\nدوباره تلاش کن:')
                bot.register_next_step_handler(message, change_user_plan)
        else:
            back_admin(message)
            
def change_user_plan_type(message, user_id):

    if message.chat.id == admin_id:
        if message.text == '♻️ تغییر زمان':
            bot.send_message(admin_id, text='⏳لطفا زمان مورد نظر برای اتمام اشتراک کاربر را وارد کنید:', reply_markup=keyboard_back_admin)
            bot.register_next_step_handler(message, change_user_plan_time_final, user_id)
            

        elif message.text == '💎 تغییر پلن':

            change_user_plan_key = InlineKeyboardMarkup(row_width=2)

            buttons = [
                InlineKeyboardButton('❕رایگان', callback_data=f'change_plan-free-{user_id}'),
                InlineKeyboardButton('💍نقره ای', callback_data=f'change_plan-silver-{user_id}'),
                InlineKeyboardButton('👑طلایی', callback_data=f'change_plan-golden-{user_id}'),
                InlineKeyboardButton('💎الماسی', callback_data=f'change_plan-diamond-{user_id}'),
                InlineKeyboardButton(text='🔙| بازگشت', callback_data=f'back_admin')
            ]
            change_user_plan_key.add(*buttons)

            bot.send_message(admin_id, text='❓ لطفا نوع پلن را برای تغییر انتخاب کنید:\n\n🎩 لطفا برای تغییر پلن خود به مالک از دستور /owner استفاده کنید', reply_markup=change_user_plan_key)

        elif message.text == '🔙| بازگشت':
            back_admin(message)

        else:
            bot.send_message(admin_id, text='❌ لطفا یکی از دو گزینه مشخص شده را ارسال کنید\nدوباره تلاش کن:')
            bot.register_next_step_handler(message, change_user_plan_type, user_id)

# def change_user_newplan_time_final(message, user_id, new_plan, lplan):

#     if message.chat.id == admin_id:
#         if message.text != '🔙| بازگشت':
#             try:
#                 new_time = int(message.text)
#                 with sql.connect(DATABASE) as connection:
#                     cursor = connection.cursor()
#                     cursor.execute("UPDATE users SET plantype = ?, rplan = ?, lplan = ? WHERE user_id = ?", (new_plan, new_time, lplan, user_id))
#                     connection.commit()
#                 bot.send_message(user_id, text=f'✅ کاربر گرامی، اشتراک شما به {plan_dict[new_plan].split("-")[0]} تغییر کرد !\n\n❕اشتراک جدید شما از همین لحظه فعال شد')
#                 bot.send_message(admin_id, text=f'✅ اشتراک کاربر با موفقیت تغییر کرد !\n\nاطلاعات اشتراک جدید:\n\n💎نوع اشتراک:  {plan_dict[new_plan].split("-")[0]}\n❓ اشتراک باقی مانده: {31 if new_time != 0 else '∞'} روز\n🔎ظرفیت جستجو روزانه: {plan_dict[new_plan].split("-")[1]} بار\n', reply_markup=admins_keyboard)
#             except Exception as e:
#                 print(e)
#                 bot.send_message(admin_id, text='❌ لطفا فقط یک عدد به صورت لاتین ارسال کنید\nدوباره تلاش کن:')
#                 bot.register_next_step_handler(message, change_user_newplan_time_final, user_id, new_plan, lplan)
#         else:
#             back_admin(message)

def change_user_plan_time_final(message, user_id):

    if message.chat.id == admin_id:
        if message.text != '🔙| بازگشت':
            try:
                new_time = int(message.text)
                with sql.connect(DATABASE) as connection:
                    cursor = connection.cursor()
                    cursor.execute("UPDATE users SET rplan = ? WHERE user_id = ?", (new_time, user_id))
                    connection.commit()
                bot.reply_to(message, text='✅ زمان اشتراک با موفقیت تغییر کرد', reply_markup=admins_keyboard)
            except:
                bot.send_message(admin_id, text='❌ لطفا فقط یک عدد به صورت لاتین ارسال کنید\nدوباره تلاش کن:')
                bot.register_next_step_handler(message, change_user_plan_time_final, user_id)
        else:
            back_admin(message)

@bot.message_handler(func=lambda message: 'tiktok.com' in message.text )
def handle_message(message):
    text = message.text.strip()
    user_id = message.chat.id

    if not is_tiktok_url(text):
        bot.reply_to(message, "❌ لطفاً فقط لینک معتبر تیک تاک بفرست")
        return

    msg = bot.reply_to(message, "⏳ در حال دانلود ویدیو...")

    # ====== دانلود و ارسال ======
    try:
        final_url = resolve_tiktok_url(text)
        video_path = download_tiktok(final_url)
        bot.delete_message(message.chat.id, message_id=msg.message_id)
        msg2 = bot.send_message(user_id, "📥 در حال ارسال به تلگرام...")
    except Exception as e:
        print("ERROR DOWNLOAD:", e)
        edite_user(message.chat.id, message)
        if user_id != admin_id:
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("INSERT OR IGNORE INTO Orders (user_id, username, post_link, status) VALUES (?, ?, ?, '❌ دانلود نشده')", (user_id, message.from_user.username, final_url))
                connection.commit()   
        bot.send_message(user_id, text="❌ خطا در دانلود ویدیو")
        return

    try:
        with open(video_path, "rb") as f:
            bot.delete_message(chat_id=user_id, message_id=msg2.message_id)
            time.sleep(0.5) 
            bot.send_video(chat_id=user_id, video=f, caption="🍯 Downloaded by @honey_tiktok_bot", reply_markup=buy_coffe_keyboard)
            bot.send_message(user_id, text='🔙 به منوی اصلی برگشتید:', reply_markup=keyboard)
            
            edite_user(message.chat.id, message)
            
            if user_id != admin_id:
                with sql.connect(DATABASE) as connection:
                    cursor = connection.cursor()
                    cursor.execute("""UPDATE users SET number_order = number_order + 1 WHERE user_id = ?""", (user_id,))
                    cursor.execute("INSERT OR IGNORE INTO Orders (user_id, username, post_link, status) VALUES (?, ?, ?, '✅ دانلود شده')", (user_id, message.from_user.username, final_url))
                    connection.commit()
            
        time.sleep(0.5)
        if os.path.exists(video_path):
            os.remove(video_path)
    except Exception as e:
        print("ERROR SEND:", e)
        
        with sql.connect(DATABASE) as connection:
            cursor = connection.cursor()
            cursor.execute("INSERT OR IGNORE INTO Orders (user_id, username, post_link, status) VALUES (?, ?, ?, '❌ دانلود نشده')", (user_id, message.from_user.username, final_url))
            connection.commit()   
            
        edite_user(message.chat.id, message)
            
        bot.send_message(user_id, text="❌ خطا در دانلود ویدیو")

# def buy_search_coin(message):
#     number_coins = message.text

#     if re.fullmatch(r'[1-9][0-9]*', number_coins):
#         try:
#             number_coins = int(number_coins)
#             price_coin = number_coins * 4000

#             accept_receipt_key = InlineKeyboardMarkup()
#             accept_receipt_btn = InlineKeyboardButton(text='✅ تایید رسید', callback_data=f'accept_receipt_{number_coins}_{price_coin}')
#             accept_receipt_key.add(accept_receipt_btn)

#             bot.send_message(message.chat.id, text=f'✅ لطفا اطلاعات رسید را تایید کنید:\n\nامتیاز: {number_coins}\nمبلغ: {format(price_coin, ',')} تومان\n\n❓آیا این رسید را تایید میکنید؟', reply_markup=accept_receipt_key)

#         except Exception as e:
#             bot.send_message(message.chat.id, text=f'خطایی رخ دااده\n\n{e}')

#     else:
#         if number_coins != '🔙 بازگشت به منو':
#             bot.reply_to(message, text='❌ لطفا عدد را به صورت لاتین و بدون حروف اضافی  ارسال کنید، از اعداد انگلیسی استفاده کنید\nدوباره تلاش کنید:', reply_markup=keyboard_cancel)
#             bot.register_next_step_handler(message, buy_search_coin)
#         else:
#             cancel(message)

def get_receipt(message, name_plan, limit_plan, price_plan):

    user_id = message.chat.id
    Transaction_code = random.randint(100000, 999999)
    view_Transaction_code = f'<code>{Transaction_code}</code>'

    date, time = get_tehran_time()

    photo_id = message.photo[-1].file_id
    file_info = bot.get_file(photo_id)
    image_data = bot.download_file(file_info.file_path)

    with sql.connect(DATABASE) as connection:
        cursor = connection.cursor()
        cursor.execute("INSERT OR IGNORE INTO payments (user_id, username, image, name_plan, limit_plan, price_plan, date, time, Transaction_code, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, '‼️ در انتظار تایید')", (user_id, message.from_user.username, image_data, name_plan, limit_plan, price_plan, date, time, Transaction_code))
        connection.commit()

    confirmation_rejection_key = InlineKeyboardMarkup(row_width=2)
    confirmation_rejection_btn = InlineKeyboardButton(text='❌رد', callback_data=f'rejection-{Transaction_code}-{user_id}')
    confirmation_rejection_btn2 = InlineKeyboardButton(text='✅تایید', callback_data=f'confirmation-{Transaction_code}-{user_id}-{name_plan}-{limit_plan}-{price_plan}')
    confirmation_rejection_key.add(confirmation_rejection_btn, confirmation_rejection_btn2)

    if message.photo:
        file_id = message.photo[-1].file_id

        bot.send_photo(admin_id, photo=file_id, caption=f'🟢رسید جدید ارسال شد\n\n🔎اطلاعات\n👤آیدی: @{message.from_user.username or user_id}\n♻️آیدی عددی: {user_id}\n💎 نام اشتراک: {name_plan}\n🪎مبلغ: {format(int(price_plan), ',')}\n🔑کد پیگیری تراکنش: {Transaction_code}\n\n⏳ زمان و تاریخ: {date} {time}', reply_markup=confirmation_rejection_key)
        bot.send_message(user_id, text=f'✅رسید شما با موفقیت برای پشتیبانی ارسال شد!\n\n🔑کد پیگیری تراکنش: {view_Transaction_code}', parse_mode='html', reply_markup=keyboard)
    else:
        bot.reply_to(message, text='❗️لطفا فقط یک رسید ارسال کنید', reply_markup=keyboard)




@bot.callback_query_handler(func=lambda call: True)
def callback_query(call):

    user_id = call.message.chat.id

    if 'research' in call.data:

        status = search_func(username=call.data.split('_')[1], user_id=user_id, start=int(call.data.split('_')[2]) + 5)

        if status == 'Ok':
            continue_search_key = InlineKeyboardMarkup()

            continue_search_btn = InlineKeyboardButton(text='🔎 جستجو بیشتر', callback_data=f'research_{call.data.split("_")[1]}_{int(call.data.split("_")[2]) + 5}')

            continue_search_key.add(continue_search_btn)

            bot.send_message(user_id, text='برای سرچ 5 ویدیوی بعد روی دکمه زیر کلیک کنید:👇', reply_markup=continue_search_key)
    
    elif call.data in ['silver', 'golden', 'diamond']:
        plan = call.data

        price = {
            'silver': 20000,
            'golden': 40000,
            'diamond': 60000
        }

        name_plan = plan_dict[plan].split('-')[0]
        limit_plan = plan_dict[plan].split('-')[1]
        price_plan = price[plan]

        bot.delete_message(user_id, message_id=call.message.message_id)

        time.sleep(1)

        accept_receipt_key = InlineKeyboardMarkup()
        accept_receipt_btn = InlineKeyboardButton(text='✅ تایید فاکتور', callback_data=f'accept_receipt-{name_plan}-{limit_plan}-{price_plan}')
        accept_receipt_key.add(accept_receipt_btn)

        bot.send_message(user_id, text=f'✅ لطفا اطلاعات فاکتور را تایید کنید:\n\nنام اشتراک: {name_plan}\nجستجو در روز: {limit_plan} بار\nزمان اشتراک: 31 روز\nمبلغ: {format(price_plan, ',')} تومان\n\n❓آیا این رسید را تایید میکنید؟', reply_markup=accept_receipt_key)

    elif 'accept_receipt' in call.data:
        try:
            bot.delete_message(user_id, message_id=call.message.message_id)

            time.sleep(1)

            payment_keyboard = InlineKeyboardMarkup(row_width=2)
            payment_btn = InlineKeyboardButton(text='💳 کارت به کارت', callback_data=f'card_to_card-' + '-'.join(call.data.split('-')[1:4]))
            payment_btn2 = InlineKeyboardButton(text='✅ از طریق بله', callback_data=f'baleh')
            payment_keyboard.add(payment_btn, payment_btn2)
            
            bot.send_message(user_id, text='👇 لطفا روش پرداخت را انتخاب کنید:\n\n💳 کارت به کارت: فعالسازی بعد از تایید ادمین\n\n✅ از طریق بله:  فعالسازی به صورت آنی', reply_markup=payment_keyboard)
        except Exception as e:
            bot.send_message(admin_id, text=f'خطایی رخ داده: {e}')
            bot.send_message(user_id, text='خطایی رخ داده لطفا بعدا تلاش کنید')

    elif 'card_to_card' in call.data:
        try:
            name_plan, limit_plan, price_plan = call.data.split('-')[1: 4]

            bot.delete_message(user_id, message_id=call.message.message_id)

            time.sleep(1)

            view_card_number = f'<code>{card_number}</code>'

            send_receipt_key = InlineKeyboardMarkup().add(
                InlineKeyboardButton('📸 ارسال رسید پرداخت', callback_data=f'send_receipt-{name_plan}-{limit_plan}-{price_plan}')
                )

            bot.send_message(user_id, text=f'🟢لطفا مبلغ ذکر شده را به کارت زیر انتقال دهید:\n\n⚠️در صورت ارسال رسید فیک حساب شما با هر موجودی برای همیشه مسدود میشود.\n\n💳 {view_card_number} - مطلبی\n\n🪎مبلغ: {format(int(price_plan), ',')}\n\n❗️حتما بعد از واریز از طریق دکمه زیر رسید رو برای پشتیبانی ارسال کنید، در صورت ارسال نکردن رسید حساب شما شارژ نمیشود.', reply_markup=send_receipt_key, parse_mode='html')

        except Exception as e:
            bot.send_message(admin_id, text=f'خطایی رخ داده: {e}')
            bot.send_message(user_id, text='خطایی رخ داده، لطفا بعدا دوباره تلاش کنید')

    elif call.data == 'baleh':
        bot.answer_callback_query(call.id, text='به زودی...', show_alert=True)

    elif 'send_receipt' in call.data:
        bot.send_message(user_id, text='💎لطفا رسید کارت به کارت خود را ارسال کنید:\n\n❗️توجه داشتید باشید در رسید تاریخ و روز (ساعت دقیقه و ثانیه) به وضوح مشخص باشد در غیر این صورت رسید شما رد میشود', reply_markup=keyboard_cancel)
        bot.register_next_step_handler(call.message, get_receipt, call.data.split('-')[1], call.data.split('-')[2], call.data.split('-')[3])
    
    elif 'rejection' in call.data:

        Transaction_code, user_id_T = call.data.split('-')[1:]
        try:
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("UPDATE payments SET status = ? WHERE Transaction_code = ?", ('❌ رد شده', Transaction_code))
                connection.commit()

            bot.send_message(user_id_T, text=f'❌رسید ارسالی شما با کد تراکنش {Transaction_code} از طرف ادمین رد شد\n\nدر صورت رخ دادن اشتباه ان را به پشتیبانی گزارش کنید')
            bot.send_message(user_id, text='❌رسید ارسالی با موفقیت رد شد و اعلان برای کاربر ارسال شد')
        except Exception as e:
            bot.send_message(admin_id, text=f'خطایی در رد رسید رخ داد: {e}')
    
    elif 'confirmation' in call.data:

        Transaction_code, user_id_T, name_plan, limit_plan, price_plan = call.data.split('-')[1:]

        plans_dict = {
            '💍نقره ای': 'silver',
            '👑طلایی': 'golden',
            '💎الماسی': 'diamond'
        }

        try:
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("UPDATE payments SET status = ? WHERE Transaction_code = ?", ('✅ تایید شده', Transaction_code))
                cursor.execute("UPDATE users SET plantype = ?, rplan = ?, lplan = ? WHERE user_id = ?", (plans_dict[name_plan], 31, limit_plan, user_id_T))
                connection.commit()

            bot.send_message(user_id_T, text=f'✅ کاربر گرامی، رسید شما با کد پیگیری {Transaction_code} تایید شد !\n\n❕اشتراک شما از همین لحظه فعال شد و محدودیت های قبلی حذف شد')
            bot.send_message(user_id, text='✅ رسید با موفقیت تایید شد و اشتراک برای کاربر فعال شد !')
        except Exception as e:
            bot.send_message(admin_id, text=f'خطایی در تایید رسید رخ داد: {e}')
    
    elif call.data == 'see_user_plan':

        with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("""SELECT SUM(CASE WHEN plantype = 'silver' THEN 1 ELSE 0 END) AS silver, SUM(CASE WHEN plantype = 'golden' THEN 1 ELSE 0 END) AS golden, SUM(CASE WHEN plantype = 'diamond' THEN 1 ELSE 0 END) AS diamond FROM users""")
                silver, golden, diamond = cursor.fetchone()

        plans = {
            'silver': silver,
            'golden': golden,
            'diamond': diamond
        }
        
        bot.send_message(admin_id, text=f"🪎 آمار اشتراک کاربران:\n\n💍 نقره ای: {plans['silver']}\n👑طلایی: {plans['golden']}\n💎الماسی: {plans['diamond']}")

    elif 'change_plan-' in call.data:

        plan, user_id_P = call.data.split('-')[1:]

        time_user_plan_key = InlineKeyboardMarkup(row_width=1)
        time_user_plan_btn1 = InlineKeyboardButton(text='⏳ 31 روز', callback_data=f'change_time_plan-{plan}-{user_id_P}')
        time_user_plan_btn2 = InlineKeyboardButton(text='📝 روز دلخواه', callback_data=f'change_entered_time_plan-{plan}-{user_id_P}')
        time_user_plan_btn3 = InlineKeyboardButton(text='🔙| بازگشت', callback_data=f'back_admin')
        time_user_plan_key.add(time_user_plan_btn1, time_user_plan_btn2, time_user_plan_btn3)

        bot.delete_message(admin_id, call.message.message_id)

        bot.send_message(admin_id, text='♻️ لطفا زمان اشتراک کاربر را انتخاب کنید:', reply_markup=time_user_plan_key)

    elif call.data == 'back_admin':
        bot.delete_message(admin_id, call.message.message_id)
        back_admin(call.message)

    elif 'change_time_plan-' in call.data:

        plan, user_id_P = call.data.split('-')[1:]
        rplan = 0 if plan == "free" else 31

        try:
            with sql.connect(DATABASE) as connection:
                cursor = connection.cursor()
                cursor.execute("UPDATE users SET plantype = ?, rplan = ?, lplan = ? WHERE user_id = ?", (plan, rplan, plan_dict[plan].split('-')[1], user_id_P))
                connection.commit()

                bot.delete_message(admin_id, call.message.message_id)

            bot.send_message(user_id_P, text=f'✅ کاربر گرامی، اشتراک شما به {plan_dict[plan].split("-")[0]} تغییر کرد !\n\n❕اشتراک جدید شما از همین لحظه فعال شد')
            bot.send_message(admin_id, text=f'✅ اشتراک کاربر با موفقیت تغییر کرد !\n\nاطلاعات اشتراک جدید:\n\n💎نوع اشتراک:  {plan_dict[plan].split("-")[0]}\n❓ اشتراک باقی مانده: {31 if rplan != 0 else '∞'} روز\n🔎ظرفیت جستجو روزانه: {plan_dict[plan].split("-")[1]} بار\n', reply_markup=admins_keyboard)
        except Exception as e:
            bot.send_message(admin_id, text=f'خطا در تغییر پلن: {e}')
        
    elif 'change_entered_time_plan' in call.data:

        bot.answer_callback_query(call.id, text='به زودی...', show_alert=True)

    #     plan, user_id_P = call.data.split('-')[1:]

    #     bot.delete_message(admin_id, call.message.message_id)

    #     bot.send_message(admin_id, text='⏳لطفا زمان مورد نظر برای اتمام اشتراک کاربر را وارد کنید:', reply_markup=keyboard_back_admin)
    #     bot.register_next_step_handler(call.message, change_user_newplan_time_final, plan, user_id_P, plan_dict[plan].split('-')[1])


threading.Thread(
    target=check_time_loop,
    daemon=True
).start()


WEBHOOK_URL = "https://yourdomain.com/" + BOT_TOKEN

@app.route('/' + BOT_TOKEN, methods=['POST'])
def webhook():
    json_str = request.get_data().decode('UTF-8')
    update = telebot.types.Update.de_json(json_str)
    bot.process_new_updates([update])
    return 'OK', 200

if name == "main":
    bot.remove_webhook()
    bot.set_webhook(url=WEBHOOK_URL)
