<?php
/**
 * Optimized challenge mechanisms for BotFend Anti-Bot Firewall
 *
 * @package BotFend\Challenges
 * @version 4.9.0 - Extracted inline CSS/JS to external files, consolidated to single JS
 */

namespace BotFend\Challenges;

use BotFend\Core\Config;
use BotFend\Utilities\Utilities;
use BotFend\Database\Database;

defined('ABSPATH') || exit;

/**
 * Class Challenges
 *
 * Handles JavaScript challenges, honeypots, and bot verification
 */
class Challenges {
    
    private $config;
    private $utilities;
    private $database;
    private $whitelisted_ips = [];
    private $whitelisted_paths = [];
    private $challenge_probability = 30;
    private $headless_allowlist = [];
    
    const CHALLENGE_EXPIRY = 300;
    const VERIFY_EXPIRY = 300;
    const HONEYPOT_WINDOW = 300;
    const UA_SIMILARITY_THRESHOLD = 90;
    
    public function __construct(Utilities $utilities, Database $database) {
        $this->config = Config::get_instance();
        $this->utilities = $utilities;
        $this->database = $database;
        $this->load_whitelist();
        $this->load_whitelisted_paths();
        $this->load_headless_allowlist();
        
        $this->challenge_probability = $this->config->get_int('challenge_probability', 30);
        
        add_action('init', [$this, 'check_honeypot_hit']);
        add_action('wp_ajax_botfend_verify_challenge', [$this, 'verify_challenge']);
        add_action('wp_ajax_nopriv_botfend_verify_challenge', [$this, 'verify_challenge']);
    }
    
    /**
     * Enqueue the single combined challenges JS file.
     * Safe to call multiple times — only registers/enqueues once.
     */
    private function enqueue_challenges_js(): void {
        if (!wp_script_is('botfend-challenges-js', 'registered')) {
            wp_register_script(
                'botfend-challenges-js',
                BOTFEND_ASSETS_URL . 'js/botfend-challenges.js',
                [],
                BOTFEND_VERSION,
                true
            );
        }
        wp_enqueue_script('botfend-challenges-js');
    }
    
    private function load_whitelist() {
        $whitelist_option = $this->config->get_string('whitelist_ips', '');
        $this->whitelisted_ips = array_filter(array_map('trim', explode("\n", $whitelist_option)));
        $this->whitelisted_ips = array_map('sanitize_text_field', $this->whitelisted_ips);
    }
    
    private function load_whitelisted_paths() {
        $paths_raw = $this->config->get_string('whitelisted_paths', '');
        $this->whitelisted_paths = array_filter(array_map('trim', explode("\n", $paths_raw)));
        $this->whitelisted_paths = array_map('sanitize_text_field', $this->whitelisted_paths);
    }
    
    private function load_headless_allowlist() {
        $this->headless_allowlist = [
            'pingdom',
            'uptimerobot',
            'statuscake',
            'newrelic',
            'datadog',
            'sitespeed.io',
            'lighthouse',
            'pagespeed',
            'gtmetrix',
            'wave',
            'axe',
            'pa11y',
            'siteimprove',
            'tenon',
            'google page speed',
            'google lite',
            'chrome-lighthouse',
        ];
        
        $this->headless_allowlist = apply_filters('botfend_headless_allowlist', $this->headless_allowlist);
    }
    
    private function is_ip_whitelisted($ip) {
        if (empty($this->whitelisted_ips)) {
            return false;
        }
        
        foreach ($this->whitelisted_ips as $whitelist_ip) {
            if (strpos($whitelist_ip, '#') === 0) {
                continue;
            }
            
            if (strpos($whitelist_ip, '/') !== false) {
                if ($this->ip_in_cidr($ip, $whitelist_ip)) {
                    return true;
                }
            } elseif ($ip === $whitelist_ip) {
                return true;
            }
        }
        
        return false;
    }
    
