<?php
// Configurable anti-spam guard for normal users.
// Admins can configure threshold, check window, and block duration from management panel.

if(!function_exists('bot_antispam_defaults')){
    function bot_antispam_defaults(){
        return [
            'enabled' => '✅فعال',
            'max_messages' => 5,
            'window_seconds' => 10,
            'block_minutes' => 3,
        ];
    }
}

if(!function_exists('bot_antispam_settings')){
    function bot_antispam_settings(){
        $defaults = bot_antispam_defaults();
        $s = function_exists('bot_data_get_json') ? bot_data_get_json('lib/kodam/data-antispam.json', $defaults) : $defaults;
        if(!is_array($s)) $s = [];
        $s = array_merge($defaults, $s);
        $s['enabled'] = ((string)($s['enabled'] ?? '') === '❌غیر فعال') ? '❌غیر فعال' : '✅فعال';
        $s['max_messages'] = max(2, min(100, (int)($s['max_messages'] ?? 5)));
        $s['window_seconds'] = max(2, min(600, (int)($s['window_seconds'] ?? 10)));
        $s['block_minutes'] = max(1, min(1440, (int)($s['block_minutes'] ?? 3)));
        return $s;
    }
}

if(!function_exists('bot_antispam_save_settings')){
    function bot_antispam_save_settings(array $settings){
        $s = array_merge(bot_antispam_defaults(), $settings);
        $s['enabled'] = ((string)($s['enabled'] ?? '') === '❌غیر فعال') ? '❌غیر فعال' : '✅فعال';
        $s['max_messages'] = max(2, min(100, (int)($s['max_messages'] ?? 5)));
        $s['window_seconds'] = max(2, min(600, (int)($s['window_seconds'] ?? 10)));
        $s['block_minutes'] = max(1, min(1440, (int)($s['block_minutes'] ?? 3)));
        if(function_exists('saveJson')) saveJson('lib/kodam/data-antispam.json', $s);
        elseif(function_exists('bot_data_put_json')) bot_data_put_json('lib/kodam/data-antispam.json', $s);
        return $s;
    }
}

