<?php
/**
 * Enhanced Settings Management Class
 * Handles all plugin settings and configurations with full database integration
 * comprehensive sanitization using SanitizationEngine and robust validation using ValidationEngine
 *
 * Refactored to use AjaxResponseBuilder (v3.0.0)
 * Last updated: 2024-01-15
 * Changes: All AJAX handlers now use fluent response builder interface with enhanced frontend actions
 */

namespace UltraguardPro\modules\settings;

use WP_Error;
use UltraguardPro\core\SanitizationEngine;
use UltraguardPro\core\ValidationEngine;
use UltraguardPro\support\AjaxResponseBuilder;
use UltraguardPro\core\CacheManager;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Settings migration and legacy option introspection intentionally query live option state.

class Settings {

    private static $instance = null;

    const OPTION_NAME = 'ultraguard_pro_settings';
    const SETTINGS_VERSION = '1.2.0';

    /**
     * Public settings that may be safely read before authentication.
     *
     * These power login-page UX such as 2FA and CAPTCHA widgets.
     *
     * @var string[]
     */
    private const PUBLIC_SETTING_ALLOWLIST = [
        'two_factor_enabled',
        'two_factor_allow_self_enroll',
        'two_factor_issuer_name',
        'two_factor_show_setup_prompt',
        'two_factor_grace_period_days',
        'passkey_allow_recovery_codes',
        'login_protect_enabled',
        'loginlimiter_captcha_enabled',
        'loginlimiter_captcha_provider',
        'loginlimiter_turnstile_site_key',
        'loginlimiter_recaptcha_site_key',
    ];

    /**
     * Credential-like substrings that must never be exposed by the frontend
     * setting endpoint, even to administrators.
     *
     * @var string[]
     */
    private const PRIVATE_KEY_PATTERNS = [
        '_nonce',
        '_secret',
        '_api_key',
        '_private_key',
        '_password',
        '_token',
        '_webhook_url',
    ];

    /**
     * Sanitization engine instance
     */
    private $sanitization_engine = null;

    /**
     * Validation engine instance
     */
    private $validation_engine = null;

    /**
     * Default settings with enhanced structure
     */
    private $default_settings = [
        // =========================================================================
        // VERSION & TRACKING
        // =========================================================================
        '_version' => self::SETTINGS_VERSION,
        '_last_updated' => '',
        '_updated_by' => 0,

        // =========================================================================
        // GENERAL SETTINGS
        // =========================================================================
        'plugin_enabled' => true,
        'admin_email' => '',
        'is_email_notifications' => false,
        'log_retention_days' => 30,
        'auto_cleanup' => true,
        'enable_debug_log' => false,

        // =========================================================================
        // FIREWALL SETTINGS
        // =========================================================================
        'firewall_enabled' => true,
        'firewall_mode' => 'learning',
        'blocked_countries' => [],
        'whitelist_ips' => [],
        'blacklist_ips' => [],
        'block_tor_users' => false,
        'block_proxy_users' => false,
        'rate_limiting_enabled' => true,
        'rate_limit_requests' => 100,
        'rate_limit_period' => 3600,
        'enable_geo_blocking' => false,
        'custom_firewall_rules' => '',

        // =========================================================================
        // LOGIN PROTECTION SETTINGS
        // =========================================================================
        'login_limiter_enabled' => true,
        'max_login_attempts' => 5,
        'lockout_duration' => 1800,
        'lockout_duration_increment' => true,
        'notify_lockouts' => true,
        'captcha_after_attempts' => 3,
        'two_factor_auth' => false,
        'strong_password_enforcement' => true,
        'login_page_protection' => true,
        'hide_wp_admin' => false,
        'session_management' => true,
        'inactive_logout' => 3600,

        // =========================================================================
        // ANTIVIRUS & FILE INTEGRITY — owned by their modules, not stored here.
        // These keys are read via Settings::get_option() which routes to the
        // ultraguard_antivirus_settings / ultraguard_filechecker_settings blobs.
        // =========================================================================

        // =========================================================================
        // HTACCESS PROTECTION SETTINGS
        // =========================================================================
        'htaccess_protection' => true,
        'block_wp_config_access' => true,
        'block_directory_browsing' => true,
        'disable_file_editing' => true,
        'hide_wp_version' => true,
        'block_author_scanning' => true,
        'disable_xmlrpc' => true,
        'custom_htaccess_rules' => '',
        // =========================================================================
        // ADVANCED SECURITY SETTINGS
        // =========================================================================
        'security_headers' => true,
        'content_security_policy' => false,
        'disable_wp_debug' => true,
        'remove_wp_generator' => true,
        'disable_wp_api' => false,
        'database_security' => true,
        'file_permissions_check' => true,
        'ssl_enforcement' => false,
        'backup_before_actions' => true,
        'emergency_contact' => '',

        // =========================================================================
        // LOGGING SETTINGS
        // =========================================================================
        'detailed_logging' => true,
        'log_successful_logins' => false,
        'log_admin_actions' => true,
        'log_file_changes' => true,
        'export_logs' => false,
        'log_rotation' => true,
        'log_compression' => false,

        // =========================================================================
        // PERFORMANCE SETTINGS
        // =========================================================================
        'cache_scan_results' => true,
        'background_processing' => true,
        'memory_limit' => 256,
        'max_execution_time' => 300,
        'optimize_database' => true,
        'cleanup_schedule' => 'daily',

        // =========================================================================
        // NOTIFICATION SETTINGS
        // =========================================================================
        'critical_threat_notification' => true,
        'is_daily_summary_email' => false,
        'is_weekly_report_email' => true,
        'telegram_notifications' => false,
        'telegram_bot_token' => '',
        'telegram_chat_id' => '',
        'slack_notifications' => false,
        'slack_webhook_url' => '',
        'push_notifications' => false,
        'notification_threshold' => 'medium',

        // =========================================================================
        // MULTISITE SETTINGS
        // =========================================================================
        'network_wide_protection' => false,
        'subsite_settings_control' => 'limited',
        'centralized_logging' => true,

        // =========================================================================
        // VULNERABILITY SCANNER (Section C)
        // =========================================================================
        'wpscan_api_key'                   => '',
        'vulnerability_auto_scan'          => true,
        'vulnerability_virtual_patch'      => true,
        'vulnerability_notify_on_critical' => true,
        'vulnerability_last_scan'          => '',
    ];

    /**
     * Validation rules for all settings
     */
    private $validation_rules = [
        // Version & Tracking
        '_version' => ['required' => false, 'pattern' => '/^[0-9]+\.[0-9]+\.[0-9]+$/'],
        '_last_updated' => ['required' => false, 'datetime' => ['format' => 'Y-m-d H:i:s']],
        '_updated_by' => ['required' => false, 'number' => true],

        // General Settings
        'plugin_enabled' => 'bool',
        'admin_email' => ['required' => false, 'email' => true],
        'is_email_notifications' => 'bool',
        'log_retention_days' => ['number' => ['min' => 1, 'max' => 365]],
        'auto_cleanup' => 'bool',
        'enable_debug_log' => 'bool',

        // Firewall Settings
        'firewall_enabled' => 'bool',
        'firewall_mode' => ['in' => ['learning', 'active', 'disabled']],
        'blocked_countries' => ['required' => false, 'array' => true],
        'whitelist_ips' => ['required' => false, 'array' => true],
        'blacklist_ips' => ['required' => false, 'array' => true],
        'block_tor_users' => 'bool',
        'block_proxy_users' => 'bool',
        'rate_limiting_enabled' => 'bool',
        'rate_limit_requests' => ['number' => ['min' => 1, 'max' => 10000]],
        'rate_limit_period' => ['number' => ['min' => 60, 'max' => 86400]],
        'enable_geo_blocking' => 'bool',
        'custom_firewall_rules' => ['required' => false, 'text' => true],

        // Login Protection
        'login_limiter_enabled' => 'bool',
        'max_login_attempts' => ['number' => ['min' => 1, 'max' => 100]],
        'lockout_duration' => ['number' => ['min' => 60, 'max' => 86400]],
        'lockout_duration_increment' => 'bool',
        'notify_lockouts' => 'bool',
        'captcha_after_attempts' => ['number' => ['min' => 1, 'max' => 100]],
        'two_factor_auth' => 'bool',
        'strong_password_enforcement' => 'bool',
        'login_page_protection' => 'bool',
        'hide_wp_admin' => 'bool',
        'session_management' => 'bool',
        'inactive_logout' => ['number' => ['min' => 300, 'max' => 86400]],

        // Antivirus & FileChecker validation — handled by each module's field_schema().

        // HTACCESS Protection
        'htaccess_protection' => 'bool',
        'block_wp_config_access' => 'bool',
        'block_directory_browsing' => 'bool',
        'disable_file_editing' => 'bool',
        'hide_wp_version' => 'bool',
        'block_author_scanning' => 'bool',
        'disable_xmlrpc' => 'bool',
        'custom_htaccess_rules' => ['required' => false, 'text' => true],
        // Advanced Security
        'security_headers' => 'bool',
        'content_security_policy' => 'bool',
        'disable_wp_debug' => 'bool',
        'remove_wp_generator' => 'bool',
        'disable_wp_api' => 'bool',
        'database_security' => 'bool',
        'file_permissions_check' => 'bool',
        'ssl_enforcement' => 'bool',
        'backup_before_actions' => 'bool',
        'emergency_contact' => ['required' => false, 'email' => true],

        // Logging Settings
        'detailed_logging' => 'bool',
        'log_successful_logins' => 'bool',
        'log_admin_actions' => 'bool',
        'log_file_changes' => 'bool',
        'export_logs' => 'bool',
        'log_rotation' => 'bool',
        'log_compression' => 'bool',

        // Performance Settings
        'cache_scan_results' => 'bool',
        'background_processing' => 'bool',
        'memory_limit' => ['number' => ['min' => 64, 'max' => 1024]],
        'max_execution_time' => ['number' => ['min' => 30, 'max' => 600]],
        'optimize_database' => 'bool',
        'cleanup_schedule' => ['in' => ['hourly', 'daily', 'weekly', 'monthly']],

        // Notification Settings
        'critical_threat_notification' => 'bool',
        'is_daily_summary_email' => 'bool',
        'is_weekly_report_email' => 'bool',
        'telegram_notifications' => 'bool',
        'telegram_bot_token' => ['required' => false, 'text' => true],
        'telegram_chat_id' => ['required' => false, 'text' => true],
        'slack_notifications' => 'bool',
        'slack_webhook_url' => ['required' => false, 'url' => true],
        'push_notifications' => 'bool',
        'notification_threshold' => ['in' => ['low', 'medium', 'high', 'critical']],

        // Multisite Settings
        'network_wide_protection' => 'bool',
        'subsite_settings_control' => ['in' => ['none', 'limited', 'full']],
        'centralized_logging' => 'bool',
    ];
    /**
     * Dynamic module prefix → storage-key registry.
     * Populated by each module calling register_module_prefix() in its constructor.
     * Format: [ 'antivirus_' => 'antivirus', 'loginlimiter_' => 'loginlimiter', … ]
     *
     * @var array<string,string>
     */
    private array $module_registry = [];

    /**
     * Module settings schema registry.
     *
     * Populated by each module calling register_settings_schema().
     * Format: [
     *   'storage_key' => [
     *     'prefix'  => 'passkey_',
     *     'schema'  => [
     *       'passkey_allow_recovery_codes' => [ 'type' => 'bool',   'default' => true  ],
     *       'passkey_required_roles'       => [ 'type' => 'array',  'default' => []    ],
     *     ],
     *   ],
     * ]
     *
     * @var array<string, array{prefix: string, schema: array<string, array>}>
     */
    private array $schema_registry = [];

    /**
     * Current settings cache
     */
    private $settings = [];

    /**
     * Plugin instance
     */
    private $plugin = null;

    /**
     * Cache key for settings
     */
    private $cache_key = 'ultraguard_pro_settings_cache';

    /**
     * Get singleton instance
     */
    public static function get_instance($plugin = null): self {
        if (null === self::$instance) {
            self::$instance = new self($plugin);
        } elseif ($plugin !== null && self::$instance->plugin === null) {
            // Allow the plugin reference to be injected exactly once after first
            // construction (e.g. when Settings::get_instance() is called without
            // $plugin during the autoloader phase, then again from Plugin::init()).
            // Once set, the reference is never replaced.
            self::$instance->plugin = $plugin;
        }
        return self::$instance;
    }

    /**
     * Constructor
     *
     * Core foundation only — AJAX registration and cron scheduling are the
     * responsibility of SettingsModule (or the owning module).  This class
     * provides the data-layer API; it must not self-register hooks.
     */
    private function __construct($plugin = null) {
        $this->plugin = $plugin;
        $this->sanitization_engine = SanitizationEngine::get_instance();
        $this->validation_engine = ValidationEngine::get_instance();
        $this->load_settings();

        // Register custom validators
        $this->register_custom_validators();
    }

    /**
     * Register custom validators for specific settings
     */
    private function register_custom_validators(): void {
        // Register IP address list validator
        $this->validation_engine->register_validator('ip_list', function($value, $args, $context) {
            if (empty($value) || !is_array($value)) {
                return true;
            }

            foreach ($value as $ip) {
                if (!$this->validate_ip($ip) && !$this->is_valid_ip_range($ip)) {
                    /* translators: %s: string */
                    return sprintf(__('Invalid IP address or range: %s', 'ultraguard-security-suite'), esc_html($ip));
                }
            }
            return true;
        });

        // Register country code validator
        $this->validation_engine->register_validator('country_code_list', function($value, $args, $context) {
            if (empty($value) || !is_array($value)) {
                return true;
            }

            foreach ($value as $country) {
                if (!preg_match('/^[A-Z]{2}$/', $country)) {
                    /* translators: %s: string */
                    return sprintf(__('Invalid country code: %s', 'ultraguard-security-suite'), esc_html($country));
                }
            }
            return true;
        });

        // Register file extension validatorultraguard_save_dashboard_settings
        $this->validation_engine->register_validator('file_extension_list', function($value, $args, $context) {
            if (empty($value) || !is_array($value)) {
                return true;
            }

            foreach ($value as $extension) {
                if (!preg_match('/^[a-z0-9]{1,10}$/', strtolower(ltrim($extension, '.')))) {
                    /* translators: %s: string */
                    return sprintf(__('Invalid file extension: %s', 'ultraguard-security-suite'), esc_html($extension));
                }
            }
            return true;
        });

        // Register directory path validator
        $this->validation_engine->register_validator('directory_list', function($value, $args, $context) {
            if (empty($value) || !is_array($value)) {
                return true;
            }

            foreach ($value as $directory) {
                if (!$this->validate_file_path($directory, false) ||
                    strpos($directory, '..') !== false ||
                    strpos($directory, chr(0)) !== false) {
                    /* translators: %s: string */
                    return sprintf(__('Invalid directory path: %s', 'ultraguard-security-suite'), esc_html($directory));
                }
            }
            return true;
        });

        // Register numeric dependency validator
        $this->validation_engine->register_validator('numeric_dependency', function($value, $args, $context) {
            if (empty($args['depends_on']) || !isset($args['condition'])) {
                return true;
            }

            $dependency_value = $this->get_option($args['depends_on']);

            if ($args['condition'] === 'less_than' && $value >= $dependency_value) {
                /* translators: %s: string */
                return sprintf(__('Value must be less than %s', 'ultraguard-security-suite'), $dependency_value);
            }

            if ($args['condition'] === 'greater_than' && $value <= $dependency_value) {
                /* translators: %s: string */
                return sprintf(__('Value must be greater than %s', 'ultraguard-security-suite'), $dependency_value);
            }

            return true;
        });
    }