    private function ip_in_cidr($ip, $cidr) {
        if (strpos($ip, ':') !== false) {
            return $this->ipv6_in_cidr($ip, $cidr);
        }
        
        list($subnet, $bits) = explode('/', $cidr);
        $ip_long = ip2long($ip);
        $subnet_long = ip2long($subnet);
        
        if ($ip_long === false || $subnet_long === false) {
            return false;
        }
        
        $bits = intval($bits);
        if ($bits < 0 || $bits > 32) {
            return false;
        }
        
        $mask = -1 << (32 - $bits);
        $subnet_long &= $mask;
        return ($ip_long & $mask) == $subnet_long;
    }
    
    private function ipv6_in_cidr($ip, $cidr) {
        if (!function_exists('inet_pton')) {
            return false;
        }
        
        list($subnet, $bits) = explode('/', $cidr);
        
        $ip_bin = inet_pton($ip);
        $subnet_bin = inet_pton($subnet);
        
        if ($ip_bin === false || $subnet_bin === false) {
            return false;
        }
        
        $bits = intval($bits);
        if ($bits < 0 || $bits > 128) {
            return false;
        }
        
        $mask = '';
        $full_bytes = floor($bits / 8);
        $remaining_bits = $bits % 8;
        
        for ($i = 0; $i < $full_bytes; $i++) {
            $mask .= chr(255);
        }
        
        if ($remaining_bits > 0) {
            $mask .= chr(bindec(str_pad(str_repeat('1', $remaining_bits), 8, '0')));
        }
        
        $mask = str_pad($mask, 16, chr(0));
        
        for ($i = 0; $i < 16; $i++) {
            $ip_byte = ord($ip_bin[$i]);
            $subnet_byte = ord($subnet_bin[$i]);
            $mask_byte = ord($mask[$i]);
            
            if (($ip_byte & $mask_byte) !== ($subnet_byte & $mask_byte)) {
                return false;
            }
        }
        
        return true;
    }
    
    private function is_path_whitelisted($path) {
        if (empty($path)) {
            return false;
        }
        
        foreach ($this->whitelisted_paths as $whitelisted_path) {
            if ($path === $whitelisted_path || 
                (substr($whitelisted_path, -1) === '/' && strpos($path, $whitelisted_path) === 0)) {
                return true;
            }
        }
        
        if (strpos($path, '/.well-known/') === 0) {
            return true;
        }
        
        return false;
    }
    
    private function extract_browser_family($ua) {
        $ua = strtolower($ua);
        
        if (strpos($ua, 'edg/') !== false || strpos($ua, 'edge/') !== false) {
            return 'edge';
        }
        if (strpos($ua, 'opr/') !== false || strpos($ua, 'opera/') !== false) {
            return 'opera';
        }
        if (strpos($ua, 'chrome/') !== false && strpos($ua, 'edg/') === false) {
            return 'chrome';
        }
        if (strpos($ua, 'firefox/') !== false) {
            return 'firefox';
        }
        if (strpos($ua, 'safari/') !== false && strpos($ua, 'chrome/') === false) {
            return 'safari';
        }
        if (strpos($ua, 'trident/') !== false || strpos($ua, 'msie ') !== false) {
            return 'ie';
        }
        
        return 'unknown';
    }
    
    private function extract_os_family($ua) {
        $ua = strtolower($ua);
        
        if (strpos($ua, 'windows nt') !== false) {
            return 'windows';
        }
        if (strpos($ua, 'mac os x') !== false) {
            return 'macos';
        }
        if (strpos($ua, 'linux') !== false) {
            return 'linux';
        }
        if (strpos($ua, 'android') !== false) {
            return 'android';
        }
        if (strpos($ua, 'ios') !== false || strpos($ua, 'iphone') !== false || strpos($ua, 'ipad') !== false) {
            return 'ios';
        }
        
        return 'unknown';
    }
    
    private function extract_major_version($ua) {
        $ua = strtolower($ua);
        
        $patterns = [
            'chrome/([0-9]+)',
            'firefox/([0-9]+)',
            'safari/([0-9]+)',
            'version/([0-9]+)',
            'msie ([0-9]+)',
            'rv:([0-9]+)',
            'edge/([0-9]+)',
            'opr/([0-9]+)',
        ];
        
        foreach ($patterns as $pattern) {
            if (preg_match('/' . $pattern . '/i', $ua, $matches)) {
                return $matches[1];
            }
        }
        
        return '0';
    }
    