if(!function_exists('bot_antispam_ensure_sql')){
    function bot_antispam_ensure_sql(){
        $pdo = function_exists('bot_sql_pdo') ? bot_sql_pdo() : null;
        if(!$pdo) return null;
        try{
            $pdo->exec("CREATE TABLE IF NOT EXISTS bot_anti_spam (
                user_id VARCHAR(32) NOT NULL PRIMARY KEY,
                window_start BIGINT NOT NULL DEFAULT 0,
                message_count INT NOT NULL DEFAULT 0,
                blocked_until BIGINT NOT NULL DEFAULT 0,
                last_notice_at BIGINT NOT NULL DEFAULT 0,
                data_json LONGTEXT NULL,
                updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                KEY idx_blocked_until (blocked_until),
                KEY idx_updated (updated_at)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
        }catch(Throwable $e){
            error_log('BOT AntiSpam SQL install failed: '.$e->getMessage());
            return null;
        }
        return $pdo;
    }
}

if(!function_exists('bot_antispam_get_state')){
    function bot_antispam_get_state($userId){
        $userId = (string)$userId;
        $pdo = bot_antispam_ensure_sql();
        if($pdo){
            try{
                $st = $pdo->prepare('SELECT window_start, message_count, blocked_until, last_notice_at, data_json FROM bot_anti_spam WHERE user_id=? LIMIT 1');
                $st->execute([$userId]);
                $row = $st->fetch();
                if($row){
                    $extra = function_exists('bot_json_decode_array') ? bot_json_decode_array($row['data_json'] ?? '', []) : [];
                    return array_merge(is_array($extra) ? $extra : [], [
                        'window_start'=>(int)$row['window_start'],
                        'message_count'=>(int)$row['message_count'],
                        'blocked_until'=>(int)$row['blocked_until'],
                        'last_notice_at'=>(int)$row['last_notice_at'],
                    ]);
                }
            }catch(Throwable $e){ error_log('BOT AntiSpam state read failed: '.$e->getMessage()); }
        }
        $state = function_exists('bot_data_get_json') ? bot_data_get_json('lib/spam/'.$userId.'.json', []) : [];
        return is_array($state) ? array_merge(['window_start'=>0,'message_count'=>0,'blocked_until'=>0,'last_notice_at'=>0], $state) : ['window_start'=>0,'message_count'=>0,'blocked_until'=>0,'last_notice_at'=>0];
    }
}

if(!function_exists('bot_antispam_put_state')){
    function bot_antispam_put_state($userId, array $state){
        $userId = (string)$userId;
        $state = array_merge(['window_start'=>0,'message_count'=>0,'blocked_until'=>0,'last_notice_at'=>0], $state);
        $state['window_start'] = (int)$state['window_start'];
        $state['message_count'] = (int)$state['message_count'];
        $state['blocked_until'] = (int)$state['blocked_until'];
        $state['last_notice_at'] = (int)$state['last_notice_at'];
        $pdo = bot_antispam_ensure_sql();
        if($pdo){
            try{
                $json = function_exists('bot_json_encode') ? bot_json_encode($state) : json_encode($state, JSON_UNESCAPED_UNICODE);
                $st = $pdo->prepare('INSERT INTO bot_anti_spam (user_id, window_start, message_count, blocked_until, last_notice_at, data_json) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE window_start=VALUES(window_start), message_count=VALUES(message_count), blocked_until=VALUES(blocked_until), last_notice_at=VALUES(last_notice_at), data_json=VALUES(data_json), updated_at=CURRENT_TIMESTAMP');
                $st->execute([$userId, $state['window_start'], $state['message_count'], $state['blocked_until'], $state['last_notice_at'], $json]);
                return true;
            }catch(Throwable $e){ error_log('BOT AntiSpam state write failed: '.$e->getMessage()); }
        }
        if(function_exists('bot_data_put_json')) return bot_data_put_json('lib/spam/'.$userId.'.json', $state);
        return false;
    }
}

if(!function_exists('bot_antispam_guard')){
    function bot_antispam_guard($userId, $chatId, $isAdmin = false, $chatType = null){
        if(empty($userId) || empty($chatId)) return false;
        if($isAdmin) return false;
        // فقط پیام‌های خصوصی کاربر با ربات شمارش شوند؛ کانال سفارشات و گروه‌ها خارج هستند.
        if($chatType !== null && (string)$chatType !== 'private') return false;
        if((string)$chatId !== (string)$userId) return false;
        $settings = bot_antispam_settings();
        if(($settings['enabled'] ?? '✅فعال') !== '✅فعال') return false;
        $now = time();
        $state = bot_antispam_get_state($userId);
        $blockedUntil = (int)($state['blocked_until'] ?? 0);
        if($blockedUntil > $now){
            if($now - (int)($state['last_notice_at'] ?? 0) >= 25){
                $remain = max(1, (int)ceil(($blockedUntil - $now) / 60));
                bot('sendMessage', [
                    'chat_id'=>$chatId,
                    'text'=>"⛔️ حساب شما به دلیل ارسال پیام‌های پشت سر هم موقتاً محدود شده است.\n\n⏱ زمان باقی‌مانده: **{$remain} دقیقه**",
                    'parse_mode'=>'MarkDown'
                ]);
                $state['last_notice_at'] = $now;
                bot_antispam_put_state($userId, $state);
            }
            exit;
        }

        $window = (int)$settings['window_seconds'];
        $maxMessages = (int)$settings['max_messages'];
        $start = (int)($state['window_start'] ?? 0);
        $count = (int)($state['message_count'] ?? 0);
        if($start <= 0 || ($now - $start) > $window){
            $start = $now;
            $count = 1;
        }else{
            $count++;
        }

        if($count > $maxMessages){
            $blockSeconds = max(60, (int)$settings['block_minutes'] * 60);
            $state = [
                'window_start'=>$now,
                'message_count'=>0,
                'blocked_until'=>$now + $blockSeconds,
                'last_notice_at'=>$now,
                'blocked_reason'=>'anti_spam',
            ];
            bot_antispam_put_state($userId, $state);
            bot('sendMessage', [
                'chat_id'=>$chatId,
                'text'=>"⚠️ پیام‌های زیادی پشت سر هم ارسال کردید.\n\n⛔️ حساب شما به مدت **{$settings['block_minutes']} دقیقه** محدود شد.",
                'parse_mode'=>'MarkDown'
            ]);
            exit;
        }

        $state['window_start'] = $start;
        $state['message_count'] = $count;
        $state['blocked_until'] = 0;
        bot_antispam_put_state($userId, $state);
        return false;
    }
}

if(!function_exists('bot_antispam_admin_text')){
    function bot_antispam_admin_text(){
        $s = bot_antispam_settings();
        return "🛡 **تنظیمات سیستم ضد اسپم**\n\n".
            "♻️ وضعیت: **{$s['enabled']}**\n".
            "📨 تعداد پیام مجاز: **{$s['max_messages']} پیام**\n".
            "⏱ بازه بررسی: **{$s['window_seconds']} ثانیه**\n".
            "⛔️ مدت محدودیت: **{$s['block_minutes']} دقیقه**\n\n".
            "اگر کاربر در بازه تعیین‌شده بیشتر از تعداد مجاز پیام یا کلیک پشت سر هم ارسال کند، به مدت مشخص‌شده محدود می‌شود.";
    }
}

if(!function_exists('bot_antispam_admin_keyboard')){
    function bot_antispam_admin_keyboard(){
        $s = bot_antispam_settings();
        return json_encode(['inline_keyboard'=>[
            [[ 'text'=>'♻️ وضعیت: '.$s['enabled'], 'callback_data'=>'antispam_toggle_enabled' ]],
            [[ 'text'=>'📨 تعداد مجاز: '.$s['max_messages'], 'callback_data'=>'antispam_set_max_messages' ], [ 'text'=>'⏱ بازه: '.$s['window_seconds'].' ثانیه', 'callback_data'=>'antispam_set_window_seconds' ]],
            [[ 'text'=>'⛔️ مدت محدودیت: '.$s['block_minutes'].' دقیقه', 'callback_data'=>'antispam_set_block_minutes' ]],
            [[ 'text'=>'🧹 پاکسازی محدودیت‌های فعلی', 'callback_data'=>'antispam_clear_blocks' ]],
            [[ 'text'=>'🔙 بازگشت به پنل مدیریت', 'callback_data'=>'admin_main_menu' ]],
        ]], JSON_UNESCAPED_UNICODE);
    }
}

if(!function_exists('bot_antispam_clear_blocks')){
    function bot_antispam_clear_blocks(){
        $pdo = bot_antispam_ensure_sql();
        if($pdo){
            try{
                $pdo->exec('UPDATE bot_anti_spam SET blocked_until=0, message_count=0, last_notice_at=0');
                return true;
            }catch(Throwable $e){ error_log('BOT AntiSpam clear blocks failed: '.$e->getMessage()); }
        }
        return true;
    }
}

if(!function_exists('bot_antispam_runtime_router')){
    function bot_antispam_runtime_router(){
        global $Tc, $msg, $data, $data_id, $chatID, $msg_id, $userID, $user, $isAdmin, $Button_Panel, $Button_back_panel;
        if(!isset($Tc) || $Tc !== 'private' || !$isAdmin) return false;
        $labels = ['🛡 سیستم ضد اسپم','🛡سیستم ضد اسپم','🛡 ضد اسپم','ضد اسپم','سیستم ضد اسپم'];
        if(isset($msg) && in_array(trim((string)$msg), $labels, true)){
            $user['step'] = 'none'; saveJson('melat/'.$userID.'.json', $user);
            bot('sendMessage', [
                'chat_id'=>$chatID,
                'text'=>bot_antispam_admin_text(),
                'parse_mode'=>'MarkDown',
                'reply_markup'=>bot_antispam_admin_keyboard(),
            ]);
            return true;
        }
        if(isset($data) && (string)$data === 'antispam_toggle_enabled'){
            $s = bot_antispam_settings();
            $s['enabled'] = $s['enabled'] === '✅فعال' ? '❌غیر فعال' : '✅فعال';
            bot_antispam_save_settings($s);
            bot('answercallbackquery', ['callback_query_id'=>$data_id, 'text'=>'تنظیم شد', 'show_alert'=>false]);
            bot('editMessageText', ['chat_id'=>$chatID, 'message_id'=>$msg_id, 'text'=>bot_antispam_admin_text(), 'parse_mode'=>'MarkDown', 'reply_markup'=>bot_antispam_admin_keyboard()]);
            return true;
        }
        if(isset($data) && preg_match('/^antispam_set_(max_messages|window_seconds|block_minutes)$/', (string)$data, $m)){
            $key = $m[1];
            $titles = ['max_messages'=>'تعداد پیام مجاز', 'window_seconds'=>'بازه بررسی به ثانیه', 'block_minutes'=>'مدت محدودیت به دقیقه'];
            $user['step'] = 'antispam_wait_'.$key; saveJson('melat/'.$userID.'.json', $user);
            bot('answercallbackquery', ['callback_query_id'=>$data_id, 'text'=>'عدد جدید را ارسال کنید', 'show_alert'=>false]);
            bot('sendMessage', [
                'chat_id'=>$chatID,
                'text'=>"✏️ مقدار جدید **{$titles[$key]}** را فقط عددی ارسال کنید.",
                'parse_mode'=>'MarkDown',
                'reply_markup'=>$Button_back_panel,
            ]);
            return true;
        }
        if(isset($data) && (string)$data === 'antispam_clear_blocks'){
            bot_antispam_clear_blocks();
            bot('answercallbackquery', ['callback_query_id'=>$data_id, 'text'=>'محدودیت‌های فعلی پاک شد', 'show_alert'=>false]);
            bot('editMessageText', ['chat_id'=>$chatID, 'message_id'=>$msg_id, 'text'=>bot_antispam_admin_text(), 'parse_mode'=>'MarkDown', 'reply_markup'=>bot_antispam_admin_keyboard()]);
            return true;
        }
        if(isset($msg) && isset($user['step']) && preg_match('/^antispam_wait_(max_messages|window_seconds|block_minutes)$/', (string)$user['step'], $m)){
            $valueRaw = trim((string)$msg);
            if(function_exists('bot_normalize_number_digits')) $valueRaw = bot_normalize_number_digits($valueRaw);
            $valueRaw = preg_replace('/[^0-9]/', '', $valueRaw);
            if($valueRaw === '' || (int)$valueRaw <= 0){
                bot('sendMessage', ['chat_id'=>$chatID, 'text'=>'❌ مقدار باید عددی و بزرگ‌تر از صفر باشد.', 'parse_mode'=>'MarkDown', 'reply_markup'=>$Button_back_panel]);
                return true;
            }
            $key = $m[1];
            $s = bot_antispam_settings();
            $s[$key] = (int)$valueRaw;
            $s = bot_antispam_save_settings($s);
            $user['step'] = 'none'; saveJson('melat/'.$userID.'.json', $user);
            bot('sendMessage', [
                'chat_id'=>$chatID,
                'text'=>"✅ تنظیمات ضد اسپم ذخیره شد.",
                'parse_mode'=>'MarkDown',
                'reply_markup'=>$Button_Panel,
            ]);
            bot('sendMessage', [
                'chat_id'=>$chatID,
                'text'=>bot_antispam_admin_text(),
                'parse_mode'=>'MarkDown',
                'reply_markup'=>bot_antispam_admin_keyboard(),
            ]);
            return true;
        }
        return false;
    }
}
