<?php
/**
 * Advanced operations: install self-tests, professional order management,
 * dashboard stats, support tickets, user levels, notices, safe snapshots,
 * rollback, and DB cleanup. Optional and fail-safe: when SQL is disabled it
 * never kills the webhook.
 */

if(!function_exists('bot_adv_settings_defaults')){
function bot_adv_settings_defaults(){
    return [
        'tickets_enabled' => '✅فعال',
        'notices_enabled' => '✅فعال',
        'fraud_new_user_limit_enabled' => '✅فعال',
        'new_user_first_hours' => 24,
        'new_user_order_limit' => 5,
        'default_level' => 'normal',
        'snapshot_keep' => 3,
        'cleanup_days' => 90,
    ];
}}

if(!function_exists('bot_adv_settings')){
function bot_adv_settings(){
    $s = function_exists('bot_data_get_json') ? bot_data_get_json('lib/kodam/data-advanced-tools.json', []) : [];
    if(!is_array($s)) $s = [];
    return array_merge(bot_adv_settings_defaults(), $s);
}}

if(!function_exists('bot_adv_save_settings')){
function bot_adv_save_settings(array $s){
    $s = array_merge(bot_adv_settings_defaults(), $s);
    if(function_exists('bot_data_put_json')) return bot_data_put_json('lib/kodam/data-advanced-tools.json', $s);
    if(!is_dir('lib/kodam')) @mkdir('lib/kodam', 0775, true);
    return @file_put_contents('lib/kodam/data-advanced-tools.json', json_encode($s, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT), LOCK_EX) !== false;
}}