    private function create_ua_fingerprint($user_agent) {
        $browser = $this->extract_browser_family($user_agent);
        $version = $this->extract_major_version($user_agent);
        $os = $this->extract_os_family($user_agent);
        
        return md5($browser . '|' . $version . '|' . $os);
    }
    
    private function verify_user_agent($stored_fingerprint, $current_ua) {
        $current_fingerprint = $this->create_ua_fingerprint($current_ua);
        return hash_equals($stored_fingerprint, $current_fingerprint);
    }
    
    private function detect_headless_browser($user_agent, $ip) {
        if ($this->utilities->verify_legitimate_crawler($ip, $user_agent)) {
            return false;
        }
        
        $ua_lower = strtolower($user_agent);
        
        foreach ($this->headless_allowlist as $allowed) {
            if (strpos($ua_lower, $allowed) !== false) {
                return false;
            }
        }
        
        $headless_patterns = [
            'headless',
            'phantomjs',
            'puppeteer',
            'selenium',
            'playwright',
            'chrome-headless',
            'headlesschrome',
            'headless-chrome'
        ];
        
        foreach ($headless_patterns as $pattern) {
            if (stripos($user_agent, $pattern) !== false) {
                if ($this->is_monitoring_service($ip, $user_agent)) {
                    return false;
                }
                return 'suspicious';
            }
        }
        
        if (empty($user_agent) || $this->utilities->has_suspicious_headers()) {
            return 'suspicious';
        }
        
        return false;
    }
    
    private function is_monitoring_service($ip, $user_agent) {
        $monitoring_ranges = [
            '107.6.0.0/16',
            '204.14.80.0/22',
            '69.162.124.0/24',
            '216.144.250.150/32',
            '104.236.0.0/16',
            '198.58.0.0/16',
        ];
        
        foreach ($monitoring_ranges as $range) {
            if ($this->ip_in_cidr($ip, $range)) {
                return true;
            }
        }
        
        return false;
    }
    
    public function issue_js_challenge($ip) {
        if ($this->is_ip_whitelisted($ip)) {
            return;
        }
        
        $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
        if ($this->is_path_whitelisted($request_uri)) {
            return;
        }
        
        if (!$this->config->get_bool('enable_js_challenge', true)) {
            return;
        }
        
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        
        if ($this->utilities->verify_legitimate_crawler($ip, $user_agent)) {
            return;
        }
        
        $headless_result = $this->detect_headless_browser($user_agent, $ip);
        
        if ($headless_result === true) {
            $country = $this->utilities->get_country($ip);
            $block_duration = $this->config->get_int('headless_block_duration', 24);
            
            $this->database->block_ip(
                sanitize_text_field($ip),
                'headless_bot',
                esc_html__('Headless browser detected', 'botfend-anti-bot-firewall'),
                10,
                $block_duration,
                sanitize_text_field($country)
            );
            
            $this->database->log_request(
                $ip, 
                10, 
                'headless_bot_blocked', 
                [esc_html__('Headless browser detected and blocked', 'botfend-anti-bot-firewall')], 
                $user_agent, 
                false, 
                $country
            );
            
            $this->render_blocked_page($ip, 'headless');
            exit;
        } elseif ($headless_result === 'suspicious') {
            $challenge_key = 'botfend_challenge_count_' . md5($ip);
            $challenge_count = absint(get_transient($challenge_key) ?: 0);
            $challenge_rate_limit = $this->config->get_int('challenge_rate_limit', 5);
            
            if ($challenge_count > $challenge_rate_limit) {
                $country = $this->utilities->get_country($ip);
                $block_duration = $this->config->get_int('challenge_abuse_block_duration', 12);
                
                $this->database->block_ip(
                    sanitize_text_field($ip),
                    'challenge_abuse',
                    esc_html__('Excessive challenge requests', 'botfend-anti-bot-firewall'),
                    8,
                    $block_duration,
                    sanitize_text_field($country)
                );
                return;
            }
            
            $challenge_count++;
            set_transient($challenge_key, $challenge_count, self::CHALLENGE_EXPIRY);
        }
        
        if (wp_rand(0, 100) < $this->challenge_probability) {
            $challenge_token = $this->generate_secure_token($ip);
            $ua_fingerprint = $this->create_ua_fingerprint($user_agent);
            
            $challenge_data = [
                'token' => $challenge_token,
                'ip' => $ip,
                'expires' => time() + self::CHALLENGE_EXPIRY,
                'created' => time(),
                'ua_fingerprint' => $ua_fingerprint,
                'original_ua' => $user_agent,
                'attempts' => 0
            ];
            
            set_transient('botfend_challenge_' . md5($challenge_token), $challenge_data, self::CHALLENGE_EXPIRY);
            
            $country = $this->utilities->get_country($ip);
            $this->database->log_request($ip, 7, 'js_challenge', [esc_html__('JavaScript challenge issued', 'botfend-anti-bot-firewall')], $user_agent, false, $country);
            $this->render_js_challenge($ip, $challenge_token);
            exit;
        }
    }
    
