<?php
if (!defined('ABSPATH')) {
    die('You are not allowed to call this page directly.');
}

/**
 * FormShield Divi Spam Detection
 * 
 * Fine-grained spam detection for Divi Contact Forms
 * Flags suspicious submissions instead of hard-blocking them
 * 
 * Extensible via WordPress filters and hooks:
 * 
 * Filters:
 * - formshield_divi_default_spam_patterns - Modify default spam patterns
 * - formshield_divi_spam_patterns - Modify spam patterns per request
 * - formshield_divi_behavioral_data - Modify behavioral data before scoring
 * - formshield_divi_custom_score_delta - Add custom scoring rules (return additional points to add/subtract)
 * - formshield_divi_suspicion_score - Modify final suspicion score
 * - formshield_divi_suspicion_threshold - Modify suspicion threshold (default: 50)
 * - formshield_divi_email_notification_threshold - Modify email threshold (default: 70)
 * - formshield_divi_should_send_notification - Control if notification should be sent
 * - formshield_divi_notification_subject - Modify email subject
 * - formshield_divi_notification_body - Modify email body
 * - formshield_divi_notification_email - Modify recipient email
 * - formshield_divi_send_notification - Control email sending
 * 
 * Actions:
 * - formshield_divi_before_score_calculation - Before score calculation starts
 *   Parameters: ($message, $email, $name, $post_id, $form_id, $behavioral_data)
 * - formshield_divi_after_base_score - After base score calculated (before filters)
 *   Parameters: ($score, $message, $email, $name, $post_id, $form_id, $behavioral_data)
 * - formshield_divi_suspicious_submission_flagged - When submission is flagged as suspicious
 *   Parameters: ($unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id)
 * - formshield_divi_legitimate_submission - When submission is below threshold
 *   Parameters: ($unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id)
 * - formshield_divi_submission_checked - After all checks complete (always fired)
 *   Parameters: ($unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id)
 */
class FormShieldDiviSpamDetection {
    private static $instance = null;
    private $spam_patterns = array();
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        // DEBUG: Log initialization FIRST
        error_log('[FormShield DEBUG] FormShieldDiviSpamDetection __construct called');
        
        $this->init_spam_patterns();
        
        // DEBUG: Log initialization
        error_log('[FormShield DEBUG] FormShieldDiviSpamDetection initialized - hooks registered');
        
        // Hook into Divi form submission via custom AJAX endpoint
        // We'll intercept via JavaScript and send to our endpoint
        add_action('wp_ajax_formshield_check_divi_submission', array($this, 'check_divi_submission'));
        add_action('wp_ajax_nopriv_formshield_check_divi_submission', array($this, 'check_divi_submission'));
        
        // Non-AJAX fallback: intercept early POST submissions
        add_action('init', array($this, 'intercept_divi_post'), 1);
        
        // SERVER-SIDE PROTECTION: Hook into Divi's native form processing
        // This catches spam even if JavaScript is bypassed
        add_action('et_pb_contact_form_submit', array($this, 'server_side_spam_check'), 1, 3);
        add_filter('et_pb_contact_form_submit_message', array($this, 'filter_form_message'), 1, 2);
        
        // Also intercept the AJAX handler directly
        add_action('wp_ajax_et_pb_contact_form_submit', array($this, 'intercept_divi_ajax'), 1);
        add_action('wp_ajax_nopriv_et_pb_contact_form_submit', array($this, 'intercept_divi_ajax'), 1);
        