    /**
     * Prevent cloning
     */
    private function __clone() {}

    /**
     * Prevent unserialization
     */
    public function __wakeup() {
        throw new \Exception(esc_html( "Cannot unserialize singleton" ));
    }

    /**
     * Enhanced load settings with caching
     */
    private function load_settings(): void {
        // Security: Capability check for settings access
        if (!$this->isCurrentUserAdmin() && !wp_doing_cron() && !wp_doing_ajax()) {
            $this->settings = $this->default_settings;
            return;
        }

        // Try to get cached settings first
        $cached_settings = $this->get_cache($this->cache_key);

        if ($cached_settings !== false && is_array($cached_settings)) {
            $this->settings = $cached_settings;
            return;
        }

        $this->load_settings_from_database();

        // Cache the settings for 1 hour
        $this->set_cache($this->cache_key, $this->settings, HOUR_IN_SECONDS);
    }

    /**
     * Load settings from database with enhanced error handling
     */
    private function load_settings_from_database(): array {
        try {
            $saved_settings = $this->get_wp_option(self::OPTION_NAME, [], false);

            // Handle multisite settings with secure fallback
            if (is_multisite() && $this->should_use_network_settings()) {
                $saved_settings = get_site_option(self::OPTION_NAME, []);
            }

            // Validate loaded settings — only checks keys that have a known rule.
            // Module-owned keys have no rules and are intentionally skipped.
            // On error: log and continue with whatever was loaded; do NOT wipe
            // the entire blob (that would destroy module settings on every load).
            $validation_result = $this->validate_loaded_settings($saved_settings);
            if ($validation_result !== true) {
                $this->log_error('Invalid settings loaded from database: ' . implode(', ', $validation_result));
                // Keep $saved_settings — individual bad values will fall back to
                // defaults via wp_parse_args below.
            }

            // Use wp_parse_args for secure merging with defaults
            $this->settings = wp_parse_args($saved_settings, $this->default_settings);

            // Ensure admin email is set with secure fallback
            if (empty($this->settings['admin_email'])) {
                $this->settings['admin_email'] = $this->get_wp_option('admin_email', '');
            }

            // Set update tracking with secure defaults
            if (empty($this->settings['_last_updated'])) {
                $this->settings['_last_updated'] = current_time('mysql');
            }

            // Check if settings need migration
            if (!isset($this->settings['_version']) || version_compare($this->settings['_version'], self::SETTINGS_VERSION, '<')) {
                $this->migrate_settings();
            }

            // Validate settings structure
            $this->validate_settings_structure();

            return $this->settings;

        } catch (\Exception $e) {
            $this->log_error('Failed to load settings: ' . $e->getMessage());
            $this->settings = $this->default_settings;
            return $this->settings;
        }
    }

    /**
     * Validate loaded settings before using them
     */
    private function validate_loaded_settings($settings) {
        if (!is_array($settings)) {
            return [__('Invalid settings format', 'ultraguard-security-suite')];
        }

        $errors = [];

        // Validate each setting against rules
        foreach ($settings as $key => $value) {
            if (isset($this->validation_rules[$key])) {
                $rule = $this->validation_rules[$key];
                $validation_result = $this->validate_single_setting($key, $value, $rule);

                if ($validation_result !== true) {
                    /* translators: %1$s: string, %2$s: string */
                    $errors[] = sprintf(__('Invalid value for %1$s: %2$s', 'ultraguard-security-suite'), $key, $validation_result);
                }
            }
        }

        return empty($errors) ? true : $errors;
    }

    /**
     * Validate a single setting using ValidationEngine
     */
    private function validate_single_setting($key, $value, $rule) {
        // Convert rule to ValidationEngine format
        $validation_rules = $this->convert_rule_to_validation_format($rule);

        // Skip validation for empty non-required fields
        if (empty($value) && isset($validation_rules['required']) && !$validation_rules['required']) {
            return true;
        }

        // Create data array for validation
        $data = [$key => $value];
        $rules = [$key => $validation_rules];

        // Validate using ValidationEngine
        $is_valid = $this->validation_engine->validate($data, $rules, [
            'strict_mode' => false,
            'bail' => true
        ]);

        if (!$is_valid) {
            $errors = $this->validation_engine->get_errors();
            return $errors[$key] ?? __('Validation failed', 'ultraguard-security-suite');
        }

        return true;
    }

    /**
     * Convert internal rule format to ValidationEngine format
     */
    private function convert_rule_to_validation_format($rule) {
        if (is_string($rule)) {
            switch ($rule) {
                case 'bool':
                    return 'bool';
                case 'email':
                    return 'email';
                case 'url':
                    return 'url';
                case 'alphanumeric':
                    return 'alphanumeric';
                case 'datetime':
                    return ['datetime' => ['format' => 'Y-m-d H:i:s']];
                default:
                    return $rule;
            }
        }

        if (is_array($rule)) {
            $validation_rules = [];

            foreach ($rule as $rule_key => $rule_value) {
                switch ($rule_key) {
                    case 'required':
                        if ($rule_value === false) {
                            // For non-required fields, we handle empty values differently
                            continue 2;
                        }
                        $validation_rules['required'] = true;
                        break;

                    case 'email':
                    case 'url':
                    case 'bool':
                        $validation_rules[$rule_key] = true;
                        break;

                    case 'number':
                        if (is_array($rule_value)) {
                            $validation_rules['number'] = $rule_value;
                        } else {
                            $validation_rules['number'] = true;
                        }
                        break;

                    case 'in':
                        $validation_rules['in'] = $rule_value;
                        break;

                    case 'pattern':
                        $validation_rules['pattern'] = $rule_value;
                        break;

                    case 'min_length':
                    case 'max_length':
                        $validation_rules[$rule_key] = $rule_value;
                        break;

                    case 'text':
                        // Text validation - just check it's a string
                        $validation_rules['min_length'] = 0;
                        break;

                    case 'array':
                        // Array validation
                        $validation_rules['required'] = false;
                        break;

                    case 'datetime':
                        if (is_array($rule_value) && isset($rule_value['format'])) {
                            $validation_rules['datetime'] = ['format' => $rule_value['format']];
                        } else {
                            $validation_rules['datetime'] = ['format' => 'Y-m-d H:i:s'];
                        }
                        break;
                }
            }

            return $validation_rules;
        }

        return [];
    }
    /**
     * Enhanced migrate settings
     */
    private function migrate_settings(): void {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return;
        }

        $old_version = $this->settings['_version'] ?? '1.0.0';