    private function generate_secure_token($ip) {
        $data = [
            'ip' => $ip,
            'time' => time(),
            'random' => bin2hex(random_bytes(16)),
            'salt' => wp_salt('nonce')
        ];
        
        $token_data = wp_json_encode($data);
        return hash_hmac('sha256', $token_data, wp_salt('auth'));
    }
    
    private function render_blocked_page($ip, $reason = 'headless') {
        nocache_headers();
        header('X-Frame-Options: DENY');
        header('X-Content-Type-Options: nosniff');
        header('Referrer-Policy: strict-origin-when-cross-origin');
        if (is_ssl()) {
            header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
        }
        ?>
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title><?php esc_html_e('Access Denied', 'botfend-anti-bot-firewall'); ?></title>
            <?php wp_enqueue_style('botfend-block-css', BOTFEND_ASSETS_URL . 'css/botfend-block.css', [], BOTFEND_VERSION); ?>
            <?php wp_print_styles('botfend-block-css'); ?>
        </head>
        <body class="botfend-block-page">
            <div class="botfend-container">
                <div class="icon" style="font-size: 64px; margin-bottom: 20px; color: #dc3545;">⛔</div>
                <h1><?php esc_html_e('Access Denied', 'botfend-anti-bot-firewall'); ?></h1>
                <p><?php esc_html_e('Automated browsing tools are not allowed on this site.', 'botfend-anti-bot-firewall'); ?></p>
                <p><small><?php esc_html_e('If you believe this is an error, please contact the site administrator.', 'botfend-anti-bot-firewall'); ?></small></p>
            </div>
        </body>
        </html>
        <?php
        exit;
    }
    