        // DEBUG: Hook into ALL AJAX requests to see what Divi 5 is using
        add_action('wp_ajax', array($this, 'debug_all_ajax'), 999);
        add_action('wp_ajax_nopriv', array($this, 'debug_all_ajax'), 999);
    }
    
    /**
     * DEBUG: Log all AJAX requests to see what Divi 5 uses
     */
    public function debug_all_ajax() {
        $action = isset($_REQUEST['action']) ? sanitize_text_field(wp_unslash($_REQUEST['action'])) : '';
        
        // Only log Divi-related AJAX
        if (strpos($action, 'et_') === 0 || strpos($action, 'divi') !== false || strpos($action, 'contact') !== false) {
            error_log('[FormShield DEBUG] AJAX action called: ' . $action);
            error_log('[FormShield DEBUG] POST keys: ' . implode(', ', array_keys($_POST)));
            
            // Check if this looks like a form submission
            if (isset($_POST['et_pb_contact_email_0']) || isset($_POST['et_pb_contact_message_0'])) {
                error_log('[FormShield DEBUG] This looks like a contact form submission!');
            }
        }
    }
    
    /**
     * Intercept Divi's native AJAX form submission
     * This runs BEFORE Divi processes the form
     */
    public function intercept_divi_ajax() {
        // DEBUG: Log entry
        error_log('[FormShield DEBUG] intercept_divi_ajax called - POST keys: ' . implode(', ', array_keys($_POST)));
        
        // Check if this is actually a contact form submission (not other Divi AJAX)
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $is_contact_form = isset($_POST['et_pb_contact_email_0']) || 
                           isset($_POST['et_pb_contact_message_0']) ||
                           isset($_POST['et_pb_contact_name_0']);
        
        if (!$is_contact_form) {
            // Not a contact form submission, let Divi handle it
            error_log('[FormShield DEBUG] intercept_divi_ajax - Not a contact form submission, skipping');
            return;
        }
        
        // Get message from POST data
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Divi handles its own nonce
        $message = isset($_POST['et_pb_contact_message_0']) ? sanitize_textarea_field(wp_unslash($_POST['et_pb_contact_message_0'])) : '';
        
        // Also check other message field patterns
        if (empty($message)) {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            foreach ($_POST as $key => $value) {
                if (strpos($key, 'message') !== false || strpos($key, 'Message') !== false || strpos($key, 'comment') !== false) {
                    $message = sanitize_textarea_field(wp_unslash($value));
                    break;
                }
            }
        }
        
        // Get email
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $email = isset($_POST['et_pb_contact_email_0']) ? sanitize_email(wp_unslash($_POST['et_pb_contact_email_0'])) : '';
        if (empty($email)) {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            foreach ($_POST as $key => $value) {
                if (strpos($key, 'email') !== false || strpos($key, 'Email') !== false) {
                    $email = sanitize_email(wp_unslash($value));
                    break;
                }
            }
        }
        
        // Get name
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $name = isset($_POST['et_pb_contact_name_0']) ? sanitize_text_field(wp_unslash($_POST['et_pb_contact_name_0'])) : '';
        
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $post_id = isset($_POST['et_pb_contact_form_num']) ? absint($_POST['et_pb_contact_form_num']) : 0;
        
        // DEBUG: Log received data
        error_log('[FormShield DEBUG] intercept_divi_ajax - Message: ' . substr($message, 0, 100) . ' | Email: ' . $email . ' | Name: ' . $name);
        
        // If no message and no email, skip spam check (incomplete form)
        if (empty($message) && empty($email)) {
            error_log('[FormShield DEBUG] intercept_divi_ajax - No message or email, skipping spam check');
            return;
        }
        
        // Calculate spam score
        $score = $this->calculate_suspicion_score($message, $email, $name, $post_id, 'divi_ajax', array());
        
        // Get threshold
        $threshold = apply_filters('formshield_divi_suspicion_threshold', 50, $post_id, 'divi_ajax');
        
        // DEBUG: Log score and threshold
        error_log('[FormShield DEBUG] intercept_divi_ajax - Score: ' . $score . ' | Threshold: ' . $threshold . ' | Will block: ' . ($score >= $threshold ? 'YES' : 'NO'));
        
        // If spam, block it immediately
        if ($score >= $threshold) {
            // Log the blocked submission
            $this->log_suspicious_submission('divi_ajax_' . $post_id, $message, $email, $score);
            
            // Record statistics
            if (class_exists('FormShieldForms')) {
                FormShieldForms::record_attack_statistics('divi_ajax_' . $post_id, 'spam');
            }
            
            // Send error response in Divi's expected format
            wp_send_json(array(
                'error' => true,
                'message' => __('Съобщението не може да бъде изпратено. Моля, опитайте отново без линкове.', 'formshield')
            ));
            exit;
        }
        
        // If not spam, let Divi continue processing
        error_log('[FormShield DEBUG] intercept_divi_ajax - Submission allowed, letting Divi continue');
        // (don't return anything, just let the action chain continue)
    }
    
    /**
     * Intercept non-AJAX Divi submissions (fallback)
     * Some hosts/cache setups bypass wp_ajax; catch direct POST early.
     */
    public function intercept_divi_post() {
        // Only run on POST requests with Divi contact data
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- handled by Divi; we only read
        $has_divi_post = isset($_POST['et_pb_contactform_submit']) || isset($_POST['et_pb_contact_email_0']) || isset($_POST['et_pb_contact_message_0']);
        if (!$has_divi_post) {
            return;
        }

        // Extract message
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $message = isset($_POST['et_pb_contact_message_0']) ? sanitize_textarea_field(wp_unslash($_POST['et_pb_contact_message_0'])) : '';
        if (empty($message)) {
            foreach ($_POST as $key => $value) {
                if (strpos($key, 'message') !== false || strpos($key, 'Message') !== false || strpos($key, 'comment') !== false) {
                    $message = sanitize_textarea_field(wp_unslash($value));
                    break;
                }
            }
        }

        // Extract email
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $email = isset($_POST['et_pb_contact_email_0']) ? sanitize_email(wp_unslash($_POST['et_pb_contact_email_0'])) : '';
        if (empty($email)) {
            foreach ($_POST as $key => $value) {
                if (strpos($key, 'email') !== false || strpos($key, 'Email') !== false) {
                    $email = sanitize_email(wp_unslash($value));
                    break;
                }
            }
        }

        // Extract name
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $name = isset($_POST['et_pb_contact_name_0']) ? sanitize_text_field(wp_unslash($_POST['et_pb_contact_name_0'])) : '';

        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $post_id = isset($_POST['et_pb_contact_form_num']) ? absint($_POST['et_pb_contact_form_num']) : 0;

        // Score the submission
        $score = $this->calculate_suspicion_score($message, $email, $name, $post_id, 'divi_post', array());
        $threshold = apply_filters('formshield_divi_suspicion_threshold', 50, $post_id, 'divi_post');

        if ($score >= $threshold) {
            $form_id = 'divi_post_' . $post_id;
            $this->log_suspicious_submission($form_id, $message, $email, $score);
            if (class_exists('FormShieldForms')) {
                FormShieldForms::record_attack_statistics($form_id, 'spam');
            }
            wp_die(
                __('Съобщението не може да бъде изпратено. Моля, премахнете линковете и опитайте отново.', 'formshield'),
                __('Достъпът е блокиран', 'formshield'),
                array('response' => 403)
            );
        }
    }
    
    /**
     * Server-side spam check for Divi forms
     * Fallback protection if JavaScript is bypassed
     */
    public function server_side_spam_check($fields, $info, $result) {
        // DEBUG: Log entry
        error_log('[FormShield DEBUG] server_side_spam_check called');
        
        // Extract message from fields
        $message = '';
        $email = '';
        $name = '';
        
        if (is_array($fields)) {
            foreach ($fields as $field) {
                if (isset($field['field_id'])) {
                    if (strpos(strtolower($field['field_id']), 'message') !== false) {
                        $message = isset($field['value']) ? $field['value'] : '';
                    }
                    if (strpos(strtolower($field['field_id']), 'email') !== false) {
                        $email = isset($field['value']) ? $field['value'] : '';
                    }
                    if (strpos(strtolower($field['field_id']), 'name') !== false) {
                        $name = isset($field['value']) ? $field['value'] : '';
                    }
                }
            }
        }
        
        // Calculate spam score
        $score = $this->calculate_suspicion_score($message, $email, $name, 0, 'server_side', array());
        
        // Get threshold
        $threshold = apply_filters('formshield_divi_suspicion_threshold', 50, 0, 'server_side');
        
        // If spam, throw error to stop processing
        if ($score >= $threshold) {
            // Log and record
            $this->log_suspicious_submission('divi_server_side', $message, $email, $score);
            
            // Trigger WordPress error that Divi will catch
            wp_die(__('Съобщението не може да бъде изпратено. Моля, опитайте отново без линкове.', 'formshield'), 'FormShield Spam Blocked', array('response' => 403));
        }
    }
    
    /**
     * Filter the form message before sending
     * Last chance to catch spam
     */
    public function filter_form_message($message, $fields) {
        // DEBUG: Log entry
        error_log('[FormShield DEBUG] filter_form_message called - Message: ' . substr($message, 0, 100));
        
        // Calculate spam score for the full message
        $score = $this->calculate_suspicion_score($message, '', '', 0, 'message_filter', array());
        
        // Get threshold  
        $threshold = apply_filters('formshield_divi_suspicion_threshold', 50, 0, 'message_filter');
        
        // If spam, return empty message to prevent sending
        if ($score >= $threshold) {
            $this->log_suspicious_submission('divi_filter', $message, '', $score);
            return ''; // Return empty to prevent email
        }
        
        return $message;
    }
    
    /**
     * Initialize spam detection patterns
     * Patterns can be filtered via 'formshield_divi_spam_patterns' filter
     */
    private function init_spam_patterns() {
        $default_patterns = array(
            // INSTANT BLOCK - тези pattern-и блокират веднага (100 точки)
            'instant_block' => array(
                // YouTube shorts - основен спам вектор
                '/youtube\.com\/shorts\/[a-zA-Z0-9_-]+/i',
                '/youtu\.be\/[a-zA-Z0-9_-]+/i',
                // Комбинация: затруднявате се + линк
                '/затруднявате\s+се.*https?:\/\//iu',
                '/struggling.*https?:\/\//i',
                // Комбинация: клиенти/трафик + линк
                '/(клиенти|трафик|traffic|clients|visitors).*https?:\/\//iu',
                '/https?:\/\/.*(клиенти|трафик|traffic|clients|visitors)/iu',
                // Гледайте това + линк
                '/гледайте\s+(това|видеото).*https?:\/\//iu',
                '/watch\s+this.*https?:\/\//i',
                // Само линк като съобщение (почти цялото съобщение е линк)
                '/^[\s\p{P}]*https?:\/\/[^\s]+[\s\p{P}]*$/iu',
            ),
            
            // External URLs - базови URL-та (20 точки)
            'urls' => array(
                '/(http|https|ftp):\/\/[^\s]+/i',
                '/www\.[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/i',
                '/[a-zA-Z0-9.-]+\.(com|net|org|info|biz|co\.uk|ru|cn)\b/i',
            ),
            
            // Short URL services - много подозрителни (40 точки)
            'short_urls' => array(
                '/\b(ow\.ly|bit\.ly|tinyurl|short\.link|t\.co|goo\.gl|rebrand\.ly|shortlink|shorten)\b/i',
                '/\b[a-z0-9]+\.(ly|link|short|tiny)\b/i',
                '/\b(rb\.gy|is\.gd|v\.gd|cutt\.ly|shorturl|tiny\.cc)\b/i',
            ),
            
            // YouTube и видео спам (35 точки)
            'youtube_spam' => array(
                '/youtube\.com\/shorts/i',
                '/youtube\.com\/watch/i',
                '/youtu\.be/i',
                '/\b(quick video|short video|see.*video|watch.*video)\b/i',
                '/\b(видео|видеото|гледайте|вижте)\b.*\b(youtube|video)\b/iu',
            ),
            
            // Marketing/Sales keywords - разширени (30 точки)
            'marketing' => array(
                '/\b(SEO|search engine optimization|traffic|backlinks|link building)\b/i',
                '/\b(AI marketing|artificial intelligence marketing|automated marketing|AI-driven|AI-optimized|AI-powered)\b/i',
                '/\b(ads|advertising|promotion|promote|marketing campaign|marketing solution)\b/i',
                '/\b(boost|increase|improve|grow).*\b(rankings|traffic|sales|revenue|visitors|visits)\b/i',
                '/\b(cheap|affordable|discount|special offer|limited time|cost-effective)\b/i',
                '/\b(targeted traffic|targeted visitors|keyword-specific|location-specific)\b/i',
                '/\b(delivers.*visitors|sends.*visitors|bring.*traffic)\b/i',
                '/\b(learn more|see how|check out|visit|click|watch)\b.*\b(video|solution|service)\b/i',
                // Български маркетинг фрази
                '/\b(затруднявате се|целеви клиенти|привлечете|повече клиенти|повече трафик|увеличете трафика|увеличете продажбите)\b/iu',
                '/\b(маркетингова кампания|рекламна кампания|seo услуги|линк билдинг|беклинкове)\b/iu',
            ),
            
            // Подозрителни домейни (35 точки)
            'suspicious_domains' => array(
                '/marketingaged\.com/i',
                '/marketing.*aged/i',
                '/traffic.*service/i',
                '/ai.*traffic/i',
                '/seo.*service/i',
                '/get.*traffic/i',
                '/buy.*traffic/i',
            ),
            
            // Generic/unrelated content patterns (15 точки)
            'generic' => array(
                '/\b(hello|hi|greetings|dear sir|dear madam)\b.*\b(website|site|page)\b/i',
                '/\b(great|nice|wonderful|excellent).*\b(website|site|blog)\b/i',
                '/\b(contact|reach|get in touch).*\b(regarding|about|concerning)\b/i',
                '/\b(want more|need more|looking for).*\b(traffic|visitors|clients|customers)\b/i',
            ),
        );
        
        // Store patterns for later use
        $this->spam_patterns = apply_filters('formshield_divi_default_spam_patterns', $default_patterns);
    }
    
    /**
     * Check Divi form submission
     * BLOCKS spam submissions that exceed the threshold
     */
    public function check_divi_submission() {
        // DEBUG: Log entry
        error_log('[FormShield DEBUG] check_divi_submission called');
        
        // Verify nonce
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'formshield_protection')) {
            error_log('[FormShield DEBUG] Invalid nonce');
            wp_send_json_error(array('message' => 'Invalid nonce'));
            return;
        }
        
        // Get form data from our JavaScript interceptor
        $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
        $form_id = isset($_POST['form_id']) ? sanitize_text_field(wp_unslash($_POST['form_id'])) : '';
        $message = isset($_POST['message']) ? sanitize_textarea_field(wp_unslash($_POST['message'])) : '';
        $email = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
        $name = isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : '';
        
        // DEBUG: Log received data
        error_log('[FormShield DEBUG] Received data - Message: ' . substr($message, 0, 100) . ' | Email: ' . $email . ' | Name: ' . $name);
        
        // Get behavioral data from JavaScript
        $behavioral_data = array();
        if (isset($_POST['behavioral_data'])) {
            $behavioral_json = sanitize_text_field(wp_unslash($_POST['behavioral_data']));
            $behavioral_data = json_decode($behavioral_json, true);
            if (!is_array($behavioral_data)) {
                $behavioral_data = array();
            }
        }
        
        // DEBUG: Log behavioral data
        error_log('[FormShield DEBUG] Behavioral data: ' . print_r($behavioral_data, true));
        
        // Calculate suspicion score
        $suspicion_score = $this->calculate_suspicion_score($message, $email, $name, $post_id, $form_id, $behavioral_data);
        
        // Get unique form identifier
        $unique_form_id = $this->get_unique_form_id($post_id, $form_id);
        
        // Allow filtering of suspicion threshold (default: 40 - aggressive protection)
        $suspicion_threshold = apply_filters('formshield_divi_suspicion_threshold', 50, $post_id, $form_id);
        
        // DEBUG: Log score and threshold
        error_log('[FormShield DEBUG] Score: ' . $suspicion_score . ' | Threshold: ' . $suspicion_threshold . ' | Will block: ' . ($suspicion_score >= $suspicion_threshold ? 'YES' : 'NO'));
        
        // If suspicious, BLOCK the submission
        if ($suspicion_score >= $suspicion_threshold) {
            $this->flag_suspicious_submission($unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data);
            
            // Log for admin review
            $this->log_suspicious_submission($unique_form_id, $message, $email, $suspicion_score);
            
            // Action hook when suspicious submission is blocked
            do_action('formshield_divi_suspicious_submission_flagged', $unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id);
            
            // Optionally send email notification
            $this->maybe_send_notification($unique_form_id, $message, $email, $suspicion_score);
            
            // Action hook after all checks
            do_action('formshield_divi_submission_checked', $unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id);
            
            // BLOCK the submission - return error
            wp_send_json_error(array(
                'message' => __('Съобщението не може да бъде изпратено. Моля, опитайте отново без линкове.', 'formshield'),
                'score' => $suspicion_score,
                'blocked' => true,
                'reason' => 'spam_detected'
            ));
            return;
        }
        
        // Action hook for legitimate submissions (below threshold)
        do_action('formshield_divi_legitimate_submission', $unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id);
        
        // Action hook after all checks (regardless of score)
        do_action('formshield_divi_submission_checked', $unique_form_id, $message, $email, $name, $suspicion_score, $behavioral_data, $post_id, $form_id);
        
        // Allow the submission
        wp_send_json_success(array(
            'message' => 'Submission allowed',
            'score' => $suspicion_score,
            'blocked' => false
        ));
    }
    
    /**
     * Calculate suspicion score (0-100)
     * Higher score = more suspicious
     * 
     * @param string $message Form message content
     * @param string $email Submitter email
     * @param string $name Submitter name
     * @param int $post_id Post ID where form is located
     * @param string $form_id Form identifier
     * @param array $behavioral_data Behavioral tracking data
     * @return int Suspicion score (0-100)
     */
    private function calculate_suspicion_score($message, $email, $name, $post_id, $form_id, $behavioral_data) {
        $score = 0;
        $score_breakdown = array(); // DEBUG: Track what adds points
        
        // Allow filtering of spam patterns before calculation
        $spam_patterns = apply_filters('formshield_divi_spam_patterns', $this->spam_patterns, $post_id, $form_id);
        
        // Allow filtering of behavioral data
        $behavioral_data = apply_filters('formshield_divi_behavioral_data', $behavioral_data, $post_id, $form_id);
        
        // Action hook before score calculation
        do_action('formshield_divi_before_score_calculation', $message, $email, $name, $post_id, $form_id, $behavioral_data);
        
        // ПЪРВО: Проверка за instant block patterns (100 точки = мигновено блокиране)
        if (isset($spam_patterns['instant_block'])) {
            foreach ($spam_patterns['instant_block'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    // Мигновено блокиране - това е 100% спам
                    error_log('[FormShield DEBUG] INSTANT BLOCK matched pattern: ' . $pattern);
                    return 100;
                }
            }
        }
        
        $has_url = false;
        $has_marketing = false;
        $has_short_url = false;
        $has_youtube = false;
        $has_generic = false;
        $has_language_mismatch = false;
        
        // 1. Check for short URL services (40 points - много подозрителни)
        if (isset($spam_patterns['short_urls'])) {
            foreach ($spam_patterns['short_urls'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 40;
                    $score_breakdown[] = 'Short URL: +40 (' . $pattern . ')';
                    $has_short_url = true;
                    $has_url = true;
                    break;
                }
            }
        }
        
        // 2. Check for YouTube spam links (35 points)
        if (isset($spam_patterns['youtube_spam'])) {
            foreach ($spam_patterns['youtube_spam'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 35;
                    $score_breakdown[] = 'YouTube spam: +35 (' . $pattern . ')';
                    $has_youtube = true;
                    $has_url = true;
                    break;
                }
            }
        }
        
        // 3. Check for suspicious domains (35 points)
        if (isset($spam_patterns['suspicious_domains'])) {
            foreach ($spam_patterns['suspicious_domains'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 35;
                    $score_breakdown[] = 'Suspicious domain: +35 (' . $pattern . ')';
                    $has_url = true;
                    break;
                }
            }
        }
        
        // 4. Check for external URLs (20 points)
        if (!$has_url && isset($spam_patterns['urls'])) {
            foreach ($spam_patterns['urls'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 20;
                    $score_breakdown[] = 'External URL: +20 (' . $pattern . ')';
                    $has_url = true;
                    break;
                }
            }
        }
        
        // 5. Check for marketing keywords (30 points)
        if (isset($spam_patterns['marketing'])) {
            foreach ($spam_patterns['marketing'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 30;
                    $score_breakdown[] = 'Marketing keyword: +30 (' . $pattern . ')';
                    $has_marketing = true;
                    break;
                }
            }
        }
        
        // 6. Комбинация URL + Marketing = допълнителни 20 точки (много подозрително)
        if ($has_url && $has_marketing) {
            $score += 20;
            $score_breakdown[] = 'URL + Marketing combo: +20';
        }
        
        // 7. YouTube + Marketing = допълнителни 25 точки (типичен спам pattern)
        if ($has_youtube && $has_marketing) {
            $score += 25;
            $score_breakdown[] = 'YouTube + Marketing combo: +25';
        }
        
        // 8. Check for generic/unrelated content (15 points)
        if (isset($spam_patterns['generic'])) {
            foreach ($spam_patterns['generic'] as $pattern) {
                if (preg_match($pattern, $message)) {
                    $score += 15;
                    $score_breakdown[] = 'Generic content: +15 (' . $pattern . ')';
                    $has_generic = true;
                    break;
                }
            }
        }
        
        // 9. Language mismatch check (if site language is Bulgarian, flag English-only messages)
        $site_language = get_locale();
        if (strpos($site_language, 'bg') === 0) {
            // Site is Bulgarian, check if message is only English
            if (!preg_match('/[а-яА-Я]/u', $message) && preg_match('/[a-zA-Z]/', $message)) {
                // Message is English but site is Bulgarian - might be spam
                if (strlen($message) > 50) { // Only flag longer messages
                    $score += 15;
                    $score_breakdown[] = 'Language mismatch: +15';
                    $has_language_mismatch = true;
                }
            }
        }
        
        $has_content_signal = $has_url || $has_marketing || $has_short_url || $has_youtube || $has_generic || $has_language_mismatch;
        
        // 10. Behavioral checks (only if there are other spam signals)
        if ($has_content_signal && is_array($behavioral_data) && !empty($behavioral_data)) {
            // Form submitted too fast (< 3 seconds)
            if (isset($behavioral_data['form_fill_time']) && $behavioral_data['form_fill_time'] > 0 && $behavioral_data['form_fill_time'] < 3) {
                $score += 25;
                $score_breakdown[] = 'Fast submission (<3s): +25';
            }
            
            // No mouse movement or focus events
            if ((!isset($behavioral_data['mouse_moves']) || $behavioral_data['mouse_moves'] === 0) && 
                (!isset($behavioral_data['focus_events']) || $behavioral_data['focus_events'] === 0)) {
                $score += 20;
                $score_breakdown[] = 'No mouse/focus events: +20';
            }
        }
        
        // 11. Suspicious user agent
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field($_SERVER['HTTP_USER_AGENT']) : '';
        if ($this->is_suspicious_user_agent($user_agent)) {
            $score += 15;
            $score_breakdown[] = 'Suspicious user agent: +15';
        }
        
        // 12. Check for duplicate submissions (same message, different emails)
        if ($has_content_signal && $this->is_duplicate_message($message, $email)) {
            $score += 30;
            $score_breakdown[] = 'Duplicate message: +30';
        }
        
        // Allow third-party plugins to add custom scoring rules
        $custom_score_delta = apply_filters('formshield_divi_custom_score_delta', 0, $message, $email, $name, $post_id, $form_id, $behavioral_data);
        if ($custom_score_delta != 0) {
            $score += intval($custom_score_delta);
            $score_breakdown[] = 'Custom filter: ' . ($custom_score_delta > 0 ? '+' : '') . $custom_score_delta;
        }
        
        // Action hook after base score calculation (before final adjustments)
        do_action('formshield_divi_after_base_score', $score, $message, $email, $name, $post_id, $form_id, $behavioral_data);
        
        // Allow filtering of final score before capping
        $score_before_filter = $score;
        $score = apply_filters('formshield_divi_suspicion_score', $score, $message, $email, $name, $post_id, $form_id, $behavioral_data);
        if ($score != $score_before_filter) {
            $score_breakdown[] = 'Score filter modified: ' . $score_before_filter . ' -> ' . $score;
        }
        
        // DEBUG: Log score breakdown
        error_log('[FormShield DEBUG] Score breakdown: ' . implode(' | ', $score_breakdown));
        error_log('[FormShield DEBUG] Final score: ' . $score);
        
        // Cap at 100
        return min(100, max(0, intval($score)));
    }
    
    /**
     * Check if user agent looks automated
     */
    private function is_suspicious_user_agent($user_agent) {
        if (empty($user_agent)) {
            return true;
        }
        
        $suspicious_patterns = array(
            '/bot/i',
            '/crawler/i',
            '/spider/i',
            '/scraper/i',
            '/curl/i',
            '/wget/i',
            '/python/i',
            '/php/i',
        );
        
        foreach ($suspicious_patterns as $pattern) {
            if (preg_match($pattern, $user_agent)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Check for duplicate messages with different emails
     */
    private function is_duplicate_message($message, $email) {
        if (empty($message) || strlen($message) < 20) {
            return false; // Too short to be meaningful
        }
        
        // Normalize message for comparison
        $normalized_message = strtolower(trim(preg_replace('/\s+/', ' ', $message)));
        $message_hash = md5($normalized_message);
        
        // Check if we've seen this message before with a different email
        $seen_messages = get_option('formshield_seen_messages', array());
        
        if (isset($seen_messages[$message_hash])) {
            $previous_email = $seen_messages[$message_hash];
            if ($previous_email !== $email) {
                // Same message, different email - suspicious!
                return true;
            }
        } else {
            // Store this message
            $seen_messages[$message_hash] = $email;
            // Keep only last 1000 messages
            if (count($seen_messages) > 1000) {
                $seen_messages = array_slice($seen_messages, -1000, null, true);
            }
            update_option('formshield_seen_messages', $seen_messages);
        }
        
        return false;
    }
    
    /**
     * Get unique form identifier using post_id + form_id
     */
    private function get_unique_form_id($post_id, $form_id) {
        if (!empty($form_id)) {
            return 'divi_' . $post_id . '_' . md5($form_id);
        }
        return 'divi_' . $post_id;
    }
    
    /**
     * Flag suspicious submission
     */
    private function flag_suspicious_submission($form_id, $message, $email, $name, $score, $behavioral_data) {
        $options = FormShield::get_options();
        
        if (!isset($options['formshield_forms'][$form_id])) {
            $options['formshield_forms'][$form_id] = array(
                'form_enabled' => 1,
                'form_type' => 'Divi Contact Form',
                'form_name' => 'Divi Form',
                'form_date' => current_time('mysql'),
            );
        }
        
        // Increment suspicious count
        if (!isset($options['formshield_forms'][$form_id]['suspicious_ct'])) {
            $options['formshield_forms'][$form_id]['suspicious_ct'] = 0;
        }
        $options['formshield_forms'][$form_id]['suspicious_ct']++;
        
        // Update last suspicious activity
        $options['formshield_forms'][$form_id]['last_suspicious_activity'] = current_time('mysql');
        
        // Store suspicion details
        if (!isset($options['formshield_forms'][$form_id]['suspicious_details'])) {
            $options['formshield_forms'][$form_id]['suspicious_details'] = array();
        }
        
        $options['formshield_forms'][$form_id]['suspicious_details'][] = array(
            'timestamp' => current_time('mysql'),
            'score' => $score,
            'email' => $email,
            'message_preview' => substr($message, 0, 100),
            'behavioral_data' => $behavioral_data,
        );
        
        // Keep only last 50 suspicious details
        if (count($options['formshield_forms'][$form_id]['suspicious_details']) > 50) {
            $options['formshield_forms'][$form_id]['suspicious_details'] = array_slice(
                $options['formshield_forms'][$form_id]['suspicious_details'],
                -50
            );
        }
        
        FormShield::update_options($options);
        
        // Record in attack statistics
        FormShieldForms::record_attack_statistics($form_id, 'spam');
    }
    
    /**
     * Log suspicious submission
     */
    private function log_suspicious_submission($form_id, $message, $email, $score) {
        // Log to activity log if table exists
        global $wpdb;
        $table_name = $wpdb->prefix . 'formshield_activity_log';
        
        if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name) {
            $wpdb->insert(
                $table_name,
                array(
                    'ip_address' => formshield_get_validated_ip('Unknown'),
                    'timestamp' => current_time('mysql'),
                    'is_suspicious' => 1,
                    'validation_data' => wp_json_encode(array(
                        'form_id' => $form_id,
                        'score' => $score,
                        'message_preview' => substr($message, 0, 255),
                        'email' => $email,
                        'type' => 'divi_form_suspicious'
                    ))
                ),
                array('%s', '%s', '%d', '%s')
            );
        }
    }
    
    /**
     * Maybe send email notification for suspicious submission
     */
    private function maybe_send_notification($form_id, $message, $email, $score) {
        $options = FormShield::get_options();
        
        // Check if notifications are enabled
        if (!isset($options['attack_notifications']) || !$options['attack_notifications']) {
            return;
        }
        
        // Allow filtering of email notification threshold (default: 70)
        $email_threshold = apply_filters('formshield_divi_email_notification_threshold', 70, $form_id);
        
        // Only send if score is high enough
        if ($score < $email_threshold) {
            return;
        }
        
        // Allow filtering to prevent email notification
        $should_notify = apply_filters('formshield_divi_should_send_notification', true, $form_id, $message, $email, $score);
        if (!$should_notify) {
            return;
        }
        
        $admin_email = isset($options['admin_email']) ? $options['admin_email'] : get_option('admin_email');
        
        // Allow filtering of email subject and body
        $subject = apply_filters(
            'formshield_divi_notification_subject',
            sprintf('[FormShield] Suspicious Divi Form Submission (Score: %d)', $score),
            $form_id,
            $score,
            $email
        );
        
        $default_body = sprintf(
            "A suspicious form submission was flagged on %s\n\n" .
            "Form ID: %s\n" .
            "Suspicion Score: %d/100\n" .
            "Email: %s\n" .
            "Message Preview: %s\n\n" .
            "This submission was flagged but NOT blocked. Please review it manually.\n\n" .
            "---\n" .
            "FormShield Plugin",
            get_bloginfo('name'),
            $form_id,
            $score,
            $email,
            substr($message, 0, 200)
        );
        
        $body = apply_filters(
            'formshield_divi_notification_body',
            $default_body,
            $form_id,
            $message,
            $email,
            $score
        );
        
        // Allow filtering of admin email
        $admin_email = apply_filters('formshield_divi_notification_email', $admin_email, $form_id, $score);
        
        // Send email (can be filtered to use custom email function)
        $email_sent = apply_filters('formshield_divi_send_notification', true, $admin_email, $subject, $body, $form_id, $score);
        if ($email_sent) {
            wp_mail($admin_email, $subject, $body);
        }
    }
}

// Initialize
FormShieldDiviSpamDetection::get_instance();