if(!function_exists('bot_adv_install_schema')){
function bot_adv_install_schema(){
    if(!function_exists('bot_sql_pdo')) return false;
    $pdo = bot_sql_pdo();
    if(!$pdo) return false;
    $sqls = [
        "CREATE TABLE IF NOT EXISTS bot_support_tickets (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            ticket_code VARCHAR(32) NOT NULL,
            user_id VARCHAR(32) NOT NULL,
            status VARCHAR(32) NOT NULL DEFAULT 'open',
            priority VARCHAR(20) NOT NULL DEFAULT 'normal',
            subject VARCHAR(191) NULL,
            last_message TEXT NULL,
            last_admin_id VARCHAR(32) NULL,
            last_user_seen_at TIMESTAMP NULL DEFAULT NULL,
            last_admin_seen_at TIMESTAMP NULL DEFAULT NULL,
            data_json LONGTEXT NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            UNIQUE KEY uniq_ticket_code (ticket_code),
            KEY idx_ticket_user (user_id, created_at),
            KEY idx_ticket_status (status, updated_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_support_messages (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            ticket_id BIGINT UNSIGNED NOT NULL,
            sender_id VARCHAR(32) NOT NULL,
            sender_role VARCHAR(20) NOT NULL DEFAULT 'user',
            message_text LONGTEXT NOT NULL,
            data_json LONGTEXT NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            KEY idx_ticket_created (ticket_id, created_at),
            KEY idx_sender_created (sender_id, created_at),
            CONSTRAINT fk_support_messages_ticket FOREIGN KEY (ticket_id) REFERENCES bot_support_tickets(id) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_user_levels (
            user_id VARCHAR(32) NOT NULL PRIMARY KEY,
            level_key VARCHAR(30) NOT NULL DEFAULT 'normal',
            daily_order_limit INT NOT NULL DEFAULT 0,
            note VARCHAR(191) NULL,
            data_json LONGTEXT NULL,
            updated_by VARCHAR(32) NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            KEY idx_level (level_key),
            KEY idx_updated (updated_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_notices (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            title VARCHAR(191) NOT NULL,
            body LONGTEXT NOT NULL,
            status VARCHAR(24) NOT NULL DEFAULT 'active',
            show_once TINYINT(1) NOT NULL DEFAULT 1,
            target_level VARCHAR(30) NULL,
            start_ts BIGINT NOT NULL DEFAULT 0,
            end_ts BIGINT NOT NULL DEFAULT 0,
            created_by VARCHAR(32) NULL,
            data_json LONGTEXT NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            KEY idx_notice_status (status, start_ts, end_ts),
            KEY idx_notice_level (target_level)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_notice_views (
            notice_id BIGINT UNSIGNED NOT NULL,
            user_id VARCHAR(32) NOT NULL,
            viewed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (notice_id, user_id),
            KEY idx_user_notice (user_id, viewed_at),
            CONSTRAINT fk_notice_views_notice FOREIGN KEY (notice_id) REFERENCES bot_notices(id) ON DELETE CASCADE
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_order_status_log (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            order_id VARCHAR(64) NOT NULL,
            old_status VARCHAR(100) NULL,
            new_status VARCHAR(100) NOT NULL,
            actor_id VARCHAR(32) NULL,
            note VARCHAR(191) NULL,
            data_json LONGTEXT NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            KEY idx_order_status_log (order_id, created_at),
            KEY idx_actor_status_log (actor_id, created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
        "CREATE TABLE IF NOT EXISTS bot_install_checks (
            id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            check_key VARCHAR(80) NOT NULL,
            status VARCHAR(20) NOT NULL,
            message VARCHAR(255) NULL,
            data_json LONGTEXT NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            KEY idx_check_created (check_key, created_at),
            KEY idx_check_status (status, created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
    ];
    try{ foreach($sqls as $sql) $pdo->exec($sql); return true; }
    catch(Throwable $e){ error_log('Advanced schema failed: '.$e->getMessage()); return false; }
}}

if(!function_exists('bot_adv_keyboard')){
function bot_adv_keyboard(){
    return json_encode(['keyboard'=>[
        [['text'=>'📊 داشبورد پیشرفته'], ['text'=>'📦 مدیریت سفارش‌ها']],
        [['text'=>'🎫 تیکت‌ها'], ['text'=>'👥 سطح‌بندی کاربران']],
        [['text'=>'📣 اطلاعیه‌ها'], ['text'=>'📜 قوانین و راهنما']],
        [['text'=>'🧪 تست نصب'], ['text'=>'🔄 آپدیت و بازگشت']],
        [['text'=>'🧹 پاکسازی دیتابیس'], ['text'=>'🔙بازگشت به منوی ادمین']],
    ], 'resize_keyboard'=>true], JSON_UNESCAPED_UNICODE);
}}

if(!function_exists('bot_adv_main_text')){
function bot_adv_main_text(){
    $s = bot_adv_settings();
    return "🚀 **امکانات پیشرفته**\n\n".
        "اینجا برای مدیریت سفارش‌ها، تیکت‌ها، سطح کاربران، اطلاعیه‌ها، تست نصب و بکاپ نسخه است.\n\n".
        "تیکت‌ها: **".($s['tickets_enabled']??'✅فعال')."**\n".
        "اطلاعیه‌ها: **".($s['notices_enabled']??'✅فعال')."**\n".
        "تعداد بکاپ نسخه: **".(int)($s['snapshot_keep']??3)." نسخه**";
}}

if(!function_exists('bot_adv_sql_count')){
function bot_adv_sql_count($table, $where='1=1'){
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return 0;
    if(!preg_match('/^[a-zA-Z0-9_]+$/', (string)$table)) return 0;
    try{ return (int)$pdo->query("SELECT COUNT(*) FROM {$table} WHERE {$where}")->fetchColumn(); }
    catch(Throwable $e){ return 0; }
}}

if(!function_exists('bot_adv_dashboard_text')){
function bot_adv_dashboard_text(){
    bot_adv_install_schema();
    $users = bot_adv_sql_count('bot_users');
    $orders = bot_adv_sql_count('bot_orders');
    $activeOrders = bot_adv_sql_count('bot_orders', "status IS NULL OR status NOT IN ('cancelled','canceled','completed','done','deleted')");
    $todayOrders = bot_adv_sql_count('bot_orders', "created_at >= CURDATE()");
    $ticketsOpen = bot_adv_sql_count('bot_support_tickets', "status IN ('open','answered_user')");
    $giftActive = bot_adv_sql_count('bot_gift_codes', "status='active'");
    $reports = bot_adv_sql_count('bot_order_reports', "status='open'");
    $ledgerToday = 0;
    if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){
        try{ $ledgerToday = (int)$pdo->query("SELECT COALESCE(SUM(delta_amount),0) FROM bot_wallet_ledger WHERE created_at >= CURDATE() AND delta_amount > 0")->fetchColumn(); }catch(Throwable $e){}
    }
    return "📊 **داشبورد پیشرفته**\n\n".
        "👤 کاربران: **{$users}**\n".
        "📦 کل سفارش‌ها: **{$orders}**\n".
        "⏳ سفارش فعال: **{$activeOrders}**\n".
        "📅 سفارش امروز: **{$todayOrders}**\n".
        "🎫 تیکت باز: **{$ticketsOpen}**\n".
        "🎁 کد هدیه فعال: **{$giftActive}**\n".
        "🚫 گزارش تخلف باز: **{$reports}**\n".
        "💎 الماس مثبت امروز: **{$ledgerToday}**";
}}

if(!function_exists('bot_adv_order_status_label')){
function bot_adv_order_status_label($s){
    $s = trim((string)$s);
    if($s === '') return 'در انتظار بررسی';
    $map = [
        'pending'=>'در انتظار بررسی', 'queued'=>'در صف انجام', 'running'=>'در حال انجام',
        'completed'=>'تکمیل شده', 'done'=>'تکمیل شده', 'cancelled'=>'لغو شده', 'canceled'=>'لغو شده',
        'admin_cancelled'=>'لغو توسط ادمین', 'user_cancelled'=>'لغو توسط کاربر', 'deleted'=>'حذف شده', 'failed'=>'خطا'
    ];
    return $map[$s] ?? $s;
}}

if(!function_exists('bot_adv_order_text')){
function bot_adv_order_text($orderId){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return '❌ دیتابیس فعال نیست.';
    try{
        $st=$pdo->prepare('SELECT * FROM bot_orders WHERE order_id=? LIMIT 1'); $st->execute([(string)$orderId]); $r=$st->fetch();
        if(!$r) return '❌ سفارش پیدا نشد.';
        $data = json_decode((string)($r['data_json']??''), true); if(!is_array($data)) $data=[];
        $status = bot_adv_order_status_label($r['status'] ?? '');
        $ch = $r['channel_username'] ?: ($data['channel'] ?? '-');
        return "📦 **جزئیات سفارش**\n\n".
            "🆔 سفارش: **{$r['order_id']}**\n".
            "👤 کاربر: **".($r['owner_id']?:'-')."**\n".
            "📣 کانال: **{$ch}**\n".
            "📊 وضعیت: **{$status}**\n".
            "🎯 تعداد هدف: **".(int)$r['target_count']."**\n".
            "✅ دریافت‌شده: **".(int)$r['received_count']."**\n".
            "🚪 لفت: **".(int)$r['left_count']."**\n".
            "🕒 ثبت: **".($r['created_at']??'-')."**";
    }catch(Throwable $e){ return '❌ خطا در خواندن سفارش: '.$e->getMessage(); }
}}

if(!function_exists('bot_adv_order_keyboard')){
function bot_adv_order_keyboard($orderId){
    return json_encode(['inline_keyboard'=>[
        [['text'=>'در صف انجام','callback_data'=>'adv_order_status:'.$orderId.':queued'], ['text'=>'در حال انجام','callback_data'=>'adv_order_status:'.$orderId.':running']],
        [['text'=>'تکمیل شده','callback_data'=>'adv_order_status:'.$orderId.':completed'], ['text'=>'خطا','callback_data'=>'adv_order_status:'.$orderId.':failed']],
        [['text'=>'لغو توسط ادمین','callback_data'=>'adv_order_status:'.$orderId.':admin_cancelled']],
        [['text'=>'🔄 بروزرسانی','callback_data'=>'adv_order_refresh:'.$orderId]],
    ]], JSON_UNESCAPED_UNICODE);
}}

if(!function_exists('bot_adv_set_order_status')){
function bot_adv_set_order_status($orderId, $status, $actorId, $note=''){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return ['ok'=>false,'error'=>'sql_off'];
    try{
        $pdo->beginTransaction();
        $st=$pdo->prepare('SELECT status,data_json FROM bot_orders WHERE order_id=? FOR UPDATE'); $st->execute([(string)$orderId]); $row=$st->fetch();
        if(!$row){ $pdo->rollBack(); return ['ok'=>false,'error'=>'not_found']; }
        $old = (string)($row['status'] ?? '');
        $data = json_decode((string)($row['data_json']??''), true); if(!is_array($data)) $data=[];
        $data['status'] = (string)$status;
        $data['stats'] = bot_adv_order_status_label($status);
        $data['status_updated_at'] = time();
        $data['status_updated_by'] = (string)$actorId;
        $json = json_encode($data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
        $up=$pdo->prepare('UPDATE bot_orders SET status=?, data_json=?, updated_at=CURRENT_TIMESTAMP WHERE order_id=?');
        $up->execute([(string)$status, $json, (string)$orderId]);
        $lg=$pdo->prepare('INSERT INTO bot_order_status_log (order_id,old_status,new_status,actor_id,note,data_json) VALUES (?,?,?,?,?,?)');
        $lg->execute([(string)$orderId, $old, (string)$status, (string)$actorId, (string)$note, '{}']);
        $pdo->commit();
        if(function_exists('bot_cache_invalidate_for_path')) bot_cache_invalidate_for_path('ads/'.(string)$orderId.'.json');
        if(function_exists('bot_admin_log')) bot_admin_log($actorId,'order_status_update','order',$orderId,'تغییر وضعیت سفارش',['old'=>$old,'new'=>$status]);
        return ['ok'=>true,'old'=>$old,'new'=>$status];
    }catch(Throwable $e){ if($pdo->inTransaction()) $pdo->rollBack(); return ['ok'=>false,'error'=>$e->getMessage()]; }
}}

if(!function_exists('bot_adv_recent_orders_text')){
function bot_adv_recent_orders_text($limit=10){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return '❌ دیتابیس فعال نیست.';
    $out = "📦 **آخرین سفارش‌ها**\n\n"; $found=0;
    try{
        $st=$pdo->query('SELECT order_id,owner_id,status,target_count,received_count,created_at FROM bot_orders ORDER BY created_at DESC LIMIT '.max(1,min(20,(int)$limit)));
        foreach($st as $r){ $found++; $out .= "{$found}) `{$r['order_id']}` | کاربر: {$r['owner_id']} | ".bot_adv_order_status_label($r['status'])." | {$r['received_count']}/{$r['target_count']}\n"; }
    }catch(Throwable $e){ return '❌ خطا: '.$e->getMessage(); }
    return $found ? $out."\nبرای مدیریت، آیدی سفارش را ارسال کن." : $out.'سفارشی پیدا نشد.';
}}

if(!function_exists('bot_adv_level_label')){
function bot_adv_level_label($level){
    $map = ['normal'=>'عادی','active'=>'فعال','vip'=>'ویژه','suspicious'=>'مشکوک','blocked'=>'مسدود'];
    return $map[(string)$level] ?? (string)$level;
}}

if(!function_exists('bot_adv_user_level_get')){
function bot_adv_user_level_get($uid){
    bot_adv_install_schema();
    if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){
        try{ $st=$pdo->prepare('SELECT * FROM bot_user_levels WHERE user_id=? LIMIT 1'); $st->execute([(string)$uid]); $r=$st->fetch(); if($r) return $r; }catch(Throwable $e){}
    }
    $s=bot_adv_settings(); return ['user_id'=>(string)$uid,'level_key'=>$s['default_level']??'normal','daily_order_limit'=>0,'note'=>''];
}}

if(!function_exists('bot_adv_user_level_set')){
function bot_adv_user_level_set($uid,$level,$actor){
    bot_adv_install_schema();
    $allowed=['normal','active','vip','suspicious','blocked'];
    if(!in_array($level,$allowed,true)) $level='normal';
    $limitMap=['normal'=>5,'active'=>15,'vip'=>50,'suspicious'=>1,'blocked'=>0];
    if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){
        try{ $st=$pdo->prepare('INSERT INTO bot_user_levels (user_id,level_key,daily_order_limit,updated_by) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE level_key=VALUES(level_key), daily_order_limit=VALUES(daily_order_limit), updated_by=VALUES(updated_by), updated_at=CURRENT_TIMESTAMP'); $st->execute([(string)$uid,$level,(int)$limitMap[$level],(string)$actor]); }catch(Throwable $e){ return false; }
    }
    $list=bot_data_get_json('lib/kodam/list.json',[]); if(!is_array($list))$list=[]; if(!isset($list['ban'])||!is_array($list['ban']))$list['ban']=[];
    $banList = array_map('strval', $list['ban']);
    if($level==='blocked'){
        if(!in_array((string)$uid,$banList,true)) $list['ban'][]=(string)$uid;
    }else{
        $list['ban']=array_values(array_filter($list['ban'], function($x) use ($uid){ return (string)$x !== (string)$uid; }));
    }
    saveJson('lib/kodam/list.json',$list);
    if(function_exists('bot_admin_log')) bot_admin_log($actor,'user_level_set','user',$uid,'تنظیم سطح کاربر',['level'=>$level]);
    return true;
}}

if(!function_exists('bot_adv_level_keyboard')){
function bot_adv_level_keyboard($uid){
    return json_encode(['inline_keyboard'=>[
        [['text'=>'عادی','callback_data'=>'adv_level_set:'.$uid.':normal'], ['text'=>'فعال','callback_data'=>'adv_level_set:'.$uid.':active']],
        [['text'=>'ویژه','callback_data'=>'adv_level_set:'.$uid.':vip'], ['text'=>'مشکوک','callback_data'=>'adv_level_set:'.$uid.':suspicious']],
        [['text'=>'مسدود','callback_data'=>'adv_level_set:'.$uid.':blocked']],
    ]], JSON_UNESCAPED_UNICODE);
}}

if(!function_exists('bot_adv_install_test_text')){
function bot_adv_install_test_text(){
    bot_adv_install_schema();
    $checks=[];
    $checks[]=['PHP >= 8', version_compare(PHP_VERSION,'8.0.0','>='), PHP_VERSION];
    $checks[]=['cURL', function_exists('curl_init'), function_exists('curl_init')?'فعال':'غیرفعال'];
    $checks[]=['PDO MySQL', class_exists('PDO') && in_array('mysql', PDO::getAvailableDrivers(), true), ''];
    $checks[]=['config.php', is_file('config.php'), ''];
    $checks[]=['config_db.php', is_file('config_db.php'), ''];
    $checks[]=['پوشه cache قابل نوشتن', is_writable('cache') || (@mkdir('cache',0775,true) && is_writable('cache')), ''];
    $checks[]=['پوشه lib قابل نوشتن', is_writable('lib'), ''];
    $checks[]=['دکمه جمع‌آوری تنها', trim((string)bot_data_get_text('lib/Button/dok1.txt','')) === '💎 جمع اوری الماس', bot_data_get_text('lib/Button/dok1.txt','')];
    $sqlOk = function_exists('bot_sql_pdo') && bot_sql_pdo();
    $checks[]=['اتصال SQL', (bool)$sqlOk, ''];
    if($sqlOk){ foreach(['bot_users','bot_orders','bot_settings','bot_support_tickets','bot_user_levels','bot_notices'] as $t){ $checks[]=['جدول '.$t, bot_adv_sql_count($t)>=0, '']; } }
    $out="🧪 **تست نصب و سلامت**\n\n"; $bad=0;
    foreach($checks as $c){ $ok=(bool)$c[1]; if(!$ok)$bad++; $out .= ($ok?'✅':'❌').' '.$c[0].($c[2]!==''?' — '.$c[2]:'')."\n"; }
    $out .= "\nنتیجه: ".($bad?"❌ **{$bad} مورد نیاز به بررسی دارد**":"✅ **همه تست‌های اصلی پاس شد**");
    if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){ try{ $st=$pdo->prepare('INSERT INTO bot_install_checks (check_key,status,message,data_json) VALUES (?,?,?,?)'); $st->execute(['runtime_health',$bad?'warning':'ok','admin panel test',json_encode($checks,JSON_UNESCAPED_UNICODE)]); }catch(Throwable $e){} }
    return $out;
}}

if(!function_exists('bot_adv_snapshot_dir')){ function bot_adv_snapshot_dir(){ $d='cache/snapshots'; if(!is_dir($d)) @mkdir($d,0775,true); return $d; }}

if(!function_exists('bot_adv_create_snapshot')){
function bot_adv_create_snapshot(){
    if(!class_exists('ZipArchive')) return ['ok'=>false,'error'=>'ZipArchive روی هاست فعال نیست.'];
    $dir=bot_adv_snapshot_dir(); $file=$dir.'/source_snapshot_'.date('Ymd_His').'.zip';
    $zip=new ZipArchive(); if($zip->open($file, ZipArchive::CREATE|ZipArchive::OVERWRITE)!==true) return ['ok'=>false,'error'=>'ساخت zip ناموفق بود.'];
    $root=realpath('.') ?: getcwd(); $exclude=['/cache/','/photos/','/ads/','/melat/']; $count=0;
    $it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS));
    foreach($it as $path=>$info){
        if(!$info->isFile()) continue; $rel=str_replace('\\','/',substr($path, strlen($root)+1)); $skip=false;
        foreach($exclude as $ex){ if(strpos('/'.$rel, $ex)!==false){ $skip=true; break; } }
        if($skip) continue;
        if(in_array(basename($rel), ['config.php','config_db.php'], true)) continue;
        $zip->addFile($path,$rel); $count++;
    }
    $zip->close();
    $s=bot_adv_settings(); $keep=max(1,(int)($s['snapshot_keep']??3)); $files=glob($dir.'/source_snapshot_*.zip')?:[]; rsort($files); foreach(array_slice($files,$keep) as $old) @unlink($old);
    return ['ok'=>true,'file'=>$file,'count'=>$count,'size'=>@filesize($file)?:0];
}}

if(!function_exists('bot_adv_rollback_latest')){
function bot_adv_rollback_latest(){
    if(!class_exists('ZipArchive')) return ['ok'=>false,'error'=>'ZipArchive فعال نیست.'];
    $files=glob(bot_adv_snapshot_dir().'/source_snapshot_*.zip')?:[]; rsort($files); if(!$files) return ['ok'=>false,'error'=>'نسخه پشتیبان وجود ندارد.'];
    $zip=new ZipArchive(); if($zip->open($files[0])!==true) return ['ok'=>false,'error'=>'بازکردن نسخه پشتیبان ناموفق بود.'];
    $ok=$zip->extractTo('.'); $zip->close(); return ['ok'=>(bool)$ok,'file'=>$files[0]];
}}

if(!function_exists('bot_adv_cleanup')){
function bot_adv_cleanup($days=null){
    bot_adv_install_schema(); $s=bot_adv_settings(); $days=$days===null?(int)($s['cleanup_days']??90):(int)$days; $days=max(7,$days); $res=[];
    if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){
        $queries=[
            'cron_runs'=>"DELETE FROM bot_cron_runs WHERE created_at < DATE_SUB(NOW(), INTERVAL {$days} DAY)",
            'install_checks'=>"DELETE FROM bot_install_checks WHERE created_at < DATE_SUB(NOW(), INTERVAL {$days} DAY)",
            'notice_views'=>"DELETE FROM bot_notice_views WHERE viewed_at < DATE_SUB(NOW(), INTERVAL {$days} DAY)",
        ];
        foreach($queries as $k=>$q){ try{ $res[$k]=$pdo->exec($q); }catch(Throwable $e){ $res[$k]='err'; } }
    }
    foreach(glob('cache/*.lock')?:[] as $f){ @unlink($f); }
    return ['ok'=>true,'days'=>$days,'deleted'=>$res];
}}

if(!function_exists('bot_adv_get_open_ticket')){
function bot_adv_get_open_ticket($uid){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return null;
    try{
        $st=$pdo->prepare("SELECT id,ticket_code,status,subject,updated_at FROM bot_support_tickets WHERE user_id=? AND status<>? ORDER BY id DESC LIMIT 1");
        $st->execute([(string)$uid,'closed']);
        $row=$st->fetch(PDO::FETCH_ASSOC);
        return $row ?: null;
    }catch(Throwable $e){ return null; }
}}

if(!function_exists('bot_adv_open_ticket_text')){
function bot_adv_open_ticket_text($t){
    if(!$t) return '';
    return "🎫 شما یک تیکت باز دارید.\n\nکد پیگیری: **".($t['ticket_code'] ?? '-')."**\nوضعیت: **".($t['status'] ?? '-')."**\nموضوع: **".($t['subject'] ?? '-')."**\n\nتا وقتی ادمین این تیکت را نبندد، تیکت جدید ثبت نمی‌شود.";
}}

if(!function_exists('bot_adv_create_ticket')){
function bot_adv_create_ticket($uid,$text,array $extra=[]){
    bot_adv_install_schema();
    $open = bot_adv_get_open_ticket($uid);
    if($open) return ['ok'=>false,'error'=>'open_ticket_exists','ticket'=>$open];
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return ['ok'=>false,'error'=>'sql_off'];
    try{
        $code='T'.date('ymd').substr((string)abs(crc32($uid.microtime(true))),0,6);
        $cleanText=trim((string)$text);
        $messageText=$cleanText!==''?$cleanText:'[پیام غیرمتنی]';
        $st=$pdo->prepare('INSERT INTO bot_support_tickets (ticket_code,user_id,subject,last_message,data_json) VALUES (?,?,?,?,?)');
        $subject=mb_substr($cleanText,0,60,'UTF-8'); if($subject==='')$subject='پیام پشتیبانی';
        $st->execute([$code,(string)$uid,$subject,$messageText,json_encode($extra,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)]); $id=(int)$pdo->lastInsertId();
        $m=$pdo->prepare('INSERT INTO bot_support_messages (ticket_id,sender_id,sender_role,message_text,data_json) VALUES (?,?,?,?,?)');
        $m->execute([$id,(string)$uid,'user',$messageText,json_encode($extra,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)]);
        return ['ok'=>true,'id'=>$id,'code'=>$code,'ticket'=>['id'=>$id,'ticket_code'=>$code,'user_id'=>(string)$uid,'subject'=>$subject]];
    }catch(Throwable $e){ return ['ok'=>false,'error'=>$e->getMessage()]; }
}}

if(!function_exists('bot_adv_ticket_list_text')){
function bot_adv_ticket_list_text($status='open'){
    bot_adv_install_schema(); if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return '❌ دیتابیس فعال نیست.';
    $out="🎫 **تیکت‌های اخیر**\n\n"; $found=0;
    try{ $st=$pdo->prepare("SELECT id,ticket_code,user_id,status,subject,updated_at FROM bot_support_tickets WHERE status<>? ORDER BY updated_at DESC LIMIT 15"); $st->execute(['closed']); foreach($st as $r){$found++; $out.="{$found}) #{$r['id']} | {$r['ticket_code']} | {$r['user_id']} | {$r['status']}\n{$r['subject']}\n\n";} }catch(Throwable $e){ return '❌ خطا: '.$e->getMessage(); }
    return $found?$out.'برای پاسخ، شماره تیکت را از دکمه پاسخ وارد کن.':$out.'تیکت بازی وجود ندارد.';
}}

if(!function_exists('bot_adv_ticket_keyboard')){
function bot_adv_ticket_keyboard(){ return json_encode(['inline_keyboard'=>[[['text'=>'✍️ پاسخ به تیکت','callback_data'=>'adv_ticket_reply_start'], ['text'=>'✅ بستن تیکت','callback_data'=>'adv_ticket_close_start']]]], JSON_UNESCAPED_UNICODE); }
}
if(!function_exists('bot_adv_ticket_admin_ids')){
function bot_adv_ticket_admin_ids(){
    global $admin;
    $ids=[];
    if(function_exists('bot_runtime_admin_list')) $ids = bot_runtime_admin_list();
    if(!$ids && function_exists('bot_config_master_admin_ids')) $ids = bot_config_master_admin_ids();
    if(!empty($admin)) $ids[] = (string)$admin;
    $out=[];
    foreach((array)$ids as $id){ $id=preg_replace('/[^0-9\-]/','',(string)$id); if($id!=='' && !in_array($id,$out,true)) $out[]=$id; }
    return $out;
}}

if(!function_exists('bot_adv_ticket_action_keyboard')){
function bot_adv_ticket_action_keyboard($ticketId,$userId){
    $ticketId=(int)$ticketId; $userId=preg_replace('/[^0-9\-]/','',(string)$userId);
    $rows=[
        [['text'=>'💬 پاسخ به کاربر','callback_data'=>'adv_ticket_direct_reply:'.$ticketId], ['text'=>'✅ بستن تیکت','callback_data'=>'adv_ticket_direct_close:'.$ticketId]],
        [['text'=>'⚡ پاسخ آماده','callback_data'=>'adv_ticket_quick_menu:'.$ticketId]],
    ];
    $web = function_exists('bot_web_panel_page_url') ? bot_web_panel_page_url('tickets.php') : '';
    if($web !== '') $rows[] = [['text'=>'🌐 مشاهده در پنل وب','url'=>$web]];
    if($userId!=='') $rows[]=[['text'=>'👤 باز کردن چت کاربر','url'=>'tg://user?id='.$userId]];
    return json_encode(['inline_keyboard'=>$rows], JSON_UNESCAPED_UNICODE);
}}

if(!function_exists('bot_adv_message_payload_meta')){
function bot_adv_message_payload_meta($message=null){
    $type='text';
    if(is_object($message)){
        if(isset($message->photo)) $type='photo';
        elseif(isset($message->document)) $type='document';
        elseif(isset($message->video)) $type='video';
        elseif(isset($message->voice)) $type='voice';
        elseif(isset($message->audio)) $type='audio';
        elseif(isset($message->sticker)) $type='sticker';
    }
    return ['message_type'=>$type];
}}

if(!function_exists('bot_adv_api_ok')){
function bot_adv_api_ok($res){
    return is_object($res) && !empty($res->ok);
}}

if(!function_exists('bot_adv_ticket_delivery_error')){
function bot_adv_ticket_delivery_error($res){
    if(is_object($res) && isset($res->description)) return (string)$res->description;
    if(is_string($res)) return $res;
    return 'unknown';
}}

if(!function_exists('bot_adv_ticket_data_array')){
function bot_adv_ticket_data_array(array $ticket){
    $raw = $ticket['data_json'] ?? '';
    if(is_array($raw)) return $raw;
    $j = is_string($raw) && $raw !== '' ? json_decode($raw, true) : [];
    return is_array($j) ? $j : [];
}}

if(!function_exists('bot_adv_ticket_user_chat_id')){
function bot_adv_ticket_user_chat_id(array $ticket){
    $data = bot_adv_ticket_data_array($ticket);
    $candidates = [
        $data['chat_id'] ?? null,
        $data['from_chat_id'] ?? null,
        $ticket['user_id'] ?? null,
    ];
    foreach($candidates as $id){
        $id = preg_replace('/[^0-9\-]/', '', (string)$id);
        if($id !== '') return $id;
    }
    return '';
}}

if(!function_exists('bot_adv_ticket_update_delivery')){
function bot_adv_ticket_update_delivery($ticketId, array $delivery){
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return false;
    try{
        $st=$pdo->prepare('SELECT data_json FROM bot_support_tickets WHERE id=? LIMIT 1');
        $st->execute([(int)$ticketId]);
        $raw=(string)$st->fetchColumn();
        $data=$raw!=='' ? json_decode($raw,true) : [];
        if(!is_array($data)) $data=[];
        $data['last_delivery'] = $delivery + ['at'=>date('c')];
        $up=$pdo->prepare('UPDATE bot_support_tickets SET data_json=? WHERE id=?');
        $up->execute([json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT),(int)$ticketId]);
        return true;
    }catch(Throwable $e){ return false; }
}}

if(!function_exists('bot_adv_send_message_safe')){
function bot_adv_send_message_safe($chatId, $text, $parseMode='HTML', array $extra=[]){
    $chatId = preg_replace('/[^0-9\-]/', '', (string)$chatId);
    $text = (string)$text;
    if($chatId === '' || trim($text) === '') return ['ok'=>false,'error'=>'empty_chat_or_text'];
    $payload = array_merge($extra, ['chat_id'=>$chatId, 'text'=>$text]);
    $pm = trim((string)$parseMode);
    if($pm !== '') $payload['parse_mode'] = $pm;
    $res = bot('sendMessage', $payload);
    if(bot_adv_api_ok($res)) return ['ok'=>true,'response'=>$res,'chat_id'=>$chatId,'method'=>'sendMessage'];
    if($pm !== ''){
        unset($payload['parse_mode']);
        $res2 = bot('sendMessage', $payload);
        if(bot_adv_api_ok($res2)) return ['ok'=>true,'response'=>$res2,'chat_id'=>$chatId,'method'=>'sendMessage_plain'];
        return ['ok'=>false,'response'=>$res2,'chat_id'=>$chatId,'error'=>bot_adv_ticket_delivery_error($res2), 'first_error'=>bot_adv_ticket_delivery_error($res)];
    }
    return ['ok'=>false,'response'=>$res,'chat_id'=>$chatId,'error'=>bot_adv_ticket_delivery_error($res)];
}}

if(!function_exists('bot_adv_send_ticket_text_to_user')){
function bot_adv_send_ticket_text_to_user(array $ticket, $text, $source='ticket_reply', array $extra=[]){
    $ticketId = (int)($ticket['id'] ?? 0);
    $code = (string)($ticket['ticket_code'] ?? '');
    $chatId = bot_adv_ticket_user_chat_id($ticket);
    $safeText = htmlspecialchars((string)$text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    $body = "📩 <b>پاسخ پشتیبانی</b>";
    if($code !== '') $body .= "\nکد تیکت: <code>".htmlspecialchars($code, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')."</code>";
    $body .= "\n\n".$safeText;
    if(!isset($extra['reply_markup']) && function_exists('bot_ticket_miniapp_inline_keyboard')){
        $extra['reply_markup'] = bot_ticket_miniapp_inline_keyboard($ticketId, false);
    }
    $r = bot_adv_send_message_safe($chatId, $body, 'HTML', $extra);
    if($ticketId > 0){
        bot_adv_ticket_update_delivery($ticketId, [
            'source'=>$source,
            'method'=>$r['method'] ?? 'sendMessage',
            'ok'=>!empty($r['ok']),
            'chat_id'=>$chatId,
            'error'=>$r['error'] ?? null,
            'first_error'=>$r['first_error'] ?? null,
        ]);
    }
    return $r;
}}

if(!function_exists('bot_adv_send_ticket_close_to_user')){
function bot_adv_send_ticket_close_to_user(array $ticket, $text=''){
    $ticketId = (int)($ticket['id'] ?? 0);
    $code = (string)($ticket['ticket_code'] ?? '');
    $chatId = bot_adv_ticket_user_chat_id($ticket);
    if($text === '') $text = "✅ تیکت شما بسته شد.";
    $body = htmlspecialchars((string)$text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    if($code !== '') $body .= "\nکد تیکت: <code>".htmlspecialchars($code, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')."</code>";
    $extra = [];
    if(function_exists('bot_ticket_miniapp_inline_keyboard')) $extra['reply_markup'] = bot_ticket_miniapp_inline_keyboard($ticketId, false);
    $r = bot_adv_send_message_safe($chatId, $body, 'HTML', $extra);
    if($ticketId > 0){
        bot_adv_ticket_update_delivery($ticketId, [
            'source'=>'ticket_close',
            'method'=>$r['method'] ?? 'sendMessage',
            'ok'=>!empty($r['ok']),
            'chat_id'=>$chatId,
            'error'=>$r['error'] ?? null,
            'first_error'=>$r['first_error'] ?? null,
        ]);
    }
    return $r;
}}

if(!function_exists('bot_adv_copy_admin_message_to_ticket_user')){
function bot_adv_copy_admin_message_to_ticket_user(array $ticket, $fromChatId, $messageId, $fallbackText=''){
    $ticketId = (int)($ticket['id'] ?? 0);
    $code = (string)($ticket['ticket_code'] ?? '');
    $chatId = bot_adv_ticket_user_chat_id($ticket);
    $header = "💬 <b>پاسخ پشتیبانی</b>";
    if($code !== '') $header .= "\nکد تیکت: <code>".htmlspecialchars($code, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')."</code>";
    $headerExtra = [];
    if(function_exists('bot_ticket_miniapp_inline_keyboard')) $headerExtra['reply_markup'] = bot_ticket_miniapp_inline_keyboard($ticketId, false);
    bot_adv_send_message_safe($chatId, $header, 'HTML', $headerExtra);
    $copy = bot('copyMessage', ['chat_id'=>$chatId, 'from_chat_id'=>$fromChatId, 'message_id'=>(int)$messageId]);
    $ok = bot_adv_api_ok($copy);
    $method = 'copyMessage';
    $err = $ok ? null : bot_adv_ticket_delivery_error($copy);
    if(!$ok && trim((string)$fallbackText) !== ''){
        $fallback = bot_adv_send_ticket_text_to_user($ticket, (string)$fallbackText, 'ticket_direct_reply_fallback');
        $ok = !empty($fallback['ok']);
        $method = $fallback['method'] ?? 'sendMessage_fallback';
        $err = $fallback['error'] ?? $err;
    }
    if($ticketId > 0){
        bot_adv_ticket_update_delivery($ticketId, [
            'source'=>'ticket_direct_reply',
            'method'=>$method,
            'ok'=>$ok,
            'chat_id'=>$chatId,
            'error'=>$err,
        ]);
    }
    return ['ok'=>$ok,'response'=>$copy,'chat_id'=>$chatId,'method'=>$method,'error'=>$err];
}}

if(!function_exists('bot_adv_append_ticket_message')){
function bot_adv_append_ticket_message($ticketId,$senderId,$role,$text,array $extra=[]){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return ['ok'=>false,'error'=>'sql_off'];
    try{
        $ticketId=(int)$ticketId;
        $clean=trim((string)$text);
        $messageText=$clean!==''?$clean:'[پیام غیرمتنی]';
        $m=$pdo->prepare('INSERT INTO bot_support_messages (ticket_id,sender_id,sender_role,message_text,data_json) VALUES (?,?,?,?,?)');
        $m->execute([$ticketId,(string)$senderId,(string)$role,$messageText,json_encode($extra,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)]);
        $status=$role==='admin'?'answered_admin':'answered_user';
        $field=$role==='admin'?'last_admin_seen_at':'last_user_seen_at';
        $up=$pdo->prepare("UPDATE bot_support_tickets SET status=?, last_message=?, {$field}=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP WHERE id=?");
        $up->execute([$status,$messageText,$ticketId]);
        return ['ok'=>true];
    }catch(Throwable $e){ return ['ok'=>false,'error'=>$e->getMessage()]; }
}}

if(!function_exists('bot_adv_ticket_by_id')){
function bot_adv_ticket_by_id($ticketId){
    bot_adv_install_schema();
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return null;
    try{ $st=$pdo->prepare('SELECT * FROM bot_support_tickets WHERE id=? LIMIT 1'); $st->execute([(int)$ticketId]); $row=$st->fetch(PDO::FETCH_ASSOC); return $row?:null; }catch(Throwable $e){ return null; }
}}

if(!function_exists('bot_adv_notify_admins_ticket')){
function bot_adv_notify_admins_ticket(array $ticket,$fromChatId,$messageId,$fallbackText=''){
    $ids=bot_adv_ticket_admin_ids();
    $ticketId=(int)($ticket['id'] ?? 0); $code=(string)($ticket['ticket_code'] ?? ''); $uid=(string)($ticket['user_id'] ?? '');
    $kb=bot_adv_ticket_action_keyboard($ticketId,$uid);
    $sent=0;
    foreach($ids as $aid){
        if($fromChatId && $messageId){
            $forwarded=bot('forwardMessage',['chat_id'=>$aid,'from_chat_id'=>$fromChatId,'message_id'=>(int)$messageId]);
            if(!is_object($forwarded) || empty($forwarded->ok)){
                $copied=bot('copyMessage',['chat_id'=>$aid,'from_chat_id'=>$fromChatId,'message_id'=>(int)$messageId]);
                if(!is_object($copied) || empty($copied->ok)){
                    bot('sendMessage',['chat_id'=>$aid,'text'=>$fallbackText!==''?$fallbackText:'[پیام تیکت]','parse_mode'=>'HTML']);
                }
            }
        }else{
            bot('sendMessage',['chat_id'=>$aid,'text'=>$fallbackText!==''?$fallbackText:'[پیام تیکت]','parse_mode'=>'HTML']);
        }
        $meta="🎫 <b>تیکت پشتیبانی</b>\n".
              "🆔 کد: <code>".htmlspecialchars($code,ENT_QUOTES,'UTF-8')."</code>\n".
              "#️⃣ شماره: <code>{$ticketId}</code>\n".
              "👤 کاربر: <code>".htmlspecialchars($uid,ENT_QUOTES,'UTF-8')."</code>\n\n".
              "برای جواب دادن، دکمه زیر را بزن.";
        bot('sendMessage',['chat_id'=>$aid,'text'=>$meta,'parse_mode'=>'HTML','reply_markup'=>$kb]);
        $sent++;
    }
    return $sent;
}}


if(!function_exists('bot_adv_notice_active_text')){
function bot_adv_notice_active_text($uid){
    bot_adv_install_schema(); $s=bot_adv_settings(); if(($s['notices_enabled']??'✅فعال')!=='✅فعال') return '';
    if(!function_exists('bot_sql_pdo') || !($pdo=bot_sql_pdo())) return '';
    $now=time(); $level=bot_adv_user_level_get($uid)['level_key'] ?? 'normal';
    try{
        $st=$pdo->prepare("SELECT n.* FROM bot_notices n LEFT JOIN bot_notice_views v ON v.notice_id=n.id AND v.user_id=? WHERE n.status='active' AND (n.start_ts=0 OR n.start_ts<=?) AND (n.end_ts=0 OR n.end_ts>=?) AND (n.target_level IS NULL OR n.target_level='' OR n.target_level=?) AND (n.show_once=0 OR v.notice_id IS NULL) ORDER BY n.id DESC LIMIT 1");
        $st->execute([(string)$uid,$now,$now,$level]); $n=$st->fetch(); if(!$n) return '';
        if((int)$n['show_once']===1){ $ins=$pdo->prepare('INSERT IGNORE INTO bot_notice_views (notice_id,user_id) VALUES (?,?)'); $ins->execute([(int)$n['id'],(string)$uid]); }
        return "📣 **".$n['title']."**\n\n".$n['body'];
    }catch(Throwable $e){ return ''; }
}}

if(!function_exists('bot_adv_runtime_router')){
function bot_adv_runtime_router(){
    global $msg,$data,$Tc,$isAdmin,$chatID,$userID,$msg_id,$user,$Button_Panel,$data_id,$admin;
    bot_adv_install_schema();
    $step = is_array($user) ? (string)($user['step'] ?? '') : '';

    // User-side support tickets.
    if((string)$Tc === 'private' && empty($isAdmin)){
        $miniTicketTexts = ['🎫 پشتیبانی','🎫 تیکت پشتیبانی','پشتیبانی','تیکت','ثبت تیکت','📨 پشتیبانی','📩 پشتیبانی'];
        $legacyTicketRequest = ((string)$data === 'adv_user_ticket_legacy');
        if(in_array((string)$msg, ['🎫 وضعیت تیکت','وضعیت تیکت','پیگیری تیکت'], true)){
            if(function_exists('bot_ticket_miniapp_send_entry')){
                bot_ticket_miniapp_send_entry($chatID, $userID, $msg_id);
                return true;
            }
            $open = bot_adv_get_open_ticket($userID);
            if($open){
                SM($chatID, bot_adv_open_ticket_text($open), 'MarkDown', $msg_id); return true;
            }
            SM($chatID, '🎫 تیکت بازی برای شما ثبت نشده است.
برای ارسال پیام به پشتیبانی، دکمه «🎫 پشتیبانی» را بزن.', 'MarkDown', $msg_id); return true;
        }
        if((in_array((string)$msg, $miniTicketTexts, true) || (string)$data === 'adv_user_ticket_new') && !$legacyTicketRequest){
            if(($s=bot_adv_settings()) && ($s['tickets_enabled']??'✅فعال') !== '✅فعال') { SM($chatID,'❌ پشتیبانی موقتاً غیرفعال است.','MarkDown',$msg_id); return true; }
            if(!empty($data_id)) bot('answercallbackquery', ['callback_query_id'=>$data_id, 'text'=>'مینی‌اپ پشتیبانی را باز کن', 'show_alert'=>false]);
            if(function_exists('bot_ticket_miniapp_send_entry')) bot_ticket_miniapp_send_entry($chatID, $userID, $msg_id);
            else SM($chatID,'🎫 مینی‌اپ پشتیبانی در این نسخه لود نشده است. از دکمه ارسال داخل چت استفاده کن.','MarkDown',$msg_id, bot_adv_ticket_keyboard());
            return true;
        }
        if($legacyTicketRequest || in_array((string)$msg, ['✍️ ارسال تیکت داخل چت ربات'], true)){
            if(($s=bot_adv_settings()) && ($s['tickets_enabled']??'✅فعال') !== '✅فعال') { SM($chatID,'❌ پشتیبانی موقتاً غیرفعال است.','MarkDown',$msg_id); return true; }
            if(!empty($data_id)) bot('answercallbackquery', ['callback_query_id'=>$data_id, 'text'=>'پیام خود را داخل چت بفرست', 'show_alert'=>false]);
            $open = bot_adv_get_open_ticket($userID);
            if($open){
                $user['step']='adv_ticket_wait_existing:'.(int)$open['id']; saveJson('melat/'.$userID.'.json',$user);
                SM($chatID, bot_adv_open_ticket_text($open)."

✍️ پیام جدیدت را ارسال کن تا زیر همین تیکت برای ادمین برود.
برای لغو، دکمه بازگشت را بزن.", 'MarkDown', $msg_id, json_encode(['keyboard'=>[[['text'=>'🔙 بازگشت']]],'resize_keyboard'=>true],JSON_UNESCAPED_UNICODE)); return true;
            }
            $user['step']='adv_ticket_wait'; saveJson('melat/'.$userID.'.json',$user);
            SM($chatID,'🎫 پیام پشتیبانی خود را ارسال کن.

می‌توانی متن، عکس یا فایل بفرستی. پیام تو مستقیم برای ادمین‌ها می‌رود و زیرش دکمه پاسخ نمایش داده می‌شود.','MarkDown',$msg_id,json_encode(['keyboard'=>[[['text'=>'🔙 بازگشت']]],'resize_keyboard'=>true],JSON_UNESCAPED_UNICODE)); return true;
        }
        if(($step === 'adv_ticket_wait' || preg_match('/^adv_ticket_wait_existing:(\d+)$/',(string)$step,$existingTicket)) && !bot_is_menu_back_text($msg)){
            $extra = bot_adv_message_payload_meta($message ?? null) + ['from_chat_id'=>$chatID,'message_id'=>$msg_id,'username'=>$username ?? '', 'first_name'=>$first_name ?? ''];
            if(!empty($existingTicket[1])){
                $tid=(int)$existingTicket[1];
                $t=bot_adv_ticket_by_id($tid);
                $r=bot_adv_append_ticket_message($tid,$userID,'user',(string)$msg,$extra);
                if($t){ $t['id']=$tid; }
            }else{
                $r=bot_adv_create_ticket($userID,(string)$msg,$extra);
                $tid=(int)($r['id'] ?? 0);
                $t=$r['ticket'] ?? ['id'=>$tid,'ticket_code'=>$r['code'] ?? '', 'user_id'=>(string)$userID];
            }
            $user['step']='none'; saveJson('melat/'.$userID.'.json',$user);
            if(!empty($r['ok'])){
                bot_adv_notify_admins_ticket($t,$chatID,$msg_id,(string)$msg);
                $code=(string)($t['ticket_code'] ?? ($r['code'] ?? ''));
                SM($chatID,"✅ پیام شما برای پشتیبانی ارسال شد.
کد پیگیری: **{$code}**",'MarkDown',$msg_id);
            } else SM($chatID,'❌ خطا در ثبت تیکت. چند دقیقه بعد دوباره تلاش کن.','MarkDown',$msg_id);
            return true;
        }
        // One-time notice after /start or main interactions. Do not block the normal handler.
        return false;
    }

    if(empty($isAdmin) || (isset($Tc) && (string)$Tc !== 'private')) return false;

    if($msg === '🚀 امکانات پیشرفته'){
        if(is_array($user)){ $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); }
        if(function_exists('bot_admin_log')) bot_admin_log($userID,'open_advanced_tools','panel',null,'باز کردن امکانات پیشرفته');
        SM($chatID, bot_adv_main_text(), 'MarkDown', $msg_id, bot_adv_keyboard()); return true;
    }
    if($msg === '📊 داشبورد پیشرفته'){ SM($chatID, bot_adv_dashboard_text(), 'MarkDown', $msg_id, bot_adv_keyboard()); return true; }
    if($msg === '🧪 تست نصب'){ SM($chatID, bot_adv_install_test_text(), 'MarkDown', $msg_id, bot_adv_keyboard()); return true; }

    if($msg === '📦 مدیریت سفارش‌ها'){
        $user['step']='adv_order_lookup'; saveJson('melat/'.$userID.'.json',$user);
        SM($chatID, bot_adv_recent_orders_text(10)."\n\nآیدی سفارش را ارسال کن:", 'MarkDown', $msg_id, bot_adv_keyboard()); return true;
    }
    if($step === 'adv_order_lookup' && !bot_is_menu_back_text($msg)){
        $oid=trim((string)$msg); $user['step']='none'; saveJson('melat/'.$userID.'.json',$user);
        SM($chatID, bot_adv_order_text($oid), 'MarkDown', $msg_id, bot_adv_order_keyboard($oid)); return true;
    }
    if(preg_match('/^adv_order_status:([^:]+):([a-z_]+)$/',(string)$data,$m)){
        $r=bot_adv_set_order_status($m[1],$m[2],$userID,'admin_panel');
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>!empty($r['ok'])?'ثبت شد':'خطا','show_alert'=>false]);
        bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>bot_adv_order_text($m[1]),'parse_mode'=>'MarkDown','reply_markup'=>bot_adv_order_keyboard($m[1])]); return true;
    }
    if(preg_match('/^adv_order_refresh:([^:]+)$/',(string)$data,$m)){
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'بروزرسانی شد','show_alert'=>false]);
        bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>bot_adv_order_text($m[1]),'parse_mode'=>'MarkDown','reply_markup'=>bot_adv_order_keyboard($m[1])]); return true;
    }

    if($msg === '👥 سطح‌بندی کاربران'){
        $user['step']='adv_level_lookup'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'آیدی عددی کاربر را ارسال کن:','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    if($step === 'adv_level_lookup' && !bot_is_menu_back_text($msg)){
        $uid=preg_replace('/[^0-9]/','',(string)$msg); $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); $lev=bot_adv_user_level_get($uid);
        SM($chatID,"👥 سطح فعلی کاربر **{$uid}**: **".bot_adv_level_label($lev['level_key']??'normal')."**\nمحدودیت روزانه: **".(int)($lev['daily_order_limit']??0)."**",'MarkDown',$msg_id,bot_adv_level_keyboard($uid)); return true;
    }
    if(preg_match('/^adv_level_set:(\d+):([a-z_]+)$/',(string)$data,$m)){
        bot_adv_user_level_set($m[1],$m[2],$userID); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'سطح ثبت شد','show_alert'=>false]);
        $lev=bot_adv_user_level_get($m[1]); bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>"✅ سطح کاربر **{$m[1]}** شد: **".bot_adv_level_label($lev['level_key']??'normal')."**",'parse_mode'=>'MarkDown','reply_markup'=>bot_adv_level_keyboard($m[1])]); return true;
    }

    if($msg === '🎫 تیکت‌ها'){ SM($chatID, bot_adv_ticket_list_text(), 'MarkDown', $msg_id, bot_adv_ticket_keyboard()); return true; }
    if(preg_match('/^adv_ticket_quick_menu:(\d+)$/',(string)$data,$m)){
        $tid=(int)$m[1]; $t=bot_adv_ticket_by_id($tid);
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>$t?'پاسخ‌های آماده':'تیکت پیدا نشد','show_alert'=>!$t]);
        if(!$t) return true;
        $kb=function_exists('bot_canned_keyboard') ? bot_canned_keyboard('tickets','adv_ticket_quick',$tid,'adv_ticket_back') : bot_adv_ticket_action_keyboard($tid,$t['user_id']);
        bot('editMessageText',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>'⚡ <b>پاسخ آماده تیکت</b>

یکی از پاسخ‌های آماده را انتخاب کن. متن از پنل وب قابل تغییر است.','parse_mode'=>'HTML','reply_markup'=>$kb]);
        return true;
    }
    if(preg_match('/^adv_ticket_back:(\d+)$/',(string)$data,$m)){
        $tid=(int)$m[1]; $t=bot_adv_ticket_by_id($tid);
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'بازگشت','show_alert'=>false]);
        if($t) bot('editMessageText',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>'🎫 <b>مدیریت تیکت</b>

تیکت: <code>'.$tid.'</code>
کاربر: <code>'.htmlspecialchars((string)$t['user_id'],ENT_QUOTES,'UTF-8').'</code>','parse_mode'=>'HTML','reply_markup'=>bot_adv_ticket_action_keyboard($tid,$t['user_id'])]);
        return true;
    }
    if(preg_match('/^adv_ticket_quick:(\d+):([A-Za-z0-9_\-]+)$/',(string)$data,$m)){
        $tid=(int)$m[1]; $key=(string)$m[2]; $t=bot_adv_ticket_by_id($tid); $reply=function_exists('bot_canned_get')?bot_canned_get('tickets',$key):null;
        if(!$t || !$reply){ bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'پاسخ یا تیکت پیدا نشد','show_alert'=>true]); return true; }
        $replyText = (string)($reply['text'] ?? '');
        $delivery = bot_adv_send_ticket_text_to_user($t, $replyText, 'ticket_quick_reply');
        bot_adv_append_ticket_message($tid,$userID,'admin',$replyText,['canned_key'=>$key,'canned_title'=>$reply['title'] ?? '', 'delivery_ok'=>!empty($delivery['ok']), 'delivery_error'=>$delivery['error'] ?? null]);
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>!empty($delivery['ok'])?'پاسخ آماده ارسال شد':'پاسخ ثبت شد ولی ارسال ناموفق بود','show_alert'=>empty($delivery['ok'])]);
        $deliveryText = !empty($delivery['ok']) ? '✅ پاسخ آماده مستقیم برای کاربر <code>'.htmlspecialchars((string)$t['user_id'],ENT_QUOTES,'UTF-8').'</code> ارسال شد.' : '⚠️ پاسخ در تیکت ثبت شد، اما ارسال به کاربر ناموفق بود.<br>علت احتمالی: کاربر ربات را بلاک کرده یا هنوز /start نکرده است.<br>خطا: <code>'.htmlspecialchars((string)($delivery['error'] ?? 'unknown'),ENT_QUOTES,'UTF-8').'</code>';
        bot('editMessageText',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>$deliveryText,'parse_mode'=>'HTML','reply_markup'=>bot_adv_ticket_action_keyboard($tid,$t['user_id'])]);
        return true;
    }
    if(preg_match('/^adv_ticket_direct_reply:(\d+)$/',(string)$data,$m)){
        $tid=(int)$m[1]; $t=bot_adv_ticket_by_id($tid);
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>$t?'پاسخ را ارسال کن':'تیکت پیدا نشد','show_alert'=>!$t]);
        if(!$t) return true;
        $user['step']='adv_ticket_direct_reply:'.$tid; saveJson('melat/'.$userID.'.json',$user);
        SM($chatID,"💬 پاسخ خودت را برای کاربر <code>{$t['user_id']}</code> ارسال کن.\n\nمی‌توانی متن، عکس یا فایل بفرستی؛ ربات بدون ذخیره روی هاست آن را برای کاربر کپی می‌کند.",'html',null,(function_exists('bot_state_cancel_keyboard')?bot_state_cancel_keyboard(true):bot_adv_keyboard())); return true;
    }
    if(preg_match('/^adv_ticket_direct_close:(\d+)$/',(string)$data,$m)){
        $tid=(int)$m[1]; $t=bot_adv_ticket_by_id($tid);
        if($t && function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){ try{ $pdo->prepare("UPDATE bot_support_tickets SET status='closed', updated_at=CURRENT_TIMESTAMP WHERE id=?")->execute([$tid]); }catch(Throwable $e){} }
        bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>$t?'تیکت بسته شد':'تیکت پیدا نشد','show_alert'=>false]);
        if($t){ bot_adv_send_ticket_close_to_user($t, '✅ تیکت شما بسته شد.'); bot('editMessageReplyMarkup',['chat_id'=>$chatID,'message_id'=>$msg_id,'reply_markup'=>json_encode(['inline_keyboard'=>[[['text'=>'✅ تیکت بسته شد','callback_data'=>'noop']]]],JSON_UNESCAPED_UNICODE)]); }
        return true;
    }
    if(preg_match('/^adv_ticket_direct_reply:(\d+)$/',(string)$step,$m) && !bot_is_menu_back_text($msg)){
        $tid=(int)$m[1]; $t=bot_adv_ticket_by_id($tid);
        if(!$t){ $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'❌ تیکت پیدا نشد.','html',$msg_id,bot_adv_keyboard()); return true; }
        $delivery = bot_adv_copy_admin_message_to_ticket_user($t, $chatID, $msg_id, (string)$msg);
        $extra=bot_adv_message_payload_meta($message ?? null) + ['from_chat_id'=>$chatID,'message_id'=>$msg_id,'delivery_ok'=>!empty($delivery['ok']),'delivery_method'=>$delivery['method'] ?? '', 'delivery_error'=>$delivery['error'] ?? null];
        bot_adv_append_ticket_message($tid,$userID,'admin',(string)$msg,$extra);
        $user['step']='none'; saveJson('melat/'.$userID.'.json',$user);
        if(!empty($delivery['ok'])) SM($chatID,"✅ پاسخ مستقیم برای کاربر <code>{$t['user_id']}</code> ارسال شد.",'html',$msg_id,bot_adv_ticket_action_keyboard($tid,$t['user_id']));
        else SM($chatID,"⚠️ پاسخ در تیکت ثبت شد، اما ارسال به کاربر ناموفق بود.\n\nعلت معمول: کاربر ربات را بلاک کرده یا هنوز /start نکرده است. بسته بودن فوروارد دیگر مانع شناسایی کاربر نیست.\nخطا: <code>".htmlspecialchars((string)($delivery['error'] ?? 'unknown'),ENT_QUOTES,'UTF-8')."</code>",'html',$msg_id,bot_adv_ticket_action_keyboard($tid,$t['user_id']));
        return true;
    }
    if($data === 'adv_ticket_reply_start'){
        $user['step']='adv_ticket_reply_id'; saveJson('melat/'.$userID.'.json',$user); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'شماره تیکت را ارسال کن','show_alert'=>false]); SM($chatID,'شماره عددی تیکت را ارسال کن:','MarkDown',null,bot_adv_keyboard()); return true;
    }
    if($step === 'adv_ticket_reply_id' && !bot_is_menu_back_text($msg)){
        $tid=(int)preg_replace('/[^0-9]/','',(string)$msg); $user['step']='adv_ticket_direct_reply:'.$tid; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'پاسخ را ارسال کن:','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    if($data === 'adv_ticket_close_start'){
        $user['step']='adv_ticket_close_id'; saveJson('melat/'.$userID.'.json',$user); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'شماره تیکت را ارسال کن','show_alert'=>false]); SM($chatID,'شماره تیکت برای بستن را ارسال کن:','MarkDown',null,bot_adv_keyboard()); return true;
    }
    if($step === 'adv_ticket_close_id' && !bot_is_menu_back_text($msg)){
        $tid=(int)preg_replace('/[^0-9]/','',(string)$msg); $closedTicket=null; if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){ try{ $closedTicket=bot_adv_ticket_by_id($tid); $pdo->prepare("UPDATE bot_support_tickets SET status='closed' WHERE id=?")->execute([$tid]); }catch(Throwable $e){} }
        $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'✅ تیکت بسته شد.','MarkDown',$msg_id,bot_adv_keyboard()); if($closedTicket) bot_adv_send_ticket_close_to_user($closedTicket,'✅ تیکت شما بسته شد. اگر هنوز مشکلی داری می‌توانی تیکت جدید ثبت کنی.'); return true;
    }

    if($msg === '📣 اطلاعیه‌ها'){
        $kb=json_encode(['inline_keyboard'=>[[['text'=>'➕ اطلاعیه جدید','callback_data'=>'adv_notice_new'],['text'=>'📋 لیست اطلاعیه‌ها','callback_data'=>'adv_notice_list']]]],JSON_UNESCAPED_UNICODE);
        SM($chatID,'📣 مدیریت اطلاعیه‌ها\n\nبرای ساخت اطلاعیه، عنوان و متن را در مراحل بعد وارد کن.','MarkDown',$msg_id,$kb); return true;
    }
    if($data === 'adv_notice_new'){
        $user['step']='adv_notice_title'; saveJson('melat/'.$userID.'.json',$user); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>'عنوان را ارسال کن','show_alert'=>false]); SM($chatID,'عنوان اطلاعیه را ارسال کن:','MarkDown',null,bot_adv_keyboard()); return true;
    }
    if($step === 'adv_notice_title' && !bot_is_menu_back_text($msg)){
        $user['step']='adv_notice_body:'.base64_encode((string)$msg); saveJson('melat/'.$userID.'.json',$user); SM($chatID,'متن اطلاعیه را ارسال کن:','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    if(preg_match('/^adv_notice_body:(.+)$/',$step,$m) && !bot_is_menu_back_text($msg)){
        $title=base64_decode($m[1]); if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){ try{ $st=$pdo->prepare('INSERT INTO bot_notices (title,body,status,show_once,created_by) VALUES (?,?,?,?,?)'); $st->execute([(string)$title,(string)$msg,'active',1,(string)$userID]); }catch(Throwable $e){} }
        $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'✅ اطلاعیه فعال شد.','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    if($data === 'adv_notice_list'){
        $text="📋 **اطلاعیه‌های اخیر**\n\n"; $found=0; if(function_exists('bot_sql_pdo') && ($pdo=bot_sql_pdo())){ try{ foreach($pdo->query('SELECT id,title,status,created_at FROM bot_notices ORDER BY id DESC LIMIT 10') as $r){ $found++; $text.="#{$r['id']} | {$r['status']} | {$r['title']} | {$r['created_at']}\n"; } }catch(Throwable $e){} } if(!$found)$text.='اطلاعیه‌ای ثبت نشده است.'; bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>$text,'parse_mode'=>'MarkDown']); return true;
    }

    if($msg === '📜 قوانین و راهنما'){
        $user['step']='adv_rules_text'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'متن قوانین/راهنمای عمومی را ارسال کن. این متن در فایل تنظیمات ذخیره می‌شود.','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    if($step === 'adv_rules_text' && !bot_is_menu_back_text($msg)){
        bot_data_put_text('lib/Button/doktxt11.txt',(string)$msg); $user['step']='none'; saveJson('melat/'.$userID.'.json',$user); SM($chatID,'✅ متن راهنما ذخیره شد.','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }

    if($msg === '🔄 آپدیت و بازگشت'){
        if(function_exists('bot_admin_tools_is_owner') && !bot_admin_tools_is_owner($userID)) return bot_admin_tools_sensitive_denied('آپدیت و بازگشت');
        $kb=json_encode(['inline_keyboard'=>[[['text'=>'📸 ساخت نسخه پشتیبان','callback_data'=>'adv_snapshot_make'],['text'=>'↩️ بازگشت به آخرین نسخه پشتیبان','callback_data'=>'adv_snapshot_rollback_confirm']]]],JSON_UNESCAPED_UNICODE);
        SM($chatID,'🔄 **آپدیت امن و بازگشت**\n\nقبل از هر آپدیت نسخه پشتیبان بگیر. اگر آپدیت خراب شد، از آخرین نسخه پشتیبان برگردان.','MarkDown',$msg_id,$kb); return true;
    }
    if($data === 'adv_snapshot_make'){
        if(function_exists('bot_admin_tools_is_owner') && !bot_admin_tools_is_owner($userID)) return bot_admin_tools_sensitive_denied('ساخت نسخه پشتیبان سورس');
        $r=bot_adv_create_snapshot(); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>!empty($r['ok'])?'نسخه پشتیبان ساخته شد':'خطا','show_alert'=>false]);
        $txt=!empty($r['ok'])?'✅ نسخه پشتیبان ساخته شد\nفایل: **'.basename($r['file'])."**\nتعداد فایل: **{$r['count']}**":'❌ خطا: '.($r['error']??'نامشخص'); bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>$txt,'parse_mode'=>'MarkDown']); return true;
    }
    if($data === 'adv_snapshot_rollback_confirm'){
        if(function_exists('bot_admin_tools_is_owner') && !bot_admin_tools_is_owner($userID)) return bot_admin_tools_sensitive_denied('بازگشت نسخه سورس');
        $kb=json_encode(['inline_keyboard'=>[[['text'=>'⚠️ تایید بازگشت','callback_data'=>'adv_snapshot_rollback_do']]]],JSON_UNESCAPED_UNICODE);
        bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>'⚠️ با تایید، فایل‌های سورس از آخرین نسخه پشتیبان جایگزین می‌شوند. config و دیتابیس دست‌نخورده می‌مانند.','parse_mode'=>'MarkDown','reply_markup'=>$kb]); return true;
    }
    if($data === 'adv_snapshot_rollback_do'){
        if(function_exists('bot_admin_tools_is_owner') && !bot_admin_tools_is_owner($userID)) return bot_admin_tools_sensitive_denied('بازگشت نسخه سورس');
        $r=bot_adv_rollback_latest(); bot('answercallbackquery',['callback_query_id'=>$data_id,'text'=>!empty($r['ok'])?'بازگشت انجام شد':'خطا','show_alert'=>true]); bot('editmessagetext',['chat_id'=>$chatID,'message_id'=>$msg_id,'text'=>!empty($r['ok'])?'✅ بازگشت انجام شد.':'❌ خطا: '.($r['error']??'نامشخص'),'parse_mode'=>'MarkDown']); return true;
    }

    if($msg === '🧹 پاکسازی دیتابیس'){
        if(function_exists('bot_admin_tools_is_owner') && !bot_admin_tools_is_owner($userID)) return bot_admin_tools_sensitive_denied('پاکسازی دیتابیس');
        $r=bot_adv_cleanup(); SM($chatID,'✅ پاکسازی انجام شد.\nروز نگهداری: **'.$r['days'].'**\n`'.json_encode($r['deleted'],JSON_UNESCAPED_UNICODE).'`','MarkDown',$msg_id,bot_adv_keyboard()); return true;
    }
    return false;
}}

if(!function_exists('bot_adv_notice_guard')){
function bot_adv_notice_guard(){
    global $Tc,$isAdmin,$userID,$msg;
    if((string)$Tc !== 'private' || !empty($isAdmin) || empty($userID)) return;
    if((string)$msg === '/start' || (string)$msg === '🔙 بازگشت' || (string)$msg === '🔙بازگشت به منو'){
        $txt=bot_adv_notice_active_text($userID); if($txt!=='') SM($userID,$txt,'MarkDown');
    }
}}

?>