    private function render_js_challenge($ip, $token) {
        nocache_headers();
        header('X-Frame-Options: DENY');
        header('X-Content-Type-Options: nosniff');
        header('Referrer-Policy: strict-origin-when-cross-origin');
        if (is_ssl()) {
            header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
        }
        
        // Enqueue external CSS
        wp_enqueue_style(
            'botfend-challenges-css',
            BOTFEND_ASSETS_URL . 'css/botfend-challenges.css',
            [],
            BOTFEND_VERSION
        );
        wp_enqueue_style(
            'botfend-block-css',
            BOTFEND_ASSETS_URL . 'css/botfend-block.css',
            [],
            BOTFEND_VERSION
        );
        
        // Enqueue combined JS with challenge data
        $this->enqueue_challenges_js();
        wp_add_inline_script(
            'botfend-challenges-js',
            'var botfendChallenge = ' . wp_json_encode([
                'ajaxUrl' => admin_url('admin-ajax.php'),
                'token'   => $token,
                'nonce'   => wp_create_nonce('botfend_challenge'),
            ]) . ';',
            'before'
        );
        ?>
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <title><?php esc_html_e('Verifying Browser...', 'botfend-anti-bot-firewall'); ?></title>
            <?php wp_print_styles(['botfend-challenges-css', 'botfend-block-css']); ?>
        </head>
        <body class="botfend-challenge-page">
            <div class="botfend-container botfend-challenge-container">
                <div class="botfend-spinner-container">
                    <div class="botfend-spinner"></div>
                </div>
                
                <h2><?php esc_html_e('Verifying Your Browser', 'botfend-anti-bot-firewall'); ?></h2>
                <p><?php esc_html_e('Please wait while we verify your browser is not automated.', 'botfend-anti-bot-firewall'); ?></p>
                
                <div class="botfend-progress-bar">
                    <div class="botfend-progress-fill" id="botfend-progress-fill"></div>
                </div>
                
                <p>
                    <small>
                        <span class="botfend-security-badge">🔒 <?php esc_html_e('Security Check', 'botfend-anti-bot-firewall'); ?></span>
                        <br>
                        <a href="#" id="botfend-learn-more-link" class="botfend-learn-more-link">
                            <?php esc_html_e('Why am I seeing this?', 'botfend-anti-bot-firewall'); ?>
                        </a>
                    </small>
                </p>
                
                <div id="botfend-explanation-box" class="botfend-explanation-box">
                    <strong><?php esc_html_e('About this security check:', 'botfend-anti-bot-firewall'); ?></strong>
                    <p style="margin: 10px 0 0 0; font-size: 14px;">
                        <?php esc_html_e('This check helps protect our website from malicious bots and automated attacks. It ensures that you are a real human visitor. The verification only takes a few seconds and helps keep our site safe for everyone.', 'botfend-anti-bot-firewall'); ?>
                    </p>
                </div>
                
                <form method="POST" action="<?php echo esc_url(admin_url('admin-ajax.php')); ?>" class="botfend-hidden" id="botfend-challenge-fallback">
                    <input type="hidden" name="action" value="botfend_verify_challenge">
                    <input type="hidden" name="token" value="<?php echo esc_attr($token); ?>">
                    <input type="hidden" name="nonce" value="<?php echo esc_attr(wp_create_nonce('botfend_challenge')); ?>">
                    <button type="submit" class="botfend-btn"><?php esc_html_e('Continue', 'botfend-anti-bot-firewall'); ?></button>
                </form>
            </div>
            
            <?php wp_print_scripts('botfend-challenges-js'); ?>
        </body>
        </html>
        <?php
    }
    
    public function verify_challenge() {
        check_ajax_referer('botfend_challenge', 'nonce');
        
        $token = isset($_POST['token']) ? sanitize_text_field(wp_unslash($_POST['token'])) : '';
        $ip = $this->utilities->get_client_ip();
        
        $verification_key = 'botfend_verify_attempts_' . md5($ip . $token);
        $attempts = absint(get_transient($verification_key) ?: 0);
        
        if ($attempts > 3) {
            wp_send_json_error(['message' => esc_html__('Too many attempts', 'botfend-anti-bot-firewall')]);
        }
        
        $attempts++;
        set_transient($verification_key, $attempts, self::VERIFY_EXPIRY);
        
        $challenge_key = 'botfend_challenge_' . md5($token);
        $challenge = get_transient($challenge_key);
        
        if (!$challenge) {
            wp_send_json_error(['message' => esc_html__('Challenge expired or invalid', 'botfend-anti-bot-firewall')]);
        }
        
        if (!hash_equals($challenge['token'], $token)) {
            wp_send_json_error(['message' => esc_html__('Invalid token', 'botfend-anti-bot-firewall')]);
        }
        
        if ($challenge['ip'] !== $ip) {
            wp_send_json_error(['message' => esc_html__('IP mismatch', 'botfend-anti-bot-firewall')]);
        }
        
        if ($challenge['expires'] < time()) {
            delete_transient($challenge_key);
            wp_send_json_error(['message' => esc_html__('Challenge expired', 'botfend-anti-bot-firewall')]);
        }
        
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        $current_fingerprint = $this->create_ua_fingerprint($user_agent);
        
        if ($challenge['ua_fingerprint'] !== $current_fingerprint) {
            if (isset($challenge['original_ua'])) {
                $similarity = 0;
                similar_text($challenge['original_ua'], $user_agent, $similarity);
                
                if ($similarity < self::UA_SIMILARITY_THRESHOLD) {
                    delete_transient($challenge_key);
                    wp_send_json_error(['message' => esc_html__('User agent mismatch', 'botfend-anti-bot-firewall')]);
                }
            } else {
                delete_transient($challenge_key);
                wp_send_json_error(['message' => esc_html__('User agent mismatch', 'botfend-anti-bot-firewall')]);
            }
        }
        
        if ($challenge['attempts'] > 2) {
            delete_transient($challenge_key);
            wp_send_json_error(['message' => esc_html__('Too many attempts', 'botfend-anti-bot-firewall')]);
        }
        
        $challenge['attempts']++;
        set_transient($challenge_key, $challenge, self::CHALLENGE_EXPIRY);
        
        $verified_key = 'botfend_verified_' . md5($ip);
        set_transient($verified_key, [
            'verified' => true,
            'verified_at' => time(),
            'ip' => $ip
        ], DAY_IN_SECONDS);
        
        delete_transient($challenge_key);
        delete_transient($verification_key);
        
        $country = $this->utilities->get_country($ip);
        $this->database->log_request($ip, 0, 'challenge_passed', [esc_html__('JavaScript challenge completed', 'botfend-anti-bot-firewall')], $user_agent, false, $country);
        
        $redirect = isset($_SERVER['HTTP_REFERER']) ? esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : home_url();
        
        $redirect_host = wp_parse_url($redirect, PHP_URL_HOST);
        $site_host = wp_parse_url(home_url(), PHP_URL_HOST);
        
        if ($redirect_host && $redirect_host !== $site_host) {
            $redirect = home_url();
        }
        
        wp_send_json_success([
            'message' => esc_html__('Verified', 'botfend-anti-bot-firewall'),
            'redirect' => $redirect
        ]);
    }
    