        try {
            // Migration from version 1.0.0 to 1.2.0
            if (version_compare($old_version, '1.2.0', '<')) {
                // Add new settings with default values using wp_parse_args for safety
                $new_settings = [
                    'enable_debug_log' => false,
                    'enable_geo_blocking' => false,
                    'custom_firewall_rules' => '',
                    'session_management' => true,
                    'inactive_logout' => 3600,
                    'malware_signature_updates' => true,
                    'heuristic_analysis' => true,
                    'baseline_auto_update' => true,
                    'checksum_verification' => true,
                    'backup_before_actions' => true,
                    'emergency_contact' => '',
                    'log_rotation' => true,
                    'log_compression' => false,
                    'optimize_database' => true,
                    'cleanup_schedule' => 'daily',
                    'push_notifications' => false,
                    'notification_threshold' => 'medium',
                    'network_wide_protection' => false,
                    'subsite_settings_control' => 'limited',
                    'centralized_logging' => true
                ];

                $this->settings = wp_parse_args($new_settings, $this->settings);
            }

            // Update version and tracking
            $this->settings['_version'] = self::SETTINGS_VERSION;
            $this->settings['_last_updated'] = current_time('mysql');
            $this->settings['_updated_by'] = get_current_user_id();

            $this->save_settings_to_database();

            // Log the migration
            $this->log_info('Settings migrated successfully', [
                'from_version' => $old_version,
                'to_version' => self::SETTINGS_VERSION,
                'migrated_by' => get_current_user_id()
            ]);

        } catch (\Exception $e) {
            $this->log_error('Settings migration failed: ' . $e->getMessage());
        }
    }

    /**
     * Validate settings structure
     */
    private function validate_settings_structure(): void {
        // Ensure all core default keys are present.
        $this->settings = wp_parse_args($this->settings, $this->default_settings);

        // Do NOT strip unknown keys.  Module settings (e.g. passkey_allow_recovery_codes,
        // loginlimiter_max_attempts) are stored in the same blob by save_module_settings()
        // and must be preserved across loads.  Each module is responsible for sanitising
        // and validating its own keys before they reach this class.
    }

    /**
     * Register settings with WordPress
     */
    public function register_settings(): void {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return;
        }

        register_setting(
            'ultraguard_pro_settings',
            self::OPTION_NAME,
            [
                'sanitize_callback' => [$this, 'sanitize_settings'],
                'default' => $this->default_settings
            ]
        );

        // Register additional settings for multisite
        if (is_multisite()) {
            register_setting(
                'ultraguard_pro_network_settings',
                self::OPTION_NAME . '_network',
                [
                    'sanitize_callback' => [$this, 'sanitize_network_settings'],
                    'default' => []
                ]
            );
        }
    }

    /**
     * Set default options on plugin activation
     */
    public function set_default_options(): bool {
        // Security: Capability check
        if (!current_user_can('activate_plugins')) {
            return false;
        }

        try {
            $current_settings = $this->should_use_network_settings() ?
                get_site_option(self::OPTION_NAME, []) :
                $this->get_wp_option(self::OPTION_NAME, [], false);

            if (empty($current_settings)) {
                $this->settings = $this->default_settings;

                // Set admin email if not already set
                if (empty($this->settings['admin_email'])) {
                    $this->settings['admin_email'] = $this->get_wp_option('admin_email', '');
                }

                // Set initial tracking
                $this->settings['_last_updated'] = current_time('mysql');
                $this->settings['_updated_by'] = get_current_user_id();

                // Validate default settings before saving
                $validation_result = $this->validate_settings();
                if ($validation_result !== true) {
                    $this->log_error('Default settings validation failed: ' . implode(', ', $validation_result));
                    return false;
                }

                $this->save_settings_to_database();

                // Log the initialization
                $this->log_info('Default settings initialized', [
                    'initialized_by' => get_current_user_id(),
                    'blog_id' => get_current_blog_id()
                ]);
            }

            $this->clear_cache();
            return true;

        } catch (\Exception $e) {
            $this->log_error('Failed to set default options: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Enhanced get option value with security checks and database fallback
     */
    public function get_option($option_name, $default = null) {
        // Security: Validate option name
        if (!is_string($option_name) || empty($option_name)) {
            return $default;
        }

        // Security: Check for sensitive options
        $sensitive_options = [
            'telegram_bot_token',
            'slack_webhook_url',
            'admin_email',
            'emergency_contact',
            'telegram_chat_id'
        ];

        if (in_array($option_name, $sensitive_options) && !$this->isCurrentUserAdmin()) {
            return $default;
        }

        // Check if option exists in current settings with secure access
        if (isset($this->settings[$option_name])) {
            // Validate the stored value before returning
            if (isset($this->validation_rules[$option_name])) {
                $validation_result = $this->validate_single_setting(
                    $option_name,
                    $this->settings[$option_name],
                    $this->validation_rules[$option_name]
                );

                if ($validation_result !== true) {
                    $this->log_warning('Invalid stored value for option: ' . $option_name, [
                        'value' => $this->mask_sensitive_data($option_name, $this->settings[$option_name]),
                        'error' => $validation_result
                    ]);
                    return $default !== null ? $default : ($this->default_settings[$option_name] ?? null);
                }
            }

            return $this->settings[$option_name];
        }

        // Try to get from database as fallback
        try {
            $fallback_value = $this->get_option_from_database($option_name);
            if ($fallback_value !== null) {
                return $fallback_value;
            }
        } catch (\Exception $e) {
            $this->log_error('Failed to get option from database: ' . $e->getMessage());
        }

        // Final fallback: schema-declared default (module keys), then core defaults.
        $schema_default = $this->get_schema_default( $option_name );
        if ( $schema_default !== null ) {
            return $schema_default;
        }

        return $default !== null ? $default : ($this->default_settings[$option_name] ?? null);
    }

    /**
     * Get option directly from database.
     *
     * Lookup order:
     *   1. Consolidated plugin blob (ultraguard_pro_settings)
     *   2. Dynamically-registered module blobs — populated by each module's
     *      constructor via register_module_prefix().  Settings has zero
     *      hardcoded knowledge of which modules exist.
     *   3. Individual prefixed WP option (ultraguard_{key}) — firewall / htaccess
     *   4. Direct WP option ({key}) — final fallback
     */
    private function get_option_from_database( $option_name ) {
        // 1. Consolidated plugin blob.
        $settings = $this->should_use_network_settings()
            ? get_site_option( self::OPTION_NAME, [] )
            : $this->get_wp_option( self::OPTION_NAME, [], false );

        if ( isset( $settings[ $option_name ] ) ) {
            return $settings[ $option_name ];
        }

        // 2. Module-owned settings blobs (dynamic registry — no hardcoded list).
        foreach ( $this->module_registry as $prefix => $storage_key ) {
            if ( strncmp( $option_name, $prefix, strlen( $prefix ) ) === 0 ) {
                $blob = get_option( 'ultraguard_' . $storage_key . '_settings', null );
                if ( is_array( $blob ) && array_key_exists( $option_name, $blob ) ) {
                    return $blob[ $option_name ];
                }
                break; // Matched prefix — no need to keep iterating
            }
        }

        // 3. Individual prefixed WP option (firewall, htaccess, etc.)
        $prefixed_value = get_option( 'ultraguard_' . $option_name, null );
        if ( $prefixed_value !== null ) {
            return $prefixed_value;
        }

        // 4. Direct WP option — final fallback.
        return get_option( $option_name, null );
    }

    /**
     * Enhanced update single option with security, validation, and logging
     */
    public function update_option($option_name, $value): bool {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return false;
        }

        // Security: Validate option name
        if (!is_string($option_name) || empty($option_name)) {
            return false;
        }

        // NOTE: Nonce verification is intentionally NOT done here.
        // This is a data-layer method; nonce checks must be performed by the
        // module's own AJAX handler before it calls update_option().
        // Checking a fixed nonce action here would break every module that
        // correctly verifies its own nonce before delegating to this method.

        try {
            $old_value = $this->get_option($option_name);

            // Validate the new value
            if (isset($this->validation_rules[$option_name])) {
                $validation_result = $this->validate_single_setting($option_name, $value, $this->validation_rules[$option_name]);
                if ($validation_result !== true) {
                    $this->log_error('Setting validation failed: ' . $validation_result, [
                        'option' => $option_name,
                        'value' => $this->mask_sensitive_data($option_name, $value)
                    ]);
                    return false;
                }
            }

            $temp_settings = [$option_name => $value];
            $sanitized = $this->sanitize_settings($temp_settings);

            if (isset($sanitized[$option_name])) {
                $this->settings[$option_name] = $sanitized[$option_name];

                // Update tracking information
                $this->settings['_last_updated'] = current_time('mysql');
                $this->settings['_updated_by'] = get_current_user_id();

                // Validate settings combinations before saving
                $this->settings = $this->validate_setting_combinations($this->settings);

                $result = $this->save_settings_to_database();

                if ($result) {
                    $this->clear_cache();

                    // Log the setting change
                    $this->log_info('Setting updated successfully', [
                        'option' => $option_name,
                        'old_value' => $this->mask_sensitive_data($option_name, $old_value),
                        'new_value' => $this->mask_sensitive_data($option_name, $sanitized[$option_name]),
                        'updated_by' => get_current_user_id(),
                        'blog_id' => get_current_blog_id()
                    ]);

                    // Trigger action for other components
                    do_action('ultraguard_pro_setting_updated', $option_name, $sanitized[$option_name], $old_value);
                }

                return $result;
            }

            return false;

        } catch (\Exception $e) {
            $this->log_error('Failed to update option: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Enhanced update multiple options
     */
    public function update_options($options): bool {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return false;
        }

        if (!is_array($options)) {
            return false;
        }

        try {
            // Validate each option before sanitization
            foreach ($options as $key => $value) {
                if (isset($this->validation_rules[$key])) {
                    $validation_result = $this->validate_single_setting($key, $value, $this->validation_rules[$key]);
                    if ($validation_result !== true) {
                        $this->log_error('Bulk update validation failed for ' . $key . ': ' . $validation_result);
                        return false;
                    }
                }
            }

            $sanitized_options = $this->sanitize_settings($options);
            $this->settings = wp_parse_args($sanitized_options, $this->settings);

            // Update tracking information
            $this->settings['_last_updated'] = current_time('mysql');
            $this->settings['_updated_by'] = get_current_user_id();

            // Validate settings combinations before saving
            $this->settings = $this->validate_setting_combinations($this->settings);

            $result = $this->save_settings_to_database();

            if ($result) {
                $this->clear_cache();

                // Log the settings update
                $this->log_info('Multiple settings updated', [
                    'options_updated' => array_keys($sanitized_options),
                    'count' => count($sanitized_options),
                    'updated_by' => get_current_user_id(),
                    'blog_id' => get_current_blog_id()
                ]);

                // Trigger action for other components
                do_action('ultraguard_pro_settings_bulk_updated', $sanitized_options);
            }

            return $result;

        } catch (\Exception $e) {
            $this->log_error('Failed to update multiple options: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Save settings to database with multisite support
     */
    private function save_settings_to_database(): bool {
        if ($this->should_use_network_settings()) {
            return update_site_option(self::OPTION_NAME, $this->settings);
        } else {
            return $this->update_wp_option(self::OPTION_NAME, $this->settings);
        }
    }

    /**
     * Check if network settings should be used
     */
    private function should_use_network_settings(): bool {
        return is_multisite() && $this->get_option('network_wide_protection', false);
    }

    /**
     * Enhanced sanitize settings using SanitizationEngine for robust type handling
     */
    public function sanitize_settings($input): array {
        if (!is_array($input)) {
            return [];
        }

        $sanitized = [];

        foreach ($input as $key => $value) {
            if (!is_string($key) || $key === '') {
                continue;
            }

            if (array_key_exists($key, $this->default_settings)) {
                // Core setting — sanitize using the inferred type for this key.
                $default_value        = $this->default_settings[$key];
                $sanitization_type    = $this->determine_sanitization_type($key, $default_value);
                $sanitized[$key]      = $this->apply_sanitization($key, $value, $sanitization_type);
            } else {
                // Module-owned setting — look it up in the schema registry first
                // so we can apply the declared type.  If no schema is registered,
                // fall back to basic sanitization (the module has already done its
                // own sanitize_fields() before calling save_module_settings()).
                $schema_def = $this->get_schema_def( $key );

                if ( $schema_def !== null ) {
                    $type             = $schema_def['type']    ?? 'text';
                    $def_default      = $schema_def['default'] ?? null;
                    $sanitized[$key]  = $this->sanitize_by_type( $key, $value, $type, $def_default, $schema_def );
                } else {
                    // No schema — basic passthrough sanitization.
                    if ( is_array( $value ) ) {
                        $sanitized[$key] = array_map( 'sanitize_text_field', $value );
                    } elseif ( is_bool( $value ) ) {
                        $sanitized[$key] = $value;
                    } elseif ( is_int( $value ) || is_float( $value ) ) {
                        $sanitized[$key] = $value;
                    } else {
                        $sanitized[$key] = sanitize_text_field( (string) $value );
                    }
                }
            }

        }

        // Validate specific combinations and dependencies
        $sanitized = $this->validate_setting_combinations($sanitized);

        return $sanitized;
    }

    /**
     * Determine the appropriate sanitization type for a setting
     */
    private function determine_sanitization_type(string $key, $default_value): string {

        // Check key name patterns first
            if (strpos($key, 'email') !== false) {
            if (strpos($key, '_notifications') !== false ||
                strpos($key, '_enabled') !== false ||
                strpos($key, 'is_') !== false ||
                strpos($key, 'enable_') === 0) {
                return 'bool';
            }
            return 'email';
        }


        if (strpos($key, 'url') !== false) {
            return 'url';
        }

        if (strpos($key, 'ip') !== false) {
            return 'ip_address';
        }

        if (strpos($key, 'token') !== false || strpos($key, 'secret') !== false ||
            strpos($key, 'password') !== false || strpos($key, 'key') !== false) {
            return 'key';
        }

        if (strpos($key, 'rules') !== false || strpos($key, 'content') !== false) {
            return 'textarea';
        }

        // Determine by default value type
        if (is_bool($default_value)) {
            return 'bool';
        }

        if (is_int($default_value)) {
            return 'int';
        }

        if (is_float($default_value)) {
            return 'float';
        }

        if (is_array($default_value)) {
            return 'array';
        }

        if (is_string($default_value)) {
            // Check for specific string patterns
            if (in_array($key, ['firewall_mode', 'scan_frequency', 'scan_depth', 'notification_threshold',
                               'cleanup_schedule', 'integrity_check_frequency', 'subsite_settings_control'])) {
                return 'text'; // Will be validated separately
            }

            if (in_array($key, ['admin_email', 'emergency_contact'])) {
                return 'email';
            }

            if ($key === 'slack_webhook_url') {
                return 'url';
            }

            if (in_array($key, ['custom_htaccess_rules', 'custom_firewall_rules'])) {
                return 'textarea';
            }

            if (in_array($key, ['telegram_bot_token', 'telegram_chat_id'])) {
                return 'key';
            }

            return 'text';
        }

        // Default fallback
        return 'text';
    }

    /**
     * Apply sanitization using SanitizationEngine with custom rules
     */
    private function apply_sanitization(string $key, $value, string $type) {
        // Handle null values
        if (is_null($value)) {
            return $this->default_settings[$key] ?? null;
        }

        // Special handling for certain types
        switch ($type) {
            case 'email':
                if (empty($value)) {
                    return $this->default_settings[$key] ?? '';
                }
                $sanitized = $this->sanitization_engine->quick_sanitize($value, 'email');
                return is_email($sanitized) ? $sanitized : ($this->default_settings[$key] ?? '');

            case 'url':
                if (empty($value)) {
                    return $this->default_settings[$key] ?? '';
                }
                $sanitized = $this->sanitization_engine->quick_sanitize($value, 'url');
                return filter_var($sanitized, FILTER_VALIDATE_URL) ? $sanitized : ($this->default_settings[$key] ?? '');

            case 'int':
            case 'float':
                $sanitized = $this->sanitization_engine->quick_sanitize($value, $type);
                // Apply range validation for specific settings
                return $this->apply_numeric_validation($key, $sanitized);

            case 'bool':
                // First, try to use SanitizationEngine
                $sanitized = $this->sanitization_engine->quick_sanitize($value, 'bool');

                // If SanitizationEngine returned a boolean, use it
                if (is_bool($sanitized)) {
                    return $sanitized;
                }

                // Handle string representations
                if (is_string($sanitized)) {
                    $sanitized = strtolower(trim($sanitized));
                    if ($sanitized === '0' || $sanitized === 'false' || $sanitized === 'no' || $sanitized === 'off' || $sanitized === '') {
                        return false;
                    }
                    if ($sanitized === '1' || $sanitized === 'true' || $sanitized === 'yes' || $sanitized === 'on') {
                        return true;
                    }
                }

                // Handle numeric values
                if (is_numeric($sanitized)) {
                    return (bool) floatval($sanitized);
                }

                // Default: convert to boolean
                return (bool) $sanitized;

            case 'array':
                return $this->sanitize_array_setting($key, $value);

            case 'textarea':
                return $this->sanitization_engine->quick_sanitize($value, 'textarea');

            case 'ip_address':
                if (empty($value)) {
                    return $this->default_settings[$key] ?? '';
                }
                // Handle both single IP and comma-separated lists
                if (is_string($value) && strpos($value, ',') !== false) {
                    $ips = array_map('trim', explode(',', $value));
                    $valid_ips = [];
                    foreach ($ips as $ip) {
                        if ($this->validate_ip($ip) || $this->is_valid_ip_range($ip)) {
                            $valid_ips[] = $ip;
                        }
                    }
                    return implode(', ', $valid_ips);
                }
                $sanitized = $this->sanitization_engine->quick_sanitize($value, 'text');
                return ($this->validate_ip($sanitized) || $this->is_valid_ip_range($sanitized)) ? $sanitized : '';

            case 'key':
                if (empty($value)) {
                    return $this->default_settings[$key] ?? '';
                }
                return $this->sanitization_engine->quick_sanitize($value, 'key');

            case 'text':
            default:
                // Special validation for specific text fields
                if (in_array($key, ['firewall_mode'])) {
                    $allowed_modes = ['learning', 'active', 'disabled'];
                    $value = is_string($value) ? strtolower(trim($value)) : '';
                    return in_array($value, $allowed_modes) ? $value : 'learning';
                }

                if (in_array($key, ['scan_frequency', 'integrity_check_frequency', 'cleanup_schedule'])) {
                    $allowed_frequencies = ['hourly', 'daily', 'weekly', 'monthly'];
                    $value = is_string($value) ? strtolower(trim($value)) : '';
                    return in_array($value, $allowed_frequencies) ? $value : 'daily';
                }

                if ($key === 'scan_depth') {
                    $allowed_depths = ['quick', 'standard', 'deep'];
                    $value = is_string($value) ? strtolower(trim($value)) : '';
                    return in_array($value, $allowed_depths) ? $value : 'standard';
                }

                if ($key === 'notification_threshold') {
                    $allowed_thresholds = ['low', 'medium', 'high', 'critical'];
                    $value = is_string($value) ? strtolower(trim($value)) : '';
                    return in_array($value, $allowed_thresholds) ? $value : 'medium';
                }

                if ($key === 'subsite_settings_control') {
                    $allowed_controls = ['none', 'limited', 'full'];
                    $value = is_string($value) ? strtolower(trim($value)) : '';
                    return in_array($value, $allowed_controls) ? $value : 'limited';
                }

                // Default text sanitization
                return $this->sanitization_engine->quick_sanitize($value, 'text');
        }
    }
    /**
     * Apply numeric validation with ranges
     */
    private function apply_numeric_validation(string $key, $value) {
        // Define ranges for specific settings
        $ranges = [
            'log_retention_days' => [1, 365],
            'rate_limit_requests' => [1, 10000],
            'rate_limit_period' => [60, 86400],
            'max_login_attempts' => [1, 100],
            'lockout_duration' => [60, 86400],
            'captcha_after_attempts' => [1, 100],
            'max_file_size_scan' => [1, 100],
            'memory_limit' => [64, 1024],
            'max_execution_time' => [30, 600],
            'inactive_logout' => [300, 86400]
        ];

        if (isset($ranges[$key])) {
            $min = $ranges[$key][0];
            $max = $ranges[$key][1];
            return max($min, min($max, $value));
        }

        return $value;
    }

    /**
     * Enhanced sanitize array setting with flexible input handling
     * Uses SanitizationEngine for better type handling
     */
    private function sanitize_array_setting($key, $value): array {
        // Convert various input formats to array
        $array_value = $this->normalize_to_array($value);

        $sanitized = [];

        foreach ($array_value as $item) {
            // Skip empty items
            if ($item === '' || $item === null) {
                continue;
            }

            // Use SanitizationEngine based on array content type
            switch ($key) {
                case 'blocked_countries':
                    // Validate country codes (2 letters)
                    $clean_item = $this->sanitization_engine->quick_sanitize($item, 'alpha');
                    $clean_item = strtoupper($clean_item);
                    if (strlen($clean_item) === 2 && ctype_alpha($clean_item)) {
                        $sanitized[] = $clean_item;
                    }
                    break;

                case 'whitelist_ips':
                case 'blacklist_ips':
                    // Validate IP addresses and ranges
                    $clean_item = $this->sanitization_engine->quick_sanitize($item, 'text');
                    if ($this->validate_ip($clean_item) || $this->is_valid_ip_range($clean_item)) {
                        $sanitized[] = $clean_item;
                    }
                    break;

                case 'allowed_file_types':
                    // Validate file extensions
                    $clean_item = $this->sanitization_engine->quick_sanitize($item, 'alphanumeric');
                    $clean_item = strtolower(ltrim($clean_item, '.'));
                    if (preg_match('/^[a-z0-9]{1,10}$/', $clean_item)) {
                        $sanitized[] = $clean_item;
                    }
                    break;

                case 'exclude_directories':
                    // Enhanced validation for directories
                    $clean_item = $this->sanitization_engine->quick_sanitize($item, 'text');
                    if ($this->validate_file_path($clean_item, false) &&
                        strpos($clean_item, '..') === false &&
                        strpos($clean_item, chr(0)) === false) {
                        $sanitized[] = $clean_item;
                    }
                    break;

                default:
                    // Generic array sanitization
                    $clean_item = $this->sanitization_engine->quick_sanitize($item, 'text');
                    if (!empty($clean_item)) {
                        $sanitized[] = $clean_item;
                    }
                    break;
            }
        }

        // Remove duplicates and reindex
        $sanitized = array_values(array_unique($sanitized));

        return $sanitized;
    }

    /**
     * Normalize various input formats to array
     */
    private function normalize_to_array($value): array {
        if (is_array($value)) {
            return $value;
        }

        if (is_string($value)) {
            $value = trim($value);

            if (empty($value)) {
                return [];
            }

            // Handle JSON string
            if ($this->validate_json($value)) {
                $decoded = json_decode($value, true);
                if (is_array($decoded)) {
                    return $decoded;
                }
            }

            // Handle comma-separated values
            if (strpos($value, ',') !== false) {
                return array_map('trim', explode(',', $value));
            }

            // Handle newline-separated values
            if (strpos($value, "\n") !== false) {
                return array_map('trim', explode("\n", $value));
            }

            // Handle space-separated values
            if (strpos($value, ' ') !== false) {
                return array_map('trim', explode(' ', $value));
            }

            // Single value
            return [$value];
        }

        // Handle other types
        if (is_numeric($value) || is_bool($value)) {
            return [strval($value)];
        }

        return [];
    }

    /**
     * Enhanced validate setting combinations and dependencies
     */
    private function validate_setting_combinations($settings): array {
        // Use wp_parse_args to ensure all settings have defaults
        $settings = wp_parse_args($settings, $this->default_settings);

        // Handle firewall dependencies
        if (isset($settings['firewall_mode']) && $settings['firewall_mode'] === 'disabled') {
            $settings['firewall_enabled'] = false;
        }

        if (isset($settings['firewall_enabled']) && !$settings['firewall_enabled']) {
            $settings['firewall_mode'] = 'disabled';
            $settings['rate_limiting_enabled'] = false;
            $settings['block_tor_users'] = false;
            $settings['block_proxy_users'] = false;
            $settings['enable_geo_blocking'] = false;
        }

        // Disable rate limiting specific settings when rate limiting is disabled
        if (isset($settings['rate_limiting_enabled']) && !$settings['rate_limiting_enabled']) {
            $settings['rate_limit_requests'] = $this->default_settings['rate_limit_requests'];
            $settings['rate_limit_period'] = $this->default_settings['rate_limit_period'];
        }

        // Login protection dependencies
        if (isset($settings['login_limiter_enabled']) && !$settings['login_limiter_enabled']) {
            $settings['max_login_attempts'] = $this->default_settings['max_login_attempts'];
            $settings['lockout_duration'] = $this->default_settings['lockout_duration'];
            $settings['captcha_after_attempts'] = $this->default_settings['captcha_after_attempts'];
            $settings['notify_lockouts'] = false;
        }

        // Ensure captcha after attempts is less than or equal to max attempts
        if (isset($settings['captcha_after_attempts']) && isset($settings['max_login_attempts'])) {
            if ($settings['captcha_after_attempts'] > $settings['max_login_attempts']) {
                $settings['captcha_after_attempts'] = $settings['max_login_attempts'];
            }
        }

        // Antivirus & FileChecker dependency rules are handled by their own modules.

        // Notification dependencies
        if (isset($settings['is_email_notifications']) && !$settings['is_email_notifications']) {
            $settings['critical_threat_notification'] = false;
            $settings['is_daily_summary_email'] = false;
            $settings['is_weekly_report_email'] = false;
        }

        // Telegram notification dependencies
        if (isset($settings['telegram_notifications']) && $settings['telegram_notifications']) {
            if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) {
                $settings['telegram_notifications'] = false;
            }
        }

        // Slack notification dependencies
        if (isset($settings['slack_notifications']) && $settings['slack_notifications']) {
            if (empty($settings['slack_webhook_url'])) {
                $settings['slack_notifications'] = false;
            }
        }

        return $settings;
    }

    /**
     * Enhanced export settings with security
     */
    public function export_settings(): string {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return wp_json_encode(['error' => 'Insufficient permissions']);
        }

        // Security: Nonce verification
        if (wp_doing_ajax() && !$this->verify_nonce('ultraguard_admin_nonce', 'nonce')) {
            return wp_json_encode(['error' => 'Security check failed']);
        }

        try {
            $export_data = $this->settings;

            // Remove sensitive data from export
            $sensitive_keys = [
                'telegram_bot_token',
                'slack_webhook_url',
                'telegram_chat_id',
                'emergency_contact',
                '_last_updated',
                '_updated_by'
            ];

            foreach ($sensitive_keys as $key) {
                if (isset($export_data[$key])) {
                    unset($export_data[$key]);
                }
            }

            // Validate export data
            $validation_result = $this->validate_settings($export_data);
            if ($validation_result !== true) {
                return wp_json_encode(['error' => 'Invalid settings data: ' . implode(', ', $validation_result)]);
            }

            // Add export metadata
            $export_data['_export_meta'] = [
                'exported_at' => current_time('mysql'),
                'exported_by' => get_current_user_id(),
                'site_url' => get_site_url(),
                'blog_id' => get_current_blog_id(),
                'plugin_version' => defined('ULTRAGUARD_PRO_VERSION') ? ULTRAGUARD_PRO_VERSION : 'Unknown'
            ];

            // Log the export
            $this->log_info('Settings exported successfully', [
                'exported_by' => get_current_user_id(),
                'blog_id' => get_current_blog_id()
            ]);

            return wp_json_encode($export_data, JSON_PRETTY_PRINT);

        } catch (\Exception $e) {
            $this->log_error('Settings export failed: ' . $e->getMessage());
            return wp_json_encode(['error' => 'Export failed: ' . $e->getMessage()]);
        }
    }

    /**
     * Enhanced import settings with transaction support and validation
     */
    public function import_settings($json_data, $nonce = '') {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return new WP_Error('insufficient_permissions', __('Insufficient permissions', 'ultraguard-security-suite'));
        }

        // Security: Nonce verification
        if (empty($nonce) || !$this->verify_nonce_util($nonce, 'ultraguard_pro_import_settings')) {
            return new WP_Error('invalid_nonce', __('Security check failed', 'ultraguard-security-suite'));
        }

        // Security: Validate JSON data
        if (!is_string($json_data) || empty($json_data)) {
            return new WP_Error('invalid_data', __('Invalid data provided', 'ultraguard-security-suite'));
        }

        // Security: Limit JSON size to prevent DoS
        if (strlen($json_data) > 100000) {
            return new WP_Error('data_too_large', __('Import data too large', 'ultraguard-security-suite'));
        }

        try {
            // Validate JSON
            if (!$this->validate_json($json_data)) {
                return new WP_Error('invalid_json', __('Invalid JSON format', 'ultraguard-security-suite'));
            }

            $import_data = json_decode($json_data, true);

            if (!is_array($import_data)) {
                return new WP_Error('invalid_format', __('Invalid settings format', 'ultraguard-security-suite'));
            }

            // Validate import data
            $validation_result = $this->validate_settings($import_data);
            if ($validation_result !== true) {
                return new WP_Error('validation_failed', __('Import data validation failed: ', 'ultraguard-security-suite') . implode(', ', $validation_result));
            }

            // Remove export metadata if present
            if (isset($import_data['_export_meta'])) {
                unset($import_data['_export_meta']);
            }

            // Preserve sensitive data and tracking information with secure defaults
            $preserved_data = [
                'telegram_bot_token' => $this->settings['telegram_bot_token'] ?? '',
                'slack_webhook_url' => $this->settings['slack_webhook_url'] ?? '',
                'telegram_chat_id' => $this->settings['telegram_chat_id'] ?? '',
                'emergency_contact' => $this->settings['emergency_contact'] ?? '',
                'admin_email' => $this->settings['admin_email'] ?? $this->get_wp_option('admin_email', ''),
                '_version' => $this->settings['_version'] ?? self::SETTINGS_VERSION,
                '_last_updated' => current_time('mysql'),
                '_updated_by' => get_current_user_id()
            ];

            // Sanitize imported data
            $sanitized_import = $this->sanitize_settings($import_data);

            // Merge with preserved data using wp_parse_args for safety
            $this->settings = wp_parse_args($preserved_data, wp_parse_args($sanitized_import, $this->default_settings));

            // Save to database
            $result = $this->save_settings_to_database();

            if ($result) {
                $this->clear_cache();

                // Log the import
                $this->log_info('Settings imported successfully', [
                    'imported_by' => get_current_user_id(),
                    'blog_id' => get_current_blog_id(),
                    'settings_imported' => array_keys($sanitized_import)
                ]);

                // Trigger action for other components
                do_action('ultraguard_pro_settings_imported', $sanitized_import);

                return true;
            } else {
                return new WP_Error('save_failed', __('Failed to save imported settings', 'ultraguard-security-suite'));
            }

        } catch (\Exception $e) {
            $this->log_error('Settings import failed: ' . $e->getMessage());
            /* translators: %s: import failure message. */
            return new WP_Error('import_failed', sprintf( __('Import failed: %s', 'ultraguard-security-suite'), $e->getMessage() ));
        }
    }

    /**
     * Enhanced reset settings to defaults with security and logging
     */
    public function reset_settings($nonce = ''): bool {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return false;
        }

        // Security: Nonce verification
        if (empty($nonce) || !$this->verify_nonce_util($nonce, 'ultraguard_pro_reset_settings')) {
            return false;
        }

        try {
            // Backup current settings for logging
            $old_settings = $this->settings;

            // Reset to defaults
            $this->settings = $this->default_settings;

            // Preserve admin email and tracking with secure defaults
            $this->settings['admin_email'] = $this->get_wp_option('admin_email', '');
            $this->settings['_last_updated'] = current_time('mysql');
            $this->settings['_updated_by'] = get_current_user_id();

            $result = $this->save_settings_to_database();

            if ($result) {
                $this->clear_cache();

                // Log the reset
                $this->log_warning('Settings reset to defaults', [
                    'reset_by' => get_current_user_id(),
                    'blog_id' => get_current_blog_id(),
                    'old_settings_count' => is_array($old_settings) ? count($old_settings) : 0
                ]);

                // Trigger action for other components
                do_action('ultraguard_pro_settings_reset', $old_settings);
            }

            return $result;

        } catch (\Exception $e) {
            $this->log_error('Settings reset failed: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Enhanced get all settings with security filtering
     */
    public function get_all_settings(): array {
        // Security: Capability check
        if (!$this->isCurrentUserAdmin()) {
            return [];
        }

        $all_settings = $this->settings;

        // Validate all settings before returning
        foreach ($all_settings as $key => $value) {
            if (isset($this->validation_rules[$key])) {
                $validation_result = $this->validate_single_setting($key, $value, $this->validation_rules[$key]);
                if ($validation_result !== true) {
                    // Log validation errors but don't fail
                    $this->log_warning('Invalid setting detected in get_all_settings: ' . $key, [
                        'error' => $validation_result
                    ]);
                }
            }
        }

        // Mask sensitive data for non-admin users
        if (!\UltraguardPro\ultraguard_current_user_can_manage()) {
            $sensitive_keys = [
                'telegram_bot_token',
                'slack_webhook_url',
                'telegram_chat_id',
                'emergency_contact'
            ];

            foreach ($sensitive_keys as $key) {
                if (isset($all_settings[$key])) {
                    $all_settings[$key] = '***';
                }
            }
        }

        return $all_settings;
    }

    /**
     * Enhanced validate settings with comprehensive checks using ValidationEngine
     */
    public function validate_settings($settings = null) {
        $settings_to_validate = $settings ?: $this->settings;

        // Ensure settings is an array
        if (!is_array($settings_to_validate)) {
            return [__('Invalid settings format', 'ultraguard-security-suite')];
        }

        $errors = [];

        // Validate each setting using ValidationEngine
        foreach ($settings_to_validate as $key => $value) {
            if (isset($this->validation_rules[$key])) {
                $validation_result = $this->validate_single_setting($key, $value, $this->validation_rules[$key]);
                if ($validation_result !== true) {
                    /* translators: %1$s: string, %2$s: string */
                    $errors[] = sprintf(__('%1$s: %2$s', 'ultraguard-security-suite'), $key, $validation_result);
                }
            }
        }

        // Validate specific combinations
        $combination_errors = $this->validate_setting_combinations_errors($settings_to_validate);
        if (!empty($combination_errors)) {
            $errors = array_merge($errors, $combination_errors);
        }

        return empty($errors) ? true : $errors;
    }

    /**
     * Validate setting combinations for errors
     */
    private function validate_setting_combinations_errors($settings): array {
        $errors = [];

        // Ensure captcha after attempts is less than or equal to max attempts
        if (isset($settings['captcha_after_attempts'], $settings['max_login_attempts'])) {
            if ($settings['captcha_after_attempts'] > $settings['max_login_attempts']) {
                $errors[] = __('CAPTCHA after attempts cannot be greater than maximum login attempts', 'ultraguard-security-suite');
            }
        }

        // Validate telegram notification dependencies
        if (isset($settings['telegram_notifications']) && $settings['telegram_notifications']) {
            if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) {
                $errors[] = __('Telegram notifications require both bot token and chat ID', 'ultraguard-security-suite');
            }
        }

        // Validate slack notification dependencies
        if (isset($settings['slack_notifications']) && $settings['slack_notifications']) {
            if (empty($settings['slack_webhook_url'])) {
                $errors[] = __('Slack notifications require webhook URL', 'ultraguard-security-suite');
            }
        }

        return $errors;
    }

    /**
     * Enhanced clear cache with multisite support
     */
    public function clear_cache(): void {
        // Clear controller cache
        $this->delete_cache($this->cache_key);

        // Clear WordPress object cache
        wp_cache_delete('ultraguard_pro_settings_cache_' . get_current_blog_id(), 'options');

        // Clear multisite cache if applicable
        if (is_multisite()) {
            wp_cache_delete('ultraguard_pro_network_settings', 'options');
        }

        // Clear SanitizationEngine cache
        $this->sanitization_engine->clear_cache();

        // Clear ValidationEngine cache
        $this->validation_engine->clear_cache();
    }

    /**
     * Enhanced schedule cleanup
     */
    private function schedule_cleanup(): void {
        if (!wp_next_scheduled('ultraguard_pro_settings_cleanup')) {
            wp_schedule_event(time(), 'daily', 'ultraguard_pro_settings_cleanup');
        }

        add_action('ultraguard_pro_settings_cleanup', [$this, 'perform_cleanup']);
    }

    /**
     * Enhanced perform cleanup
     */
    public function perform_cleanup(): void {
        // Clear expired caches
        $this->clear_cache();

        // Validate settings structure
        $this->validate_settings_structure();

        // Log cleanup
        $this->log_info('Settings cleanup performed', [
            'blog_id' => get_current_blog_id(),
            'timestamp' => current_time('mysql')
        ]);
    }

    /**
     * Mask sensitive data for logging
     */
    private function mask_sensitive_data($key, $value) {
        $sensitive_keys = [
            'telegram_bot_token',
            'slack_webhook_url',
            'telegram_chat_id',
            'emergency_contact'
        ];

        if (in_array($key, $sensitive_keys) && !empty($value)) {
            $value_str = strval($value);
            if (strlen($value_str) > 4) {
                return '***' . substr($value_str, -4);
            }
            return '***';
        }

        return $value;
    }

    /**
     * Sanitize network settings for multisite
     */
    public function sanitize_network_settings($input): array {
        if (!is_multisite() || !current_user_can('manage_network_options')) {
            return [];
        }

        return $this->sanitize_settings($input);
    }

    /**
     * Get settings schema for validation
     */
    public function get_settings_schema(): array {
        $schema = [
            'general' => [
                'type' => 'object',
                'properties' => [
                ]
            ]
        ];
        return $schema;
    }

    /**
     * Check if a setting is enabled
     */
    public function is_enabled($setting_name): bool {
        return (bool) $this->get_option($setting_name, false);
    }

    /**
     * Get settings version
     */
    public function get_version(): string {
        return $this->get_option('_version', self::SETTINGS_VERSION);
    }

    /**
     * Get last updated timestamp
     */
    public function get_last_updated(): string {
        return $this->get_option('_last_updated', '');
    }

    /**
     * Get user who last updated settings
     */
    public function get_last_updated_by(): int {
        return (int) $this->get_option('_updated_by', 0);
    }

    /**
     * Handle settings update hook
     */
    public function handle_settings_update($old_value, $value, $option): void {
        if ($option === self::OPTION_NAME) {
            // Validate new settings
            $validation_result = $this->validate_settings($value);
            if ($validation_result !== true) {
                $this->log_error('Settings update validation failed: ' . implode(', ', $validation_result));
            }

            $this->clear_cache();
            do_action('ultraguard_pro_settings_updated', $value, $old_value);
        }
    }

    /**
     * Handle network settings update hook
     */
    public function handle_network_settings_update($option, $value, $old_value, $network_id): void {
        if ($option === self::OPTION_NAME) {
            // Validate new network settings
            $validation_result = $this->validate_settings($value);
            if ($validation_result !== true) {
                $this->log_error('Network settings update validation failed: ' . implode(', ', $validation_result));
            }

            $this->clear_cache();
            do_action('ultraguard_pro_network_settings_updated', $value, $old_value, $network_id);
        }
    }

    /**
     * Get all options (alias for get_all_settings for compatibility)
     */
    public function get_all_options(): array {
        return $this->get_all_settings();
    }

    // =========================================================================
    // MODULE SETTINGS API
    // Modules call these methods — Settings has zero knowledge of module keys.
    // =========================================================================

    /**
     * Register a module's settings schema — the single call that wires up
     * everything: key-prefix routing, per-key defaults, and per-key types.
     *
     * This replaces the need to add keys to $default_settings or $validation_rules
     * in this class.  Each module is fully self-contained.
     *
     * @param string $storage_key  Module blob identifier, e.g. 'passkeys'.
     *                             Stored as ultraguard_{storage_key}_settings.
     * @param string $prefix       Key prefix owned by this module, e.g. 'passkey_'.
     *                             Used to route get_option() reads to the right blob.
     * @param array  $schema       Map of option-key → definition array.
     *                             Each definition supports:
     *                               'type'    string  One of: bool, int, float, text,
     *                                                 email, url, key, textarea, array,
     *                                                 select.  Default: 'text'.
     *                               'default' mixed   Value returned when the key is
     *                                                 absent from storage.
     *                               'options' array   For type='select': allowed values.
     *                               'min'     int     For type='int'/'float'.
     *                               'max'     int     For type='int'/'float'.
     *
     * Example — in PasskeysModule::boot():
     *
     *   $this->plugin->settings->register_settings_schema( 'passkeys', 'passkey_', [
     *       'passkey_allow_recovery_codes' => [ 'type' => 'bool',  'default' => true  ],
     *       'passkey_required_roles'       => [ 'type' => 'array', 'default' => []    ],
     *   ] );
     */
    public function register_settings_schema(
        string $storage_key,
        string $prefix,
        array  $schema
    ): void {
        // Also register in the legacy prefix-map so get_option_from_database()
        // routing continues to work without changes.
        $this->module_registry[ $prefix ] = $storage_key;

        $this->schema_registry[ $storage_key ] = [
            'prefix' => $prefix,
            'schema' => $schema,
        ];

        // Load the module's saved blob and merge into $this->settings so that
        // get_option() returns real saved values, not just defaults.
        // This runs at module boot time (after load_settings()), so it correctly
        // overrides any default that load_settings() may have missed.
        $saved_blob = (array) get_option( 'ultraguard_' . $storage_key . '_settings', [] );

        foreach ( $schema as $key => $def ) {
            if ( array_key_exists( $key, $saved_blob ) ) {
                // Real saved value from the module blob — use it.
                $this->settings[ $key ] = $saved_blob[ $key ];
            } elseif ( ! isset( $this->settings[ $key ] ) && array_key_exists( 'default', $def ) ) {
                // No saved value yet — seed with the declared default.
                $this->settings[ $key ] = $def['default'];
            }
        }
    }

    /**
     * Register a key prefix → storage key mapping for a module.
     *
     * Kept for backwards compatibility.  Prefer register_settings_schema() for
     * new modules — it also declares types and defaults in one place.
     *
     * @param string $prefix      The option-key prefix owned by this module.
     * @param string $storage_key The wp_options key suffix for the module blob.
     */
    public function register_module_prefix( string $prefix, string $storage_key ): void {
        $this->module_registry[ $prefix ] = $storage_key;
    }

    /**
     * Persist a module's validated settings to its own wp_option blob.
     *
     * The module AJAX class is responsible for sanitising and validating $data
     * before calling this method.  Settings merges the new values on top of any
     * previously saved values so that partial saves work correctly.
     *
     * @param string $storage_key Identifies the module blob
     *                            (e.g. 'antivirus' → ultraguard_antivirus_settings).
     * @param array  $data        Sanitised key-value pairs to persist.
     * @return bool               True if the option was updated, false otherwise.
     */
    public function save_module_settings( string $storage_key, array $data ): bool {
        if ( ! $this->isCurrentUserAdmin() ) {
            return false;
        }

        $option_key = 'ultraguard_' . $storage_key . '_settings';
        $existing   = (array) get_option( $option_key, [] );
        $merged     = array_merge( $existing, $data );

        $ok = (bool) update_option( $option_key, $merged );

        if ( $ok ) {
            // Update in-memory settings so get_option() returns fresh values
            // immediately in the same request (e.g. after a save the page re-renders).
            foreach ( $merged as $key => $value ) {
                $this->settings[ $key ] = $value;
            }
            $this->clear_cache();
            do_action( 'ultraguard_pro_module_settings_saved', $storage_key, $data );
        }

        return $ok;
    }

    /**
     * Read all settings for a module from its blob.
     *
     * @param string $storage_key  Module storage key (e.g. 'antivirus').
     * @return array               Saved settings, or an empty array if none exist.
     */
    public function get_module_settings( string $storage_key ): array {
        return (array) get_option( 'ultraguard_' . $storage_key . '_settings', [] );
    }

    // =========================================================================
    // SCHEMA HELPERS
    // =========================================================================

    /**
     * Look up the schema definition for a single key across all registered modules.
     * Returns the definition array or null if the key has no registered schema.
     *
     * @param  string      $key  Option key e.g. 'passkey_allow_recovery_codes'
     * @return array|null
     */
    private function get_schema_def( string $key ): ?array {
        foreach ( $this->schema_registry as $entry ) {
            if ( isset( $entry['schema'][ $key ] ) ) {
                return $entry['schema'][ $key ];
            }
        }
        return null;
    }

    /**
     * Sanitize a single value according to an explicit type string.
     *
     * Supported types: bool, int, float, text, email, url, key, textarea, array, select.
     *
     * @param  string $key      Option key (used for range lookup).
     * @param  mixed  $value    Raw value.
     * @param  string $type     Declared type from schema.
     * @param  mixed  $default  Fallback when value is invalid/empty.
     * @param  array  $def      Full schema definition (for 'options', 'min', 'max').
     * @return mixed
     */
    private function sanitize_by_type( string $key, $value, string $type, $default, array $def = [] ) {
        switch ( $type ) {
            case 'bool':
                if ( is_bool( $value ) ) { return $value; }
                if ( in_array( $value, [ '0', 'false', 'no', 'off', '' ], true ) ) { return false; }
                if ( in_array( $value, [ '1', 'true',  'yes', 'on'     ], true ) ) { return true;  }
                return (bool) $value;

            case 'int':
                $v = absint( $value );
                if ( isset( $def['min'] ) ) { $v = max( (int) $def['min'], $v ); }
                if ( isset( $def['max'] ) ) { $v = min( (int) $def['max'], $v ); }
                return $v;

            case 'float':
                $v = (float) $value;
                if ( isset( $def['min'] ) ) { $v = max( (float) $def['min'], $v ); }
                if ( isset( $def['max'] ) ) { $v = min( (float) $def['max'], $v ); }
                return $v;

            case 'email':
                $v = sanitize_email( (string) $value );
                return is_email( $v ) ? $v : ( $default ?? '' );

            case 'url':
                $v = sanitize_url( (string) $value );
                return filter_var( $v, FILTER_VALIDATE_URL ) ? $v : ( $default ?? '' );

            case 'key':
                return sanitize_key( (string) $value );

            case 'textarea':
                return sanitize_textarea_field( (string) $value );

            case 'select':
                $allowed = $def['options'] ?? [];
                $v       = sanitize_key( (string) $value );
                return in_array( $v, $allowed, true ) ? $v : ( $default ?? ( $allowed[0] ?? '' ) );

            case 'array':
                if ( ! is_array( $value ) ) { $value = []; }
                $allowed = $def['options'] ?? null;
                $clean   = [];
                foreach ( $value as $item ) {
                    $item = sanitize_key( (string) $item );
                    if ( $item === '' ) { continue; }
                    if ( $allowed !== null && ! in_array( $item, $allowed, true ) ) { continue; }
                    $clean[] = $item;
                }
                return array_values( array_unique( $clean ) );

            case 'text':
            default:
                return sanitize_text_field( (string) $value );
        }
    }

    /**
     * Return the declared default for a key from the schema registry.
     * Returns null if the key has no registered schema or no 'default' declared.
     *
     * @param  string $key
     * @return mixed|null
     */
    public function get_schema_default( string $key ) {
        $def = $this->get_schema_def( $key );
        return ( $def !== null && array_key_exists( 'default', $def ) ) ? $def['default'] : null;
    }

        // =========================================================================
    // UTILITY METHODS
    // =========================================================================

    /**
     * Check if current user is admin
     */
    private function isCurrentUserAdmin(): bool {
        return \UltraguardPro\ultraguard_current_user_can_manage();
    }

    /**
     * Verify nonce with customizable actions
     */
    private function verify_nonce($action = 'ultraguard_pro', $nonce_field = 'ultraguard_admin_nonce'): bool {
        $nonce = $this->get_request_var($nonce_field, 'POST');

        if (empty($nonce)) {
            return false;
        }

        return wp_verify_nonce($nonce, $action);
    }

    /**
     * Verify nonce utility
     */
    private function verify_nonce_util($nonce, $action): bool {
        return wp_verify_nonce($nonce, $action);
    }

    /**
     * Validate a nonce against one or more accepted action names.
     *
     * Some settings endpoints still have legacy nonce names in older UI code,
     * so we accept both the current AJAX action and the historical alias.
     *
     * @param mixed $nonce
     * @param string[] $actions
     * @return bool
     */
    private function validate_nonce_actions($nonce, array $actions): bool {
        if (empty($nonce)) {
            return false;
        }

        foreach ($actions as $action) {
            if ($this->verify_nonce_util($nonce, $action)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Get request variable
     */
    private function get_request_var($key, $method = 'REQUEST', $default = '') {
        $value = $default;

        switch (strtoupper($method)) {
            case 'GET':
                $value = isset( $_GET[$key ] ) ? wp_unslash( $_GET[ $key ] ) : $default; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Generic helper for sanitized request reads; validation happens in callers.
                break;
            case 'POST':
                $value = isset( $_POST[ $key ] ) ? wp_unslash( $_POST[ $key ] ) : $default; // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Generic helper for sanitized request reads; validation happens in callers.
                break;
            case 'REQUEST':
                $value = isset( $_REQUEST[$key ] ) ? wp_unslash( $_REQUEST[ $key ] ) : $default; // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Generic helper for sanitized request reads; validation happens in callers.
                break;
        }

        return $this->sanitization_engine->quick_sanitize($value, 'text');
    }

    /**
     * Validate file path
     */
    private function validate_file_path($path, $check_exists = true): bool {
        // Basic path validation
        if (empty($path) || strpos($path, '..') !== false || strpos($path, chr(0)) !== false) {
            return false;
        }

        if ($check_exists) {
            return file_exists($path);
        }

        return true;
    }

    /**
     * Validate JSON using ValidationEngine
     */
    private function validate_json($json): bool {
        return $this->validation_engine->quick_validate($json, 'json');
    }

    /**
     * Validate IP address using ValidationEngine
     */
    private function validate_ip($ip): bool {
        return $this->validation_engine->quick_validate($ip, 'ip_address', ['allow_range' => false, 'version' => 'both']);
    }

    /**
     * Check if IP range is valid
     */
    private function is_valid_ip_range($ip_range): bool {
        // Simple CIDR validation
        if (strpos($ip_range, '/') !== false) {
            list($ip, $mask) = explode('/', $ip_range);
            $mask = (int) $mask;
            return $this->validate_ip($ip) && $mask >= 0 && $mask <= 32;
        }

        // IP range validation (e.g., 192.168.1.1-192.168.1.100)
        if (strpos($ip_range, '-') !== false) {
            $parts = explode('-', $ip_range);
            if (count($parts) === 2) {
                return $this->validate_ip(trim($parts[0])) && $this->validate_ip(trim($parts[1]));
            }
        }

        return false;
    }

    /**
     * Get WordPress option with caching
     */
    private function get_wp_option($key, $default = false, $use_cache = true) {
        $cache_key = 'option_' . $key;

        if ($use_cache) {
            $cached = $this->get_cache($cache_key);
            if ($cached !== false) {
                return $cached;
            }
        }

        $value = get_option($key, $default);

        if ($use_cache) {
            $this->set_cache($cache_key, $value, 3600);
        }

        return $value;
    }

    /**
     * Update WordPress option and clear cache
     */
    private function update_wp_option($key, $value): bool {
        $result = update_option($key, $value);

        if ($result) {
            $this->delete_cache('option_' . $key);
        }

        return $result;
    }

    /**
     * Set cache
     */
    private function set_cache($key, $data, $ttl = 3600): bool {
        $cache_key = 'ultraguard_settings_' . sanitize_key($key);
        return CacheManager::get_instance()->set_db($cache_key, $data);
    }

    /**
     * Get cache
     */
    private function get_cache($key) {
        $cache_key = 'ultraguard_settings_' . sanitize_key($key);
        return CacheManager::get_instance()->get_db($cache_key);
    }

    /**
     * Delete cache
     */
    private function delete_cache($key): bool {
        $cache_key = 'ultraguard_settings_' . sanitize_key($key);
        return delete_transient($cache_key);
    }

    /**
     * Log error message
     */
    private function log_error($message, $context = []): void {
        // If logger is available in plugin, use it
        if ($this->plugin && isset($this->plugin->logger)) {
            try {
                $this->plugin->logger->log('error', $message, $context);
            } catch (\Exception $e) {
                // Fallback to error_log for critical errors only
                if (defined('WP_DEBUG') && WP_DEBUG) {
                    \UltraguardPro\core\Logger::error( 'Ultraguard Pro Settings Error: ' . $message );
                }
            }
        } elseif (defined('WP_DEBUG') && WP_DEBUG) {
            \UltraguardPro\core\Logger::error( 'Ultraguard Pro Settings Error: ' . $message );
        }
    }

    /**
     * Log info message
     */
    private function log_info($message, $context = []): void {
        // If logger is available in plugin, use it
        if ($this->plugin && isset($this->plugin->logger)) {
            try {
                $this->plugin->logger->log('info', $message, $context);
            } catch (\Exception $e) {
                // Silent failure for info logs in production
            }
        }
    }

    /**
     * Log warning message
     */
    private function log_warning($message, $context = []): void {
        // If logger is available in plugin, use it
        if ($this->plugin && isset($this->plugin->logger)) {
            try {
                $this->plugin->logger->log('warning', $message, $context);
            } catch (\Exception $e) {
                // Silent failure for warning logs in production
            }
        }
    }

    /**
     * Handle AJAX requests for settings operations
     */
    public function handle_ajax_settings(): void {
        $response = AjaxResponseBuilder::make();

        // Get the AJAX action early so public read-only routes can bypass the
        // admin capability gate and fall through to their own allowlist checks.
        // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Action is read first so the public allowlisted route can decide whether nonce validation is required.
        $action = $this->sanitization_engine->quick_sanitize(wp_unslash( $_POST['action'] ?? '' ), 'text');

        // Check capabilities first
        if ($action !== 'ultraguard_get_setting' && !$this->isCurrentUserAdmin()) {
            $response->permissionError(__('Insufficient permissions to manage settings.', 'ultraguard-security-suite'))->send();
            return;
        }

        // Route the action to appropriate handler
        switch ($action) {
            case 'ultraguard_save_consolidated_settings':
                $result = $this->handle_save_consolidated_settings();
                break;

            case 'ultraguard_export_all_settings':
                $result = $this->handle_export_all_settings();
                break;

            case 'ultraguard_reset_all_settings':
                $result = $this->handle_reset_all_settings();
                break;

            case 'ultraguard_test_all_configurations':
                $result = $this->handle_test_configurations();
                break;

            case 'ultraguard_save_module_settings':
                $result = $this->handle_save_module_settings();
                break;

            case 'ultraguard_import_settings':
                $result = $this->handle_import_settings();
                break;

            case 'ultraguard_get_setting':
                $result = $this->handle_get_setting();
                break;

            case 'ultraguard_update_setting':
                $result = $this->handle_update_setting();
                break;

            case 'ultraguard_bulk_update_settings':
                $result = $this->handle_bulk_update_settings();
                break;

            case 'ultraguard_validate_settings':
                $result = $this->handle_validate_settings();
                break;

            default:
                $response
                    ->error(__('Invalid action requested.', 'ultraguard-security-suite'), 'invalid_action')
                    ->addNotification(__('The requested action is not recognized.', 'ultraguard-security-suite'), 'error')
                    ->send();
                return;
        }

        // Handle the result if it's an array (from existing handlers)
        if (is_array($result) && isset($result['success'])) {
            $builder = AjaxResponseBuilder::make();
            $status_code = 200;

            if ($result['success']) {
                $builder->success($result['message'] ?? __('Operation completed successfully', 'ultraguard-security-suite'));

                // Add data if present
                if (!empty($result['data'])) {
                    foreach ($result['data'] as $key => $value) {
                        $builder->addData($key, $value);
                    }
                }

                // Add actions if present
                if (!empty($result['actions'])) {
                    foreach ($result['actions'] as $action) {
                        $this->add_builder_action($builder, $action);
                    }
                }

                // Add success notification if not already present
                if (!isset($result['actions']) || !$this->has_notification($result['actions'], 'success')) {
                    $builder->addNotification($result['message'] ?? __('Success!', 'ultraguard-security-suite'), 'success', 3000);
                }
            } else {
                if (isset($result['code']) && is_numeric($result['code'])) {
                    $candidate = (int) $result['code'];
                    if ($candidate >= 100 && $candidate <= 599) {
                        $status_code = $candidate;
                    }
                }

                $builder->error(
                    $result['message'] ?? __('Operation failed', 'ultraguard-security-suite'),
                    $result['code'] ?? 'operation_failed'
                );

                // Add error notification
                $builder->addNotification(
                    $result['message'] ?? __('An error occurred', 'ultraguard-security-suite'),
                    'error',
                    5000
                );
            }

            $builder->send($status_code);
        }
    }

    /**
     * Helper to add actions to builder from array
     */
    private function add_builder_action($builder, $action): void {
        if (!isset($action['type'])) {
            return;
        }

        switch ($action['type']) {
            case 'notification':
                $builder->addNotification(
                    $action['message'] ?? '',
                    $action['status'] ?? 'info',
                    $action['duration'] ?? 3000
                );
                break;

            case 'reload':
                $builder->addReload($action['delay'] ?? 0);
                break;

            case 'redirect':
                $builder->addRedirect($action['url'] ?? '', $action['delay'] ?? 0);
                break;

            case 'update':
                $builder->addUpdate($action['selector'] ?? '', $action['content'] ?? '');
                break;

            case 'append':
                $builder->addAppend($action['selector'] ?? '', $action['content'] ?? '');
                break;

            case 'prepend':
                $builder->addPrepend($action['selector'] ?? '', $action['content'] ?? '');
                break;

            case 'replace':
                $builder->addReplace($action['selector'] ?? '', $action['content'] ?? '');
                break;

            case 'remove':
                $builder->addRemove(
                    $action['selector'] ?? '',
                    $action['animate'] ?? true,
                    $action['duration'] ?? 400
                );
                break;

            case 'empty':
                $builder->addEmpty($action['selector'] ?? '');
                break;

            case 'addClass':
                $builder->addClass($action['selector'] ?? '', $action['class'] ?? '');
                break;

            case 'removeClass':
                $builder->removeClass($action['selector'] ?? '', $action['class'] ?? '');
                break;

            case 'toggleClass':
                $builder->toggleClass($action['selector'] ?? '', $action['class'] ?? '');
                break;

            case 'show':
                $builder->showElement($action['selector'] ?? '');
                break;

            case 'hide':
                $builder->hideElement($action['selector'] ?? '');
                break;

            case 'fadeIn':
                $builder->fadeIn($action['selector'] ?? '', $action['duration'] ?? 300);
                break;

            case 'fadeOut':
                $builder->fadeOut($action['selector'] ?? '', $action['duration'] ?? 300);
                break;

            case 'slideDown':
                $builder->slideDown($action['selector'] ?? '', $action['duration'] ?? 400);
                break;

            case 'slideUp':
                $builder->slideUp($action['selector'] ?? '', $action['duration'] ?? 400);
                break;

            case 'slideToggle':
                $builder->slideToggle($action['selector'] ?? '', $action['duration'] ?? 400);
                break;

            case 'openModal':
                $builder->openModal($action['modal'] ?? '');
                break;

            case 'closeModal':
                $builder->closeModal($action['modal'] ?? '');
                break;

            case 'toggleModal':
                $builder->toggleModal($action['modal'] ?? '');
                break;

            case 'setModalContent':
                $builder->setModalContent($action['modal'] ?? '', $action['content'] ?? '');
                break;

            case 'reloadDataTable':
                $builder->reloadDataTable($action['table'] ?? '');
                break;

            case 'updateTableRow':
                $builder->updateTableRow(
                    $action['table'] ?? '',
                    $action['row'] ?? '',
                    $action['content'] ?? ''
                );
                break;

            case 'removeTableRow':
                $builder->removeTableRow(
                    $action['table'] ?? '',
                    $action['row'] ?? '',
                    $action['animate'] ?? true,
                    $action['duration'] ?? 400
                );
                break;

            case 'resetForm':
                $builder->resetForm($action['form'] ?? '');
                break;

            case 'updateForm':
                $builder->updateForm($action['form'] ?? '', $action['values'] ?? []);
                break;

            case 'reloadWidget':
                $builder->reloadWidget($action['widget'] ?? '');
                break;

            case 'updateWidget':
                $builder->updateWidget($action['widget'] ?? '', $action['content'] ?? '');
                break;

            case 'trigger':
                $builder->trigger(
                    $action['target'] ?? 'document',
                    $action['event'] ?? '',
                    $action['data'] ?? []
                );
                break;

            case 'executeScript':
                $builder->executeScript($action['script'] ?? '');
                break;

            case 'downloadFile':
                $builder->downloadFile($action['url'] ?? '', $action['filename'] ?? '');
                break;

            case 'scrollTo':
                $builder->scrollTo(
                    $action['selector'] ?? '',
                    $action['duration'] ?? 500,
                    $action['offset'] ?? 0
                );
                break;

            case 'focusElement':
                $builder->focusElement($action['selector'] ?? '');
                break;

            case 'updateAttribute':
                $builder->updateAttribute(
                    $action['selector'] ?? '',
                    $action['attribute'] ?? '',
                    $action['value'] ?? ''
                );
                break;

            case 'removeAttribute':
                $builder->removeAttribute($action['selector'] ?? '', $action['attribute'] ?? '');
                break;

            case 'css':
                $builder->css($action['selector'] ?? '', $action['properties'] ?? []);
                break;
        }
    }

    /**
     * Check if actions array contains a notification of specific status
     */
    private function has_notification($actions, $status): bool {
        if (empty($actions) || !is_array($actions)) {
            return false;
        }

        foreach ($actions as $action) {
            if (isset($action['type']) && $action['type'] === 'notification') {
                if (isset($action['status']) && $action['status'] === $status) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Handle saving consolidated settings from the module
     */
    private function handle_save_consolidated_settings(): array {
        $response = AjaxResponseBuilder::make();

        try {
            $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if ( ! $this->validate_nonce_actions( $nonce, [ 'ultraguard_admin_nonce', 'ultraguard_save_consolidated_settings', 'ultraguard_save_settings' ] ) ) {
                return [
                    'success' => false,
                    'message' => __('Security check failed. Please refresh the page.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            // Get the submitted data
            $settings_data = wp_unslash( $_POST ?? [] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; values are sanitized by downstream setting handlers.

            if (empty($settings_data)) {
                return [
                    'success' => false,
                    'message' => __('No settings data provided.', 'ultraguard-security-suite'),
                    'code' => 400
                ];
            }

            // Remove action and nonce from data to process
            unset($settings_data['action'], $settings_data['_ultraguard_nonce'], $settings_data['nonce']);

            // Validate all settings first
            $validation_result = $this->validate_settings($settings_data);
            if ($validation_result !== true) {
                return [
                    'success' => false,
                    'message' => __('Settings validation failed', 'ultraguard-security-suite'),
                    'data' => ['errors' => $validation_result],
                    'code' => 400,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Please check the form for errors.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ],
                        [
                            'type' => 'scrollTo',
                            'selector' => '.ultraguard-alert-error',
                            'duration' => 500,
                            'offset' => -50
                        ]
                    ]
                ];
            }

            $sanitized_settings = $this->sanitize_settings($settings_data);

            // Update settings in database
            $result = $this->update_options($sanitized_settings);

            if ($result) {
                // Log the bulk update
                $this->log_info('Consolidated settings updated via AJAX', [
                    'settings_updated' => count($sanitized_settings),
                    'updated_by' => get_current_user_id()
                ]);

                return [
                    'success' => true,
                    'message' => __('Settings saved successfully.', 'ultraguard-security-suite'),
                    'data' => [
                        'updated_count' => count($sanitized_settings),
                        'updated_at'    => current_time('mysql'),
                        'saved_values'  => $sanitized_settings,
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Settings saved successfully.', 'ultraguard-security-suite'),
                            'status' => 'success',
                            'duration' => 3000
                        ],
                        [
                            'type' => 'update',
                            'selector' => '.settings-updated-time',
                            /* translators: %s: string */
                            'content' => sprintf(__('Last updated: %s', 'ultraguard-security-suite'), current_time('mysql')),
                            'method' => 'text'
                        ],
                        [
                            'type' => 'removeClass',
                            'selector' => '#settings-form',
                            'class' => 'has-changes'
                        ],
                        [
                            'type' => 'updateAttribute',
                            'selector' => '#save-button',
                            'attribute' => 'disabled',
                            'value' => true
                        ],
                        [
                            'type' => 'addClass',
                            'selector' => '#save-indicator',
                            'class' => 'saved'
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Failed to save settings. Please try again.', 'ultraguard-security-suite'),
                    'code' => 500,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Database error occurred. Please try again.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to save consolidated settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error saving settings', 'ultraguard-security-suite'),
                'code' => 500,
                'data' => ['exception' => $e->getMessage()],
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('An unexpected error occurred.', 'ultraguard-security-suite'),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Handle exporting all settings
     */
    private function handle_export_all_settings(): array {
        try {
            // Get current settings
            $settings = $this->get_all_settings();

            // Validate settings before export
            $validation_result = $this->validate_settings($settings);
            if ($validation_result !== true) {
                return [
                    'success' => false,
                    'message' => __('Settings validation failed', 'ultraguard-security-suite'),
                    'data' => ['errors' => $validation_result],
                    'code' => 400,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Cannot export invalid settings.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

            // Add export metadata
            $export_data = [
                'settings' => $settings,
                'metadata' => [
                    'exported_at' => current_time('mysql'),
                    'exported_by' => get_current_user_id(),
                    'site_url' => get_site_url(),
                    'plugin_version' => defined('ULTRAGUARD_PRO_VERSION') ? ULTRAGUARD_PRO_VERSION : 'Unknown',
                    'wordpress_version' => get_bloginfo('version'),
                    'php_version' => PHP_VERSION
                ]
            ];

            $json_data = json_encode($export_data, JSON_PRETTY_PRINT);
            $filename = 'ultraguard-security-suite-settings-' . gmdate('Y-m-d-His') . '.json';

            return [
                'success' => true,
                'message' => __('Settings export data ready.', 'ultraguard-security-suite'),
                'data' => $export_data,
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('Export prepared successfully.', 'ultraguard-security-suite'),
                        'status' => 'success',
                        'duration' => 3000
                    ],
                    [
                        'type' => 'downloadFile',
                        'url' => 'data:application/json;charset=utf-8,' . rawurlencode($json_data),
                        'filename' => $filename
                    ],
                    [
                        'type' => 'closeModal',
                        'modal' => 'export-settings-modal'
                    ]
                ]
            ];

        } catch (\Exception $e) {
            $this->log_error('Failed to export settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error exporting settings', 'ultraguard-security-suite'),
                'code' => 500,
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('Failed to generate export.', 'ultraguard-security-suite'),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Handle resetting all settings to defaults
     */
    private function handle_reset_all_settings(): array {
        try {
            // Get confirmation from POST
            $confirmed = filter_var( wp_unslash( $_POST['confirmed'] ?? false ), FILTER_VALIDATE_BOOLEAN ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reset requests are gated by the protected settings AJAX dispatcher.

            if (!$confirmed) {
                // Ask for confirmation with warning
                return [
                    'success' => false,
                    'requires_confirmation' => true,
                    'message' => __('Reset all settings to defaults?', 'ultraguard-security-suite'),
                    'data' => [
                        'confirmation_message' => __('This action cannot be undone. All your custom settings will be lost.', 'ultraguard-security-suite'),
                        'warning' => true
                    ],
                    'code' => 200,
                    'actions' => [
                        [
                            'type' => 'openModal',
                            'modal' => 'reset-confirmation-modal'
                        ],
                        [
                            'type' => 'setModalContent',
                            'modal' => 'reset-confirmation-modal',
                            'content' => $this->get_reset_confirmation_html()
                        ]
                    ]
                ];
            }

            // Reset settings
            $nonce = wp_create_nonce('ultraguard_pro_reset_settings');
            $result = $this->reset_settings($nonce);

            if ($result) {
                return [
                    'success' => true,
                    'message' => __('All settings have been reset to default values.', 'ultraguard-security-suite'),
                    'data' => [
                        'reset_at' => current_time('mysql'),
                        'reset_by' => get_current_user_id()
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Settings reset successfully.', 'ultraguard-security-suite'),
                            'status' => 'success',
                            'duration' => 5000
                        ],
                        [
                            'type' => 'closeModal',
                            'modal' => 'reset-confirmation-modal'
                        ],
                        [
                            'type' => 'reload',
                            'delay' => 1500
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Failed to reset settings. Please try again.', 'ultraguard-security-suite'),
                    'code' => 500,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Reset operation failed.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to reset settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error resetting settings', 'ultraguard-security-suite'),
                'code' => 500,
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('An unexpected error occurred.', 'ultraguard-security-suite'),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Get HTML for reset confirmation modal
     */
    private function get_reset_confirmation_html(): string {
        return '<div class="ultraguard-confirmation-content">
            <div class="ultraguard-alert ultraguard-alert-warning">
                <span class="dashicons dashicons-warning"></span>
                <strong>' . __('Warning!', 'ultraguard-security-suite') . '</strong>
                <p>' . __('This action will reset all plugin settings to their default values. This cannot be undone.', 'ultraguard-security-suite') . '</p>
            </div>
            <p>' . __('Are you sure you want to continue?', 'ultraguard-security-suite') . '</p>
            <div class="ultraguard-confirmation-actions">
                <button type="button" class="ultraguard-button ultraguard-button-secondary" data-modal-close="reset-confirmation-modal">
                    ' . __('Cancel', 'ultraguard-security-suite') . '
                </button>
                <button type="button" class="ultraguard-button ultraguard-button-danger" id="confirm-reset-button" data-confirmed="1">
                    ' . __('Yes, Reset Everything', 'ultraguard-security-suite') . '
                </button>
            </div>
        </div>';
    }

    /**
     * Handle testing all configurations
     */
    private function handle_test_configurations(): array {
        try {
            $results = [];

            // Test 1: Settings loading and validation
            $results['settings_load'] = $this->test_settings_loading();

            // Test 2: Database connectivity
            $results['database'] = $this->test_database_connectivity();

            // Test 3: File permissions
            $results['file_permissions'] = $this->test_file_permissions();

            // Test 4: Email notifications
            $results['is_email_notifications'] = $this->test_email_notifications();

            // Test 5: Security features
            $results['security_features'] = $this->test_security_features();

            // Test 6: Validation engine
            $results['validation_engine'] = $this->test_validation_engine();

            // Calculate overall status
            $passed_tests = array_filter($results, function($test) {
                return isset($test['success']) && $test['success'];
            });

            $overall_status = count($passed_tests) === count($results) ? 'success' : 'warning';
            $passed_count = count($passed_tests);
            $total_count = count($results);

            return [
                'success' => true,
                /* translators: %1$d: integer, %2$d: integer */
                'message' => sprintf(__('Tests completed: %1$d/%2$d passed', 'ultraguard-security-suite'), $passed_count, $total_count),
                'data' => [
                    'results' => $results,
                    'overall_status' => $overall_status,
                    'passed_tests' => $passed_count,
                    'total_tests' => $total_count,
                    'tested_at' => current_time('mysql')
                ],
                'actions' => [
                    [
                        'type' => 'notification',
                        /* translators: %1$d: integer, %2$d: integer */
                        'message' => sprintf(__('Configuration tests completed: %1$d/%2$d passed', 'ultraguard-security-suite'), $passed_count, $total_count),
                        'status' => $overall_status === 'success' ? 'success' : 'warning',
                        'duration' => 5000
                    ],
                    [
                        'type' => 'update',
                        'selector' => '#test-results-container',
                        'content' => $this->generate_test_results_html($results),
                        'method' => 'html'
                    ],
                    [
                        'type' => 'show',
                        'selector' => '#test-results-container'
                    ],
                    [
                        'type' => 'scrollTo',
                        'selector' => '#test-results-container',
                        'duration' => 500,
                        'offset' => -50
                    ]
                ]
            ];

        } catch (\Exception $e) {
            $this->log_error('Failed to test configurations: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error testing configurations', 'ultraguard-security-suite'),
                'code' => 500,
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('Test execution failed.', 'ultraguard-security-suite'),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Generate HTML for test results
     */
    private function generate_test_results_html($results): string {
        $html = '<div class="ultraguard-test-results">';
        $html .= '<h3>' . __('Configuration Test Results', 'ultraguard-security-suite') . '</h3>';
        $html .= '<table class="ultraguard-table">';
        $html .= '<thead><tr><th>' . __('Test', 'ultraguard-security-suite') . '</th><th>' . __('Status', 'ultraguard-security-suite') . '</th><th>' . __('Details', 'ultraguard-security-suite') . '</th></tr></thead>';
        $html .= '<tbody>';

        foreach ($results as $testName => $result) {
            $statusClass = $result['success'] ? 'success' : 'error';
            $icon = $result['success'] ? 'dashicons-yes' : 'dashicons-no';
            $statusText = $result['success'] ? __('Passed', 'ultraguard-security-suite') : __('Failed', 'ultraguard-security-suite');

            $html .= '<tr class="ultraguard-test-' . $statusClass . '">';
            $html .= '<td><strong>' . ucfirst(str_replace('_', ' ', $testName)) . '</strong></td>';
            $html .= '<td><span class="dashicons ' . $icon . '"></span> ' . $statusText . '</td>';
            $html .= '<td>' . ($result['message'] ?? '') . '</td>';
            $html .= '</tr>';
        }

        $html .= '</tbody>';
        $html .= '</table>';
        $html .= '</div>';

        return $html;
    }

    /**
     * Test validation engine functionality
     */
    private function test_validation_engine(): array {
        try {
            // Test basic validation
            $test_data = [
                'test_email' => 'test@example.com',
                'test_url' => 'https://example.com',
                'test_number' => 42
            ];

            $test_rules = [
                'test_email' => 'email',
                'test_url' => 'url',
                'test_number' => ['number' => ['min' => 1, 'max' => 100]]
            ];

            $is_valid = $this->validation_engine->validate($test_data, $test_rules);

            return [
                'success' => $is_valid,
                'message' => $is_valid ?
                    __('Validation engine working correctly.', 'ultraguard-security-suite') :
                    __('Validation engine test failed.', 'ultraguard-security-suite')
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('Validation engine error: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Test settings loading
     */
    private function test_settings_loading(): array {
        try {
            $settings = $this->load_settings_from_database();

            // Validate loaded settings
            $validation_result = $this->validate_settings($settings);

            return [
                'success' => $validation_result === true,
                'message' => $validation_result === true ?
                    __('Settings loaded and validated successfully.', 'ultraguard-security-suite') :
                    __('Settings loaded but validation failed.', 'ultraguard-security-suite')
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('Failed to load settings: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Test database connectivity
     */
    private function test_database_connectivity(): array {
        global $wpdb;

        try {
            // Test database connection
            $result = $wpdb->get_var("SELECT 1");  // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- static query, no user input

            if ($result === '1') {
                return [
                    'success' => true,
                    'message' => __('Database connection successful.', 'ultraguard-security-suite')
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Database connection test failed.', 'ultraguard-security-suite')
                ];
            }
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('Database error: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Test file permissions
     */
    private function test_file_permissions(): array {
        try {
            $upload_dir = wp_upload_dir();
            $ultraguard_dir = trailingslashit($upload_dir['basedir']) . 'ultraguard-security-suite';

            $directories = [
                $ultraguard_dir,
                trailingslashit($ultraguard_dir) . 'logs',
                trailingslashit($ultraguard_dir) . 'quarantine'
            ];

            $results = [];
            $all_writable = true;

            foreach ($directories as $dir) {
                // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- direct writability check for export directory.
                $writable = is_writable($dir);
                $results[$dir] = $writable;

                if (!$writable) {
                    $all_writable = false;
                }
            }

            return [
                'success' => $all_writable,
                'message' => $all_writable ?
                    __('All required directories are writable.', 'ultraguard-security-suite') :
                    __('Some directories are not writable.', 'ultraguard-security-suite')
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('File permission test error: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Test email notifications
     */
    private function test_email_notifications(): array {
        try {
            $admin_email = $this->get_option('admin_email', get_option('admin_email'));

            // Validate email using ValidationEngine
            $email_valid = $this->validation_engine->quick_validate($admin_email, 'email');

            if (!$email_valid) {
                return [
                    'success' => false,
                    'message' => __('Invalid admin email address configured.', 'ultraguard-security-suite')
                ];
            }

            // Check if email notifications are enabled
            $email_notifications = $this->get_option('is_email_notifications', true);

            if (!$email_notifications) {
                return [
                    'success' => true,
                    'message' => __('Email notifications are disabled.', 'ultraguard-security-suite'),
                    'warning' => __('Email notifications are currently disabled.', 'ultraguard-security-suite')
                ];
            }

            return [
                'success' => true,
                'message' => __('Email notifications configured correctly.', 'ultraguard-security-suite')
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('Email test error: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Test security features
     */
    private function test_security_features(): array {
        try {
            // get_option() routes each key to its owning module blob via the
            // registered prefix map, so these reads work without hardcoded lookups.
            $features = [
                'firewall_enabled'      => $this->get_option( 'firewall_waf_enabled', true ),
                'login_limiter_enabled' => $this->get_option( 'loginlimiter_enabled', true ),
                'antivirus_enabled'     => $this->get_option( 'antivirus_enabled',    true ),
                'filechecker_enabled'   => $this->get_option( 'filechecker_enabled',  true ),
                'htaccess_protection'   => $this->get_option( 'htaccess_protection',  true ),
            ];

            $enabled_features = array_filter($features);
            $enabled_count = count($enabled_features);
            $total_count = count($features);

            return [
                'success' => $enabled_count > 0,
                'message' => sprintf(
                    /* translators: %1$d: count of enabled security features, %2$d: total security features. */
                    __('%1$d of %2$d security features are enabled.', 'ultraguard-security-suite'),
                    $enabled_count,
                    $total_count
                )
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => __('Security features test error: ', 'ultraguard-security-suite') . $e->getMessage()
            ];
        }
    }

    /**
     * Handle saving specific module settings
     */
    private function handle_save_module_settings(): array {
        try {
            $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if ( ! $this->validate_nonce_actions( $nonce, [ 'ultraguard_save_module_settings', 'ultraguard_save_module' ] ) ) {
                return [
                    'success' => false,
                    'message' => __('Security check failed.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above.
            $module = $this->sanitization_engine->quick_sanitize(wp_unslash( $_POST['module'] ?? '' ), 'text');
            // phpcs:disable WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; scalar values sanitized immediately below.
            $settings = isset( $_POST['settings'] ) && is_array( wp_unslash( $_POST['settings'] ) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                ? array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['settings'] ) )
                : [];
            // phpcs:enable

            if (empty($module) || empty($settings)) {
                return [
                    'success' => false,
                    'message' => __('Module name or settings data missing.', 'ultraguard-security-suite'),
                    'code' => 400
                ];
            }

            // Validate module settings
            $validation_result = $this->validate_settings($settings);
            if ($validation_result !== true) {
                return [
                    'success' => false,
                    'message' => __('Module settings validation failed', 'ultraguard-security-suite'),
                    'data' => ['errors' => $validation_result],
                    'code' => 400,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Please check the module settings.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ],
                        [
                            'type' => 'scrollTo',
                            'selector' => '#module-' . sanitize_title($module) . '-errors',
                            'duration' => 500
                        ]
                    ]
                ];
            }

            // Sanitize module settings
            $sanitized_settings = $this->sanitize_settings($settings);

            // Update settings
            $result = $this->update_options($sanitized_settings);

            if ($result) {
                $this->log_info('Module settings saved via AJAX', [
                    'module' => $module,
                    'settings_updated' => count($sanitized_settings),
                    'updated_by' => get_current_user_id()
                ]);

                return [
                    'success' => true,
                    'message' => __('Module settings saved successfully.', 'ultraguard-security-suite'),
                    'data' => [
                        'module' => $module,
                        'saved_count' => count($sanitized_settings)
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Module settings saved.', 'ultraguard-security-suite'),
                            'status' => 'success',
                            'duration' => 3000
                        ],
                        [
                            'type' => 'update',
                            'selector' => '#module-' . sanitize_title($module) . '-status',
                            'content' => '<span class="dashicons dashicons-yes"></span> ' . __('Settings saved', 'ultraguard-security-suite'),
                            'method' => 'html'
                        ],
                        [
                            'type' => 'removeClass',
                            'selector' => '#module-' . sanitize_title($module) . '-form',
                            'class' => 'has-changes'
                        ],
                        [
                            'type' => 'addClass',
                            'selector' => '#module-' . sanitize_title($module) . '-indicator',
                            'class' => 'saved'
                        ],
                        [
                            'type' => 'delayAction',
                            'delay' => 2000,
                            'action' => [
                                'type' => 'removeClass',
                                'selector' => '#module-' . sanitize_title($module) . '-indicator',
                                'class' => 'saved'
                            ]
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Failed to save module settings.', 'ultraguard-security-suite'),
                    'code' => 500,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Database error occurred.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to save module settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error saving module settings', 'ultraguard-security-suite'),
                'code' => 500,
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('An unexpected error occurred.', 'ultraguard-security-suite'),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Handle importing settings
     */
    private function handle_import_settings(): array {
        try {
            $response = AjaxResponseBuilder::make();
            $nonce    = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if (!$response->validateNonce($nonce, 'ultraguard_import_settings')) {
                return [
                    'success' => false,
                    'message' => __('Security check failed.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; imported payload is validated before use.
            $import_data = isset( $_POST['import_data'] ) ? wp_unslash( $_POST['import_data'] ) : '';

            if (empty($import_data)) {
                // Check for file upload — validate before reading.
                // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce validated above for this import request.
                if ( ! empty( $_FILES['import_file']['tmp_name'] ) ) {
                    // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce validated above for this import request.
                    $tmp = isset( $_FILES['import_file'] ) ? sanitize_text_field( wp_unslash( $_FILES['import_file']['tmp_name'] ) ) : '';
                    // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; uploaded file size is cast to int before use.
                    $tmp_size = (int) ( $_FILES['import_file']['size'] ?? 0 );
                    if ( ! is_uploaded_file( $tmp ) ) {
                        return [ 'success' => false, 'message' => __( 'Invalid upload source.', 'ultraguard-security-suite' ), 'code' => 400 ];
                    }
                    if ( $tmp_size > 512 * 1024 ) {
                        return [ 'success' => false, 'message' => __( 'Import file exceeds the 512 KB limit.', 'ultraguard-security-suite' ), 'code' => 400 ];
                    }
                    $import_data = file_get_contents( $tmp );
                }
            }

            if (empty($import_data)) {
                return [
                    'success' => false,
                    'message' => __('No import data provided.', 'ultraguard-security-suite'),
                    'code' => 400,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Please select a file to import.', 'ultraguard-security-suite'),
                            'status' => 'warning',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

            $nonce = wp_create_nonce('ultraguard_pro_import_settings');
            $result = $this->import_settings($import_data, $nonce);

            if (is_wp_error($result)) {
                return [
                    'success' => false,
                    'message' => $result->get_error_message(),
                    'code' => 400,
                    'data' => ['error' => $result->get_error_message()],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => $result->get_error_message(),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

            return [
                'success' => true,
                'message' => __('Settings imported successfully.', 'ultraguard-security-suite'),
                'data' => [
                    'imported_at' => current_time('mysql'),
                    'imported_by' => get_current_user_id()
                ],
                'actions' => [
                    [
                        'type' => 'notification',
                        'message' => __('Settings imported successfully.', 'ultraguard-security-suite'),
                        'status' => 'success',
                        'duration' => 5000
                    ],
                    [
                        'type' => 'closeModal',
                        'modal' => 'import-settings-modal'
                    ],
                    [
                        'type' => 'reload',
                        'delay' => 2000
                    ]
                ]
            ];

        } catch (\Exception $e) {
            $this->log_error('Failed to import settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error importing settings', 'ultraguard-security-suite'),
                'code' => 500,
                'actions' => [
                    [
                        'type' => 'notification',
                        /* translators: %s: import failure message. */
                        'message' => sprintf( __('Import failed: %s', 'ultraguard-security-suite'), $e->getMessage() ),
                        'status' => 'error',
                        'duration' => 5000
                    ]
                ]
            ];
        }
    }

    /**
     * Handle getting a specific setting
     */
    private function handle_get_setting(): array {
        try {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Public allowlisted requests are handled intentionally here.
            $setting_name = $this->sanitization_engine->quick_sanitize(wp_unslash( $_POST['setting_name'] ?? '' ), 'text');

            if (empty($setting_name)) {
                return [
                    'success' => false,
                    'message' => __('Setting name is required.', 'ultraguard-security-suite'),
                    'code' => 400
                ];
            }

            $setting_name_lc = strtolower( $setting_name );

            // Block private WordPress options (underscore prefix)
            if ( str_starts_with( $setting_name, '_' ) ) {
                return [
                    'success' => false,
                    'message' => __( 'Private options cannot be retrieved.', 'ultraguard-security-suite' ),
                    'code' => 403
                ];
            }

            // Block settings that contain credential-like substrings, even for admins.
            // Admins use the full settings page; this endpoint is for frontend consumption.
            foreach ( self::PRIVATE_KEY_PATTERNS as $pattern ) {
                if ( str_contains( $setting_name_lc, strtolower( $pattern ) ) ) {
                    return [
                        'success' => false,
                        'message' => __( 'Sensitive settings cannot be retrieved via this endpoint.', 'ultraguard-security-suite' ),
                        'code' => 403
                    ];
                }
            }

            $is_allowlisted = in_array( $setting_name, self::PUBLIC_SETTING_ALLOWLIST, true );
            $can_manage     = is_user_logged_in() && \UltraguardPro\ultraguard_current_user_can_manage();
            $is_public_guest_request = $is_allowlisted && ! is_user_logged_in();

            if ( ! $is_public_guest_request ) {
                $response = AjaxResponseBuilder::make();
                $nonce    = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

                if ( ! $response->validateNonce( $nonce, 'ultraguard_get_setting' ) ) {
                    return [
                        'success' => false,
                        'message' => __('Security check failed.', 'ultraguard-security-suite'),
                        'code' => 403
                    ];
                }
            }

            if ( ! $is_allowlisted && ! is_user_logged_in() ) {
                return [
                    'success' => false,
                    'message' => __( 'Authentication is required to access this setting.', 'ultraguard-security-suite' ),
                    'code' => 403
                ];
            }

            if ( ! $is_allowlisted && ! $can_manage ) {
                return [
                    'success' => false,
                    'message' => __( 'You are not allowed to access this setting.', 'ultraguard-security-suite' ),
                    'code' => 403
                ];
            }

            $value = $this->get_option($setting_name);

            return [
                'success' => true,
                'message' => __('Setting retrieved successfully.', 'ultraguard-security-suite'),
                'data' => [
                    'setting_name' => $setting_name,
                    'value' => $value
                ]
            ];

        } catch (\Exception $e) {
            $this->log_error('Failed to get setting: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error getting setting', 'ultraguard-security-suite'),
                'code' => 500
            ];
        }
    }

    /**
     * Handle updating a single setting
     */
    private function handle_update_setting(): array {
        try {
            $response = AjaxResponseBuilder::make();
            $nonce    = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if (!$response->validateNonce($nonce, 'ultraguard_update_setting')) {
                return [
                    'success' => false,
                    'message' => __('Security check failed.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above.
            $setting_name = $this->sanitization_engine->quick_sanitize(wp_unslash( $_POST['setting_name'] ?? '' ), 'text');
            $setting_value = isset( $_POST['setting_value'] ) ? sanitize_text_field( wp_unslash( $_POST['setting_value'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce validated above.

            if (empty($setting_name)) {
                return [
                    'success' => false,
                    'message' => __('Setting name is required.', 'ultraguard-security-suite'),
                    'code' => 400
                ];
            }

            // Validate the setting value
            if (isset($this->validation_rules[$setting_name])) {
                $validation_result = $this->validate_single_setting(
                    $setting_name,
                    $setting_value,
                    $this->validation_rules[$setting_name]
                );

                if ($validation_result !== true) {
                    return [
                        'success' => false,
                        'message' => $validation_result,
                        'code' => 400,
                        'actions' => [
                            [
                                'type' => 'notification',
                                'message' => $validation_result,
                                'status' => 'error',
                                'duration' => 5000
                            ],
                            [
                                'type' => 'addClass',
                                'selector' => '#setting-' . sanitize_title($setting_name),
                                'class' => 'ultraguard-input-error'
                            ],
                            [
                                'type' => 'focusElement',
                                'selector' => '#setting-' . sanitize_title($setting_name)
                            ]
                        ]
                    ];
                }
            }

            $result = $this->update_option($setting_name, $setting_value);

            if ($result) {
                return [
                    'success' => true,
                    'message' => __('Setting updated successfully.', 'ultraguard-security-suite'),
                    'data' => [
                        'setting_name' => $setting_name,
                        'updated_at' => current_time('mysql')
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Setting updated.', 'ultraguard-security-suite'),
                            'status' => 'success',
                            'duration' => 3000
                        ],
                        [
                            'type' => 'removeClass',
                            'selector' => '#setting-' . sanitize_title($setting_name),
                            'class' => 'ultraguard-input-error'
                        ],
                        [
                            'type' => 'addClass',
                            'selector' => '#setting-' . sanitize_title($setting_name),
                            'class' => 'ultraguard-input-success'
                        ],
                        [
                            'type' => 'delayAction',
                            'delay' => 2000,
                            'action' => [
                                'type' => 'removeClass',
                                'selector' => '#setting-' . sanitize_title($setting_name),
                                'class' => 'ultraguard-input-success'
                            ]
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Failed to update setting.', 'ultraguard-security-suite'),
                    'code' => 500,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Database error occurred.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to update setting: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error updating setting', 'ultraguard-security-suite'),
                'code' => 500
            ];
        }
    }

    /**
     * Handle bulk updating settings
     */
    private function handle_bulk_update_settings(): array {
        try {
            $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if ( ! $this->validate_nonce_actions( $nonce, [ 'ultraguard_bulk_update_settings', 'ultraguard_bulk_update' ] ) ) {
                return [
                    'success' => false,
                    'message' => __('Security check failed.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            $settings = wp_unslash( $_POST['settings'] ?? [] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; settings are sanitized by the bulk update flow.

            if (empty($settings)) {
                return [
                    'success' => false,
                    'message' => __('No settings provided for update.', 'ultraguard-security-suite'),
                    'code' => 400
                ];
            }

            // Validate settings first
            $validation_result = $this->validate_settings($settings);
            if ($validation_result !== true) {
                return [
                    'success' => false,
                    'message' => __('Settings validation failed', 'ultraguard-security-suite'),
                    'data' => ['errors' => $validation_result],
                    'code' => 400,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Please correct the errors below.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

            // Sanitize settings first
            $sanitized_settings = $this->sanitize_settings($settings);

            $result = $this->update_options($sanitized_settings);

            if ($result) {
                return [
                    'success' => true,
                    'message' => __('Settings updated successfully.', 'ultraguard-security-suite'),
                    'data' => [
                        'settings_updated' => count($sanitized_settings),
                        'updated_at' => current_time('mysql')
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            /* translators: %d: integer */
                            'message' => sprintf(__('%d settings updated.', 'ultraguard-security-suite'), count($sanitized_settings)),
                            'status' => 'success',
                            'duration' => 4000
                        ],
                        [
                            'type' => 'trigger',
                            'target' => 'document',
                            'event' => 'ultraguard:settings:bulkUpdated',
                            'data' => ['count' => count($sanitized_settings)]
                        ],
                        [
                            'type' => 'update',
                            'selector' => '#bulk-update-time',
                            'content' => current_time('mysql'),
                            'method' => 'text'
                        ],
                        [
                            'type' => 'removeClass',
                            'selector' => '.has-changes',
                            'class' => 'has-changes'
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Failed to update settings.', 'ultraguard-security-suite'),
                    'code' => 500,
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Database error occurred.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to bulk update settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error updating settings', 'ultraguard-security-suite'),
                'code' => 500
            ];
        }
    }

    /**
     * Handle validating settings
     */
    private function handle_validate_settings(): array {
        try {
            $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? $_POST['_ultraguard_nonce'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading the nonce field in order to validate it.

            // Validate nonce
            if ( ! $this->validate_nonce_actions( $nonce, [ 'ultraguard_validate_settings', 'ultraguard_validate' ] ) ) {
                return [
                    'success' => false,
                    'message' => __('Security check failed.', 'ultraguard-security-suite'),
                    'code' => 403
                ];
            }

            // phpcs:disable WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce validated above; scalar values sanitized immediately below.
            $settings = isset( $_POST['settings'] ) && is_array( wp_unslash( $_POST['settings'] ) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
                ? array_map( 'sanitize_text_field', wp_unslash( (array) $_POST['settings'] ) )
                : $this->settings;
            // phpcs:enable

            $validation_result = $this->validate_settings($settings);

            if ($validation_result === true) {
                return [
                    'success' => true,
                    'message' => __('All settings are valid.', 'ultraguard-security-suite'),
                    'data' => [
                        'valid' => true,
                        'errors' => []
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('All settings are valid.', 'ultraguard-security-suite'),
                            'status' => 'success',
                            'duration' => 3000
                        ],
                        [
                            'type' => 'hide',
                            'selector' => '#validation-errors'
                        ],
                        [
                            'type' => 'show',
                            'selector' => '#validation-success'
                        ],
                        [
                            'type' => 'removeClass',
                            'selector' => '.ultraguard-input-error',
                            'class' => 'ultraguard-input-error'
                        ]
                    ]
                ];
            } else {
                return [
                    'success' => false,
                    'message' => __('Some settings are invalid.', 'ultraguard-security-suite'),
                    'data' => [
                        'valid' => false,
                        'errors' => $validation_result
                    ],
                    'actions' => [
                        [
                            'type' => 'notification',
                            'message' => __('Validation failed. Please check errors.', 'ultraguard-security-suite'),
                            'status' => 'error',
                            'duration' => 5000
                        ],
                        [
                            'type' => 'update',
                            'selector' => '#validation-errors',
                            'content' => $this->generate_validation_errors_html($validation_result),
                            'method' => 'html'
                        ],
                        [
                            'type' => 'show',
                            'selector' => '#validation-errors'
                        ],
                        [
                            'type' => 'hide',
                            'selector' => '#validation-success'
                        ],
                        [
                            'type' => 'scrollTo',
                            'selector' => '#validation-errors',
                            'duration' => 500,
                            'offset' => -50
                        ]
                    ]
                ];
            }

        } catch (\Exception $e) {
            $this->log_error('Failed to validate settings: ' . $e->getMessage());

            return [
                'success' => false,
                'message' => __('Error validating settings', 'ultraguard-security-suite'),
                'code' => 500
            ];
        }
    }

    /**
     * Generate HTML for validation errors
     */
    private function generate_validation_errors_html($errors): string {
        if (empty($errors) || !is_array($errors)) {
            return '<div class="ultraguard-alert ultraguard-alert-success">' .
                   __('All settings are valid.', 'ultraguard-security-suite') .
                   '</div>';
        }

        $html = '<div class="ultraguard-alert ultraguard-alert-error">';
        $html .= '<strong>' . __('Validation Errors:', 'ultraguard-security-suite') . '</strong>';
        $html .= '<ul class="ultraguard-validation-errors">';

        foreach ($errors as $error) {
            $html .= '<li>' . esc_html($error) . '</li>';
        }

        $html .= '</ul>';
        $html .= '</div>';

        return $html;
    }

    /**
     * Initialize AJAX hooks
     */
    public function init_ajax_handlers(): void {
        // Register AJAX actions for logged in users
        $ajax_actions = [
            'ultraguard_save_consolidated_settings',
            'ultraguard_export_all_settings',
            'ultraguard_reset_all_settings',
            'ultraguard_save_module_settings',
            'ultraguard_import_settings',
            'ultraguard_get_setting',
            'ultraguard_update_setting',
            'ultraguard_bulk_update_settings',
            'ultraguard_validate_settings'
        ];

        foreach ($ajax_actions as $action) {
            add_action('wp_ajax_' . $action, [$this, 'handle_ajax_settings']);
        }

        // For logged out users (non-sensitive actions only)
        add_action('wp_ajax_nopriv_ultraguard_get_setting', [$this, 'handle_ajax_settings']);
    }
}