    public function has_passed_challenge() {
        $ip = $this->utilities->get_client_ip();
        $verified_key = 'botfend_verified_' . md5($ip);
        $verified = get_transient($verified_key);
        
        return $verified && !empty($verified['verified']);
    }
    
    public function add_honeypots() {
        $ip = $this->utilities->get_client_ip();
        $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
        
        if ($this->is_ip_whitelisted($ip) || $this->is_path_whitelisted($request_uri)) {
            return;
        }
        
        if (!$this->config->get_bool('enable_honeypot', true)) {
            return;
        }
        
        if (is_admin() || wp_doing_ajax()) {
            return;
        }
        
        echo '<div style="display:none !important; visibility:hidden !important; opacity:0 !important; position:absolute !important; z-index:-9999 !important; height:0; width:0; overflow:hidden;">';
        
        $honeypots_raw = $this->config->get_string('honeypot_urls', '');
        $honeypots = array_filter(array_map('trim', explode("\n", $honeypots_raw)));
        
        if (empty($honeypots)) {
            $honeypots = [
                '/wp-admin.bak',
                '/wp-login.php.bak', 
                '/license.txt',
                '/readme.html',
                '/xmlrpc.php.bak',
                '/admin.php',
                '/administrator/index.php',
                '/wp-content/uploads/.htaccess.bak',
                '/.env',
                '/config.php.bak'
            ];
        }
        
        foreach ($honeypots as $index => $honeypot) {
            echo '<a href="' . esc_url(home_url($honeypot)) . '" id="' . esc_attr('botfend-honeypot-' . absint($index)) . '" data-bot-trap="true"></a>';
        }
        
        echo '</div>';
        
        // Enqueue combined JS with honeypot data
        $this->enqueue_challenges_js();
        wp_add_inline_script(
            'botfend-challenges-js',
            'var botfendHoneypot = ' . wp_json_encode([
                'nonce'     => wp_create_nonce('botfend_honeypot'),
                'beaconUrl' => home_url('/?botfend_honeypot=1'),
            ]) . ';',
            'before'
        );
    }
    
    public function check_honeypot_hit() {
        if (!isset($_GET['botfend_honeypot'])) {
            return;
        }
        
        $nonce = isset($_GET['nonce']) ? sanitize_text_field(wp_unslash($_GET['nonce'])) : '';
        $honeypot_value = isset($_GET['botfend_honeypot']) ? 
                          sanitize_text_field(wp_unslash($_GET['botfend_honeypot'])) : '';
        
        if (!preg_match('/^[a-zA-Z0-9_-]+$/', $honeypot_value)) {
            $this->handle_malformed_honeypot();
            return;
        }
        
        if (empty($nonce)) {
            $this->handle_dumb_bot_honeypot($honeypot_value);
            return;
        }
        
        if (!wp_verify_nonce($nonce, 'botfend_honeypot')) {
            $this->handle_honeypot_csrf_attack();
            return;
        }
        
        $honeypot_id = isset($_GET['honeypot_id']) ? 
                       sanitize_text_field(wp_unslash($_GET['honeypot_id'])) : 'unknown';
        
        $this->process_valid_honeypot_hit($honeypot_value, $honeypot_id);
    }
    
    private function handle_dumb_bot_honeypot($honeypot_value) {
        $ip = $this->utilities->get_client_ip();
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? 
                      sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        $country = $this->utilities->get_country($ip);
        
        $this->database->log_request(
            sanitize_text_field($ip),
            3,
            'honeypot_dumb_bot',
            [esc_html__('Dumb bot hit honeypot (no JS)', 'botfend-anti-bot-firewall')],
            sanitize_text_field($user_agent),
            false,
            sanitize_text_field($country)
        );
        
        $hits_key = 'botfend_honeypot_hits_' . md5(sanitize_text_field($ip));
        $hits = absint(get_transient($hits_key) ?: 0);
        $hits++;
        set_transient($hits_key, $hits, HOUR_IN_SECONDS);
        
        if ($hits >= 3) {
            $block_duration = $this->calculate_honeypot_block_duration($hits);
            $block_reason = sprintf(
                esc_html__('Multiple honeypot hits without JS (%d hits)', 'botfend-anti-bot-firewall'),
                $hits
            );
            
            $this->database->block_ip(
                sanitize_text_field($ip),
                'honeypot_repeat_bot',
                $block_reason,
                7,
                $block_duration,
                sanitize_text_field($country),
                sanitize_text_field($user_agent)
            );
        }
        
        $this->send_honeypot_security_headers();
        status_header(404);
        nocache_headers();
        exit;
    }
    
    private function handle_honeypot_csrf_attack() {
        $ip = $this->utilities->get_client_ip();
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? 
                      sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        $country = $this->utilities->get_country($ip);
        $referer = isset($_SERVER['HTTP_REFERER']) ? 
                   esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : '';
        
        $this->database->log_request(
            sanitize_text_field($ip),
            10,
            'honeypot_csrf_attack',
            [sprintf(
                esc_html__('CSRF attack on security honeypot from IP: %s', 'botfend-anti-bot-firewall'),
                esc_html($ip)
            )],
            sanitize_text_field($user_agent),
            false,
            sanitize_text_field($country),
            sanitize_text_field($referer)
        );
        
        $attack_key = 'botfend_csrf_attack_' . md5(sanitize_text_field($ip));
        $attack_count = absint(get_transient($attack_key) ?: 0);
        $attack_count++;
        
        set_transient($attack_key, $attack_count, HOUR_IN_SECONDS);
        
        $block_duration = $this->calculate_honeypot_block_duration($attack_count);
        $block_reason = sprintf(
            esc_html__('CSRF attack on security honeypot (attempt %d)', 'botfend-anti-bot-firewall'),
            $attack_count
        );
        
        $this->database->block_ip(
            sanitize_text_field($ip),
            'honeypot_csrf',
            $block_reason,
            10,
            $block_duration,
            sanitize_text_field($country),
            sanitize_text_field($user_agent)
        );
        
        $this->send_honeypot_security_headers();
        status_header(404);
        nocache_headers();
        exit;
    }
    
    private function handle_malformed_honeypot() {
        $ip = $this->utilities->get_client_ip();
        
        $this->database->log_request(
            sanitize_text_field($ip),
            6,
            'malformed_honeypot',
            [esc_html__('Malformed honeypot value detected', 'botfend-anti-bot-firewall')],
            isset($_SERVER['HTTP_USER_AGENT']) ? 
            sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '',
            false,
            $this->utilities->get_country($ip)
        );
        
        status_header(404);
        nocache_headers();
        exit;
    }
    
    private function process_valid_honeypot_hit($honeypot_value, $honeypot_id) {
        $ip = $this->utilities->get_client_ip();
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? 
                      sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        $country = $this->utilities->get_country($ip);
        
        if ($this->is_ip_whitelisted($ip)) {
            $this->database->log_request(
                sanitize_text_field($ip),
                0,
                'whitelist_honeypot',
                [sprintf(
                    esc_html__('Whitelisted IP hit honeypot: %s', 'botfend-anti-bot-firewall'),
                    esc_html($honeypot_id)
                )],
                sanitize_text_field($user_agent),
                false,
                sanitize_text_field($country)
            );
            
            wp_safe_redirect(esc_url(home_url()));
            exit;
        }
        
        $this->database->log_request(
            sanitize_text_field($ip),
            9,
            'honeypot_triggered',
            [sprintf(
                esc_html__('Honeypot triggered: %1$s (value: %2$s)', 'botfend-anti-bot-firewall'),
                esc_html($honeypot_id),
                esc_html($honeypot_value)
            )],
            sanitize_text_field($user_agent),
            true,
            sanitize_text_field($country)
        );
        
        $hits_key = 'botfend_honeypot_hits_' . md5(sanitize_text_field($ip));
        $hits = absint(get_transient($hits_key) ?: 0);
        $hits++;
        set_transient($hits_key, $hits, self::HONEYPOT_WINDOW);
        
        if ($hits >= 1) {
            $block_duration = $this->calculate_honeypot_block_duration($hits);
            $block_reason = sprintf(
                esc_html__('Bot detected via honeypot trap (%d hits)', 'botfend-anti-bot-firewall'),
                $hits
            );
            
            $this->database->block_ip(
                sanitize_text_field($ip),
                'honeypot_bot',
                $block_reason,
                9,
                $block_duration,
                sanitize_text_field($country),
                sanitize_text_field($user_agent)
            );
        }
        
        $this->send_honeypot_security_headers();
        status_header(404);
        nocache_headers();
        exit;
    }
    
    private function calculate_honeypot_block_duration($attack_count) {
        switch (true) {
            case $attack_count >= 10:
                return 720;
            case $attack_count >= 5:
                return 336;
            case $attack_count >= 3:
                return 168;
            case $attack_count >= 2:
                return 72;
            default:
                return $this->config->get_int('honeypot_block_duration', 24);
        }
    }
    
    private function send_honeypot_security_headers() {
        if (!headers_sent()) {
            header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
            header('Pragma: no-cache');
            header('X-Content-Type-Options: nosniff');
            header('X-Frame-Options: SAMEORIGIN');
            header('Referrer-Policy: strict-origin-when-cross-origin');
            if (is_ssl()) {
                header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
            }
        }
    }
    
    public function should_bypass_challenges($ip, $request_uri = '') {
        if (empty($request_uri)) {
            $request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
        }
        
        return $this->is_ip_whitelisted($ip) || $this->is_path_whitelisted($request_uri);
    }
    
    public function get_whitelisted_paths() {
        return $this->whitelisted_paths;
    }
    
    public function get_whitelisted_ips() {
        return $this->whitelisted_ips;
    }
    
    public function clear_challenge_data($ip) {
        global $wpdb;
        $hash = md5($ip);
        
        if (!wp_using_ext_object_cache()) {
            // SAFE: Only run if no object cache is present to prevent ghost transients
            $keys = $wpdb->get_col($wpdb->prepare(
                "SELECT option_name FROM {$wpdb->options} 
                 WHERE option_name LIKE %s 
                 OR option_name LIKE %s",
                '_transient_botfend_verify_attempts_' . $wpdb->esc_like($hash) . '%',
                '_transient_timeout_botfend_verify_attempts_' . $wpdb->esc_like($hash) . '%'
            ));
            
            if (!empty($keys)) {
                foreach ($keys as $key) {
                    $transient_name = str_replace(['_transient_timeout_', '_transient_'], '', $key);
                    delete_transient($transient_name);
                }
            }
        }

        $challenge_key = 'botfend_challenge_count_' . $hash;
        delete_transient($challenge_key);
        
        $verified_key = 'botfend_verified_' . $hash;
        delete_transient($verified_key);
    }
}