<?php
    /**
     * The admin-specific functionality of the SensFRX plugin.
     *
     * @link       https://sensfrx.ai
     * @since      1.0.0
     *
     * @package    SensFRX
     * @subpackage SensFRX/admin
     *
     */
if (! defined('ABSPATH')) {
    die('ASPATH is required - Admin PAGE');
}
    //
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-registration-wp.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-wp-login-track.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-wp-login-failed.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-payment-attempt.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-payment.php';
    require_once plugin_dir_path(__FILE__) . 'class-sesnfrx-profile-update.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-password-reset-track.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-password-reset-failed.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-webhook.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-webhook-action.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-api-check-comment.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-add-dashboard-notification.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-api-callback-handling.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-check-order-update.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-registration-function.php';
    require_once plugin_dir_path(__FILE__) . 'class-sensfrx-dashboard-widget.php';
class SensFRX_Admin
{
    /**
     * The ID of this plugin.
     *
     * @since    1.0.0
     *
     * @var      string    $SensFrx    The ID of this plugin.
     */
    private $SensFRX;
    /**
     * The version of this plugin.
     *
     * @since    1.0.0
     * @var      string    $version    The current version of this plugin.
     */
    private $version;
    /**
     * Initialize the class and set its properties.
     *
     * @since    1.0.0
     * @param      string    $SensFrx       The name of this plugin.
     * @param      string    $version    The version of this plugin.
     */
    public $registration_wp;
    public $login_track;
    public $login_failed;
    public $payment_attempt;
    public $payment;
    public $profile_update;
    public $password_reset;
    public $password_reset_failed;
    public $webhook;
    public $webhookAction;
    public $comment_checker;
    public $dashboard_notification;
    public $api_callback;
    public $order_update_checker;
    public $registration_func;
    public function __construct($SensFRX, $version)
    {
        $this->SensFRX = $SensFRX;          // SensFRX
        $this->version = $version;            // 1.0.0
        $this->registration_wp = new SensFRX_Registration_WP();
        $this->login_track = new SensFRX_Wp_Login_Track();
        $this->login_failed = new SensFRX_WP_Login_Failed();
        $this->payment_attempt = new SensFRX_Payment_Attempt();
        $this->payment = new SensFRX_Payment();
        $this->profile_update = new SesnFRX_Profile_Update();
        $this->password_reset = new SensFRX_Password_Reset_Track();
        $this->password_reset_failed = new SensFRX_Password_Reset_Failed();
        $this->webhook = new SensFRX_Webhook();
        $this->webhookAction = new SensFRX_Webhook_Action();
        $this->comment_checker = new SensFRX_API_Check_Comment();
        $this->dashboard_notification = new SensFRX_Add_Dashboard_Notification();
        $this->api_callback = new SensFRX_API_Callback_Handling();
        $this->order_update_checker = new SensFRX_Check_Order_Update();
        $this->registration_func = new SensFRX_Registration_Function();
    }
    /**
     * Register the stylesheets for the admin area.
     *
     * @since    1.0.0
     */
    public function enqueue_styles($hook)
    {
        /**
         * Load CSS only on SensFRX plugin pages
         */
        if (
            strpos($hook, 'sensfrx_fpwoo') === false
        ) {
            return;
        }
        /**
         * Google Fonts
         */
        wp_enqueue_style(
            'google-fonts-lato',
            'https://fonts.googleapis.com/css2?family=Lato:wght@100;300;400;500;700;900&display=swap',
            array(),
            null,
            'all'
        );
        /**
         * Bootstrap CSS
         */
        wp_enqueue_style(
            'bootstrap-css',
            'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css',
            array(),
            '5.3.2',
            'all'
        );
        /**
         * Main Admin CSS
         */
        wp_enqueue_style(
            $this->SensFRX,
            plugin_dir_url(__FILE__) . 'css/sensfrx-admin208.css',
            array(),
            time(),
            'all'
        );
        /**
         * Two-column onboarding CSS
         */
        wp_enqueue_style(
            $this->SensFRX . '-twocol',
            plugin_dir_url(__FILE__) . 'css/sensfrx-onboarding-twocol.css',
            array(),
            time(),
            'all'
        );
        /**
         * Enterprise dashboard CSS
         */
        wp_enqueue_style(
            $this->SensFRX . '-enterprise-dashboard',
            plugin_dir_url(__FILE__) . 'css/sensfrx-enterprise-dashboard.css',
            array(),
            time(),
            'all'
        );
    }
    /**
     * Register the JavaScript for the admin area.
     *
     * @since    1.0.0
     */
    public function enqueue_scripts()
    {
        /**
         * Include admin-specific Javascript files.
         *
         */
        wp_enqueue_script(
            'popper-js', // Handle for the script
            'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js', // CDN URL
            array(), // Dependencies (none)
            '1.12.9', // Version
            true // Load in footer
        );
        // chart-js
        wp_enqueue_script(
            'chart-js', // Handle for the script
            'https://cdn.jsdelivr.net/npm/chart.js', // CDN URL
            array(), // Dependencies (none)
            true // Load in footer
        );
        // Enqueue the Bootstrap JS script
        wp_enqueue_script(
            'bootstrap-js', // Handle for the script
            'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js', // CDN URL
            array('popper-js'), // Dependencies (Popper.js must load first)
            '4.0.0', // Version
            true // Load in footer
        );
        wp_enqueue_script(
            'ckeditor-script',
            'https://cdn.ckeditor.com/4.20.2/standard/ckeditor.js',
            array(), // No dependencies
            null, // No version (or specify version explicitly)
            true // Load in the footer
        );
        // wp_enqueue_script( $this->SensFRX . '-admin', plugin_dir_url( __FILE__ ) . 'js/sensfrx-admin48.js', array(), '1.0.10', true );
        extract($this->sensfrx_settings_options());
        if (( isset($sensfrx_property_id) && !empty($sensfrx_property_id) ) && ( isset($sensfrx_property_secret) && !empty($sensfrx_property_secret) )) {
            wp_enqueue_script($this->SensFRX, SENSFRX_PIXEL_URL . $sensfrx_property_id, array(), '1.0.0', false);
            if (is_user_logged_in()) {
                wp_add_inline_script($this->SensFRX, '_sensfrx("userInit", "' . esc_attr(get_current_user_id()) . '");', 'after');
            }
        }
    }
    public function add_sensfrx_menu()
    {
        // ALWAYS show top-level menu (better UX - visible immediately after activation)
        // The callback will smartly show either onboarding or dashboard based on connection status
        add_menu_page(
            'Sensfrx',                          // Page title
            'Sensfrx',                          // Menu title
            'manage_options',                   // Capability
            'sensfrx_fpwoo',                    // Menu slug
            array($this, 'sensfrx_menu_callback'), // Unified callback
            'dashicons-shield',                 // Icon
            20                                  // Position
        );
    }
    /**
     * Smart menu callback that shows appropriate page based on connection status
     * - Shows onboarding page if not connected (no credentials)
     * - Shows main dashboard if connected (has credentials)
     */
    public function sensfrx_menu_callback()
    {
        $options = get_option('sensfrx_options', SensFRX::default_options());
        $p_id = isset($options['sensfrx_property_id']) ? $options['sensfrx_property_id'] : '';
        $s_key = isset($options['sensfrx_property_secret']) ? $options['sensfrx_property_secret'] : '';
        // Check if credentials exist
        if (empty($p_id) || empty($s_key)) {
            // Not connected - show onboarding page
            $this->sensfrxOnboarding();
        } else {
            // Connected - show main dashboard
            $this->sensfrx_menu_option();
        }
    }
    public function enqueue_react_app()
    {
        $script_url = plugins_url('../build/index.js', __FILE__) . '?ver=' . time(); // Dynamic version
        wp_enqueue_script(
            'react-plugin-script',
            $script_url,
            ['wp-element'],
            null, // Set to null to prevent WordPress from appending its own version
            true
        );
        wp_enqueue_script($this->SensFRX . '-admin', plugin_dir_url(__FILE__) . 'js/sensfrx_onboarding.js', array(), '3.0.2', true);
        // Pass REST API nonce to JavaScript for authentication
        wp_localize_script($this->SensFRX . '-admin', 'sensfrxData', array(
            'restUrl' => rest_url('sensfrx-fraud-prevention-for-woocommerce/'),
            'nonce' => wp_create_nonce('wp_rest'),
            'adminUrl' => admin_url()
        ));
        extract($this->sensfrx_settings_options());
        if (( isset($sensfrx_property_id) && !empty($sensfrx_property_id) ) && ( isset($sensfrx_property_secret) && !empty($sensfrx_property_secret) )) {
            wp_enqueue_script($this->SensFRX, SENSFRX_PIXEL_URL . $sensfrx_property_id, array(), '2.0.0', false);
            wp_enqueue_script($this->SensFRX . '-admin', plugin_dir_url(__FILE__) . 'js/sensfrx_code_pixelLoad3.js', array(), '2.0.0', true);
            if (is_user_logged_in()) {
                wp_add_inline_script($this->SensFRX, '_sensfrx("userInit", "' . esc_attr(get_current_user_id()) . '");', 'after');
            }
        }
    }
    // Native Wordpress Script
    public function sensfrx_script_code()
    {
        extract($this->sensfrx_settings_options());
        if (( isset($sensfrx_property_id) && !empty($sensfrx_property_id) ) && ( isset($sensfrx_property_secret) && !empty($sensfrx_property_secret) )) {
            wp_enqueue_script($this->SensFRX, SENSFRX_PIXEL_URL . $sensfrx_property_id, array(), '2.0.0', false);
            wp_enqueue_script($this->SensFRX . '-admin', plugin_dir_url(__FILE__) . 'js/sensfrx_code_pixelLoad3.js', array(), '2.0.0', true);
            if (is_user_logged_in()) {
                wp_add_inline_script($this->SensFRX, '_sensfrx("userInit", "' . esc_attr(get_current_user_id()) . '");', 'after');
            }
        }
    }
    public function sensfrx_menu_option()
    {
        // Get current tab
        $current_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'dashboard';
            // Load appropriate template based on tab
        switch ($current_tab) {
            case 'dashboard':
            case '':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-dashboard-enterprise.php';
                break;
            /* COMMENTED OUT - Email Customization UI - Will add partial customization later
        case 'email-notifications':
            require_once(SENSFRX_DIR . 'admin/partials/sensfrx-email-notifications.php');
            break;
        */
            case 'validation-rules':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-validation-rules.php';
                break;
            case 'fraud':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-fraud-list.php';
                break;
            case 'fraud-protection':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-fraud-protection.php';
                break;
            case 'settings':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-settings.php';
                break;
            case 'activity':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-activity-logs.php';
                break;
            case 'review':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-fraud-review.php';
                break;
            case 'ofac-compliance':
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-ofac-compliance.php';
                break;
            default:
                // Fallback to dashboard for unknown tabs
                require_once SENSFRX_DIR . 'admin/partials/sensfrx-dashboard-enterprise.php';
                break;
        }
    }
    private function show_coming_soon($title, $tab)
    {
        ?>
        <div class="sensfrx-enterprise-wrapper">
            <nav class="sensfrx-nav-tabs">
                <a href="?page=sensfrx_fpwoo&tab=dashboard" class="sensfrx-nav-tab">Dashboard</a>
                <a href="?page=sensfrx_fpwoo&tab=fraud" class="sensfrx-nav-tab                                                                             <?php echo $tab === 'fraud' ? 'active' : ''; ?>">Fraud Intelligence</a>
                <a href="?page=sensfrx_fpwoo&tab=policy" class="sensfrx-nav-tab                                                                             <?php echo $tab === 'policy' ? 'active' : ''; ?>">Policy Management</a>
                <a href="?page=sensfrx_fpwoo&tab=settings" class="sensfrx-nav-tab                                                                                 <?php echo $tab === 'settings' ? 'active' : ''; ?>">Settings</a>
                <a href="?page=sensfrx_fpwoo&tab=activity" class="sensfrx-nav-tab                                                                                 <?php echo $tab === 'activity' ? 'active' : ''; ?>">Activity Logs</a>
                <a href="?page=sensfrx_fpwoo&tab=review" class="sensfrx-nav-tab sensfrx-nav-tab-highlight                                                                                                         <?php echo $tab === 'review' ? 'active' : ''; ?>">Fraud Review <span class="sensfrx-nav-badge">0</span></a>
            </nav>
            <div class="sensfrx-enterprise-dashboard">
                <div style="text-align: center; padding: 100px 20px;">
                    <svg width="120" height="120" viewBox="0 0 120 120" fill="none" style="margin-bottom: 24px;">
                        <circle cx="60" cy="60" r="50" fill="#e6f2ff"/>
                        <path d="M60 30v40M60 80v5" stroke="#0066cc" stroke-width="8" stroke-linecap="round"/>
                    </svg>
                    <h1 style="font-size: 32px; color: #111827; margin: 0 0 16px;"><?php echo esc_html($title); ?></h1>
                    <p style="font-size: 18px; color: #6b7280; margin: 0 0 32px;">This feature is coming soon!</p>
                    <a href="?page=sensfrx_fpwoo&tab=dashboard" class="sensfrx-btn sensfrx-btn-primary" style="display: inline-flex; align-items: center; padding: 12px 24px; background: #0066cc; color: white; text-decoration: none; border-radius: 8px; font-weight: 500;">
                        ← Back to Dashboard
                    </a>
                </div>
            </div>
        </div>
        <?php
    }
    public function sensfrxOnboarding()
    {
    // Add body class for full-screen takeover styling
        add_filter('admin_body_class', [$this, 'add_onboarding_body_class']);
        require_once SENSFRX_DIR . 'admin/partials/class-sensfrx-onboarding.php';
    }
            /**
             * Add body class for Jetpack-style full-screen takeover onboarding
             */
    public function add_onboarding_body_class($classes)
    {
        $classes .= ' sensfrx-onboarding-active';
        return $classes;
    }
    public function add_settings()
    {
        register_setting('sensfrx_plugin_options', 'sensfrx_options', [$this, 'validate_settings']);
        register_setting('sensfrx_plugin_policy_options', 'sensfrx_policy_options', [$this, 'validate_policy_settings']);
    }
    public function validate_settings($input)
    {
        $input['sensfrx_property_id'] = wp_filter_nohtml_kses($input['sensfrx_property_id']);
        if (isset($input['sensfrx_property_id']) && (! is_numeric($input['sensfrx_property_id']) || (strlen($input['sensfrx_property_id']) != 16))) {
            $input['sensfrx_property_id'] = '';
            $message                      = esc_html__('Error: Property ID is invalid', 'sensfrx-fraud-prevention-for-woocommerce');
            add_settings_error('sensfrx_property_id', 'invalid-property-id', $message, 'error');
        }
        if (isset($input['sensfrx_property_secret']) && (empty($input['sensfrx_property_secret']))) {
            $input['sensfrx_property_secret'] = '';
            $message                          = esc_html__('Error: Property Secret is invalid', 'sensfrx-fraud-prevention-for-woocommerce');
            add_settings_error('sensfrx_property_secret', 'invalid-property-secret', $message, 'error');
        }
        return $input;
    }
    public function validate_policy_settings($input)
    {
        // Allow safe HTML tags for rich text editor fields
        $allowed_html = [
            'strong' => [],
            'em'     => [],
            'u'      => [],
            'a'      => ['href' => [], 'title' => []],
            'ul'     => [],
            'ol'     => [],
            'li'     => [],
            'br'     => [],
            'p'      => [],
            'span'   => ['style' => []],
        ];
        $input['sensfrx_medium_email']             = wp_kses($input['sensfrx_medium_email'], $allowed_html);
        $input['sensfrx_challenge_email']          = wp_kses($input['sensfrx_challenge_email'], $allowed_html);
        $input['sensfrx_deny_email']               = wp_kses($input['sensfrx_deny_email'], $allowed_html);
        $input['sensfrx_allow_payment_email']      = wp_kses($input['sensfrx_allow_payment_email'], $allowed_html);
        $input['sensfrx_challenge_payment_email']  = wp_kses($input['sensfrx_challenge_payment_email'], $allowed_html);
        $input['sensfrx_deny_payment_email']       = wp_kses($input['sensfrx_deny_payment_email'], $allowed_html);
        $input['sensfrx_allow_register_email']     = wp_kses($input['sensfrx_allow_register_email'], $allowed_html);
        $input['sensfrx_challenge_register_email'] = wp_kses($input['sensfrx_challenge_register_email'], $allowed_html);
        $input['sensfrx_deny_register_email']      = wp_kses($input['sensfrx_deny_register_email'], $allowed_html);
        $input['sensfrx_webhook_allow']            = wp_filter_nohtml_kses($input['sensfrx_webhook_allow']);
        $input['sensfrx_whitle_list_email']        = wp_filter_nohtml_kses($input['sensfrx_whitle_list_email']);
        return $input;
    }
            /**
             * AJAX handler for saving OFAC compliance settings
             */
    public function ajax_save_ofac_settings()
    {
        // Verify nonce
        check_ajax_referer('sensfrx_ofac_save', 'nonce');
        // Check user capabilities
        if (! current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Unauthorized']);
            return;
        }
        // Get the OFAC settings from POST
        $ofac_settings = isset($_POST['ofac_settings']) ? sanitize_text_field( wp_unslash( $_POST['ofac_settings'] ) ) : [];
        // Get current options
        $options = get_option('sensfrx_options', SensFRX::default_options());
        // Update only OFAC-related settings
        $ofac_keys = [
            'sensfrx_ofac_enabled',
            'sensfrx_ofac_block_countries',
            'sensfrx_ofac_sdn_check',
            'sensfrx_ofac_email_alerts',
            'sensfrx_ofac_dashboard_alerts',
            'sensfrx_ofac_audit_log',
            'sensfrx_ofac_reports',
            'sensfrx_ofac_auto_update',
        ];
        // Set all OFAC settings to 0 first (unchecked checkboxes won't be in POST data)
        foreach ($ofac_keys as $key) {
            $options[$key] = '0';
        }
        // Then update with the values that were checked
        foreach ($ofac_settings as $key => $value) {
            if (in_array($key, $ofac_keys)) {
                $options[$key] = sanitize_text_field($value);
            }
        }
        // Save updated options
        // Note: update_option returns false if value hasn't changed, so we don't check the return value
        update_option('sensfrx_options', $options);
        // Always return success if we got this far (nonce and capability checks passed)
        wp_send_json_success(['message' => 'OFAC settings saved successfully']);
    }
    public function action_links($links, $file)
    {
        if (SENSFRX_FILE === $file && current_user_can('manage_options')) {
            $settings = '<a href="' . admin_url(SENSFRX_PATH) . '">' . esc_html__('Settings', 'sensfrx-fraud-prevention-for-woocommerce') . '</a>';
            array_unshift($links, $settings);
        }
        return $links;
    }
    public function select_menu($items, $menu)
    {
        $options = get_option('sensfrx_options', SensFRX::default_options());
        $checked = '';
        $output  = '';
        $class   = '';
        foreach ($items as $item) {
            $key     = isset($options[$menu]) ? $options[$menu] : '';
            $value   = isset($item['value']) ? $item['value'] : '';
            $checked = ($value == $key) ? ' checked="checked"' : '';
            $output .= '<div class="ats-radio-inputs' . esc_attr($class) . '">';
            $output .= '<label>';
            $output .= '<input type="radio" name="sensfrx_options[' . esc_attr($menu) . ']" value="' . esc_attr($item['value']) . '"' . $checked . '> ';
            $output .= '<span>' . $item['label'] . '</span>'; //
            $output .= '</label>';
            $output .= '</div>';
        }
        return $output;
    }
    public function sensfrx_check_update()
    {
        // Fruad Protection Key added
        $options      = get_option('sensfrx_policy_options', SensFRX::default_policy_options());
        $missing_keys = [
            'sensfrx_master_fraud',
            'sensfrx_new_account_fraud',
            'sensfrx_bot_fraud',
            'sensfrx_login_fraud',
            'sensfrx_reset_password_fraud',
            'sensfrx_before_payment_fraud',
            'sensfrx_after_payment_fraud',
        ];
        foreach ($missing_keys as $key) {
            if (! isset($options[$key])) {
                $options[$key] = '1';
            }
        }
        $update_status = update_option('sensfrx_policy_options', $options);
        global $wpdb;
        $table_exists_sensfrx_webhook_logout = null;
        $table_name                          = $wpdb->prefix . 'sensfrx_webhook_logout';
        $results                             = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_webhook_logout = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_webhook_logout = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_webhook_logout) {
            $table_name      = $wpdb->prefix . 'sensfrx_webhook_logout';
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_2', 'sensfrx_group');
            if ($results !== false) {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					client_id INTEGER,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                $results = dbDelta($sql);
                wp_cache_replace('sensfrx_table_create_2', $results, 'sensfrx_group', 86400);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					client_id INTEGER,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                $results = dbDelta($sql);
                wp_cache_set('sensfrx_table_create_2', $results, 'sensfrx_group', 86400);
            }
        }
        $table_exists_sensfrx_sleep = null;
        $table_name                 = $wpdb->prefix . 'sensfrx_sleep';
        $results                    = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_sleep = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_sleep = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_sleep) {
            $table_name      = $wpdb->prefix . 'sensfrx_sleep'; // Replace 'your_custom_table' with your desired table name
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_1', 'sensfrx_group');
            if ($results !== false) {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					cid INT NOT NULL,
					c_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                $results = dbDelta($sql);
                wp_cache_replace('sensfrx_table_create_1', $results, 'sensfrx_group', 86400);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					cid INT NOT NULL,
					c_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                $results = dbDelta($sql);
                wp_cache_set('sensfrx_table_create_1', $results, 'sensfrx_group', 86400);
            }
        }
        $table_exists_sensfrx_api_active_and_webhook = null;
        $table_name                                  = $wpdb->prefix . 'sensfrx_api_active_and_webhook';
        $results                                     = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_api_active_and_webhook = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_api_active_and_webhook = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_api_active_and_webhook) {
            $table_name      = $wpdb->prefix . 'sensfrx_api_active_and_webhook';
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_3', 'sensfrx_group');
            if ($results !== false) {
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					p_id VARCHAR(255) NOT NULL,
					s_key VARCHAR(255) NOT NULL,
					sensfrx_activate VARCHAR(255) NOT NULL,
					sensfrx_webhook VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					p_id VARCHAR(255) NOT NULL,
					s_key VARCHAR(255) NOT NULL,
					sensfrx_activate VARCHAR(255) NOT NULL,
					sensfrx_webhook VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            }
        }
        $table_exists_sensfrx_tab_data = null;
        $table_name                    = $wpdb->prefix . 'sensfrx_tab_data';
        $results                       = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_tab_data = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_tab_data = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_tab_data) {
            $table_name_1    = $wpdb->prefix . 'sensfrx_tab_data';
            $charset_collate = $wpdb->get_charset_collate();
            $results_1       = wp_cache_get('sensfrx_table_create_1', 'sensfrx_group');
            if ($results_1 !== false) {
                $sql_1 = "CREATE TABLE $table_name_1 (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_tab VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql_1);
            } else {
                $sql_1 = "CREATE TABLE $table_name_1 (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_tab VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql_1);
            }
        }
        $table_exists_sensfrx_custome_filed = null;
        $table_name                         = $wpdb->prefix . 'sensfrx_custome_filed';
        $results                            = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_custome_filed = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_custome_filed = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_custome_filed) {
            $table_name_2 = $wpdb->prefix . 'sensfrx_custome_filed';
            $results_2    = wp_cache_get('sensfrx_table_create_2', 'sensfrx_group');
            if ($results_2 !== false) {
                $sql_2 = "CREATE TABLE $table_name_2 (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_custom_field VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql_2);
            } else {
                $sql_2 = "CREATE TABLE $table_name_2 (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_custom_field VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql_2);
            }
        }
        $table_exists_sensfrx_real_activity = null;
        $table_name                         = $wpdb->prefix . 'sensfrx_real_activity';
        $results                            = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_real_activity = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_real_activity = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_real_activity) {
            $table_name      = $wpdb->prefix . 'sensfrx_real_activity';
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_333', 'sensfrx_group');
            if ($results !== false) {
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_log_type VARCHAR(255) NOT NULL,
					sensfrx_log1 VARCHAR(255) NOT NULL,
					created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_log_type VARCHAR(255) NOT NULL,
					sensfrx_log1 VARCHAR(255) NOT NULL,
					created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            }
        }
        $table_exists_sensfrx_shadow_activity = null;
        $table_name                           = $wpdb->prefix . 'sensfrx_shadow_activity';
        $results                              = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_shadow_activity = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_shadow_activity = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_shadow_activity) {
            $table_name      = $wpdb->prefix . 'sensfrx_shadow_activity';
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_3334', 'sensfrx_group');
            if ($results !== false) {
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_shadow_status VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					sensfrx_shadow_status VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            }
        }
        //
        $table_exists_sensfrx_pre_payment_order = null;
        $table_name                             = $wpdb->prefix . 'sensfrx_pre_payment_order';
        $results                                = wp_cache_get('sensfrx_admin_update_data', 'sensfrx_group');
        if ($results !== false) {
            $table_exists_sensfrx_pre_payment_order = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_replace('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        } else {
            $table_exists_sensfrx_pre_payment_order = ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name );
            wp_cache_set('sensfrx_admin_update_data', $results, 'sensfrx_group', 86400);
        }
        if (false == $table_exists_sensfrx_pre_payment_order) {
            $table_name      = $wpdb->prefix . 'sensfrx_pre_payment_order';
            $charset_collate = $wpdb->get_charset_collate();
            $results         = wp_cache_get('sensfrx_table_create_3334', 'sensfrx_group');
            if ($results !== false) {
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					pre_order_id VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            } else {
                // Define the SQL query to create the table
                $sql = "CREATE TABLE $table_name (
					id INT NOT NULL AUTO_INCREMENT,
					pre_order_id VARCHAR(255) NOT NULL,
					PRIMARY KEY (id)
				) $charset_collate;";
                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
                dbDelta($sql);
            }
        }
        wp_localize_script('your-script-handle', 'sensfrx_vars', [
            'api_url' => home_url('/wp-json/sensfrx-fraud-prevention-for-woocommerce/sensfrx_api_callback_handling'),
        ]);
    }
    public function sensfrx_settings_options()
    {
        $options         = get_option('sensfrx_options', SensFRX::default_options());
        $property_id     = (isset($options['sensfrx_property_id']) && ! empty($options['sensfrx_property_id'])) ? $options['sensfrx_property_id'] : '';
        $property_secret = (isset($options['sensfrx_property_secret']) && ! empty($options['sensfrx_property_secret'])) ? $options['sensfrx_property_secret'] : '';
        $options_array   = [
            'options'                 => $options,
            'sensfrx_property_id'     => $property_id,
            'sensfrx_property_secret' => $property_secret,
            // 'pixel_track'      => $pixel_track,
            // 'login_track'     => $login_track,
            // 'reset_track'     => $reset_track
        ];
        return apply_filters('sensfrx_settings_options_array', $options_array);
    }
    public function as_login_message($message)
    {
        return $message;
    }
    public function detect_shipping_on_order($order, $data)
    {
        foreach ($order->get_shipping_methods() as $shipping_method) {
            $method_id = $shipping_method->get_method_id();
            if ($method_id === 'local_pickup') {
                $order->update_meta_data('_chosen_shipping_method', 'local_pickup');
            } elseif ($method_id === 'free_shipping') {
                $order->update_meta_data('_chosen_shipping_method', 'free_shipping');
            } elseif ($method_id === 'flat_rate') {
                $order->update_meta_data('_chosen_shipping_method', 'flat_rate');
            } else {
                $order->update_meta_data('_chosen_shipping_method', $method_id);
            }
        }
    }
    public function check_product_type_in_order($item, $cart_item_key, $values, $order)
    {
        $product = $values['data']; // WC_Product object
        if ($product->is_virtual() && $product->is_downloadable()) {
            // Both virtual and downloadable
            $item->add_meta_data('product_type', 'virtual_downloadable');
        } elseif ($product->is_virtual()) {
            // Virtual but not downloadable
            $item->add_meta_data('product_type', 'virtual');
        } elseif ($product->is_downloadable()) {
            // Downloadable but not virtual (rare but possible)
            $item->add_meta_data('product_type', 'downloadable');
        } elseif ($product->needs_shipping()) {
            // Physical product that needs shipping
            $item->add_meta_data('product_type', 'physical');
        } else {
            // Default fallback
            $item->add_meta_data('product_type', 'unknown');
        }
    }
            /**
             * AJAX handler for auto-saving settings
             *
             * @since 1.0.0
             */
    public function autosave_settings_ajax()
    {
        // Verify nonce - returns 400 if fails
        if (! check_ajax_referer('sensfrx_autosave_nonce', 'nonce', false)) {
            wp_send_json_error([
                'message' => 'Security check failed',
            ]);
            wp_die();
        }
        // Verify we have settings data
        if (! isset($_POST['settings']) || empty($_POST['settings'])) {
            wp_send_json_error([
                'message' => 'No settings data provided',
            ]);
            wp_die();
        }
        $settings = array();
        if ( isset( $_POST['settings'] ) ) {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Raw POST data is unslashed and parsed, then sanitized via map_deep() with sanitize_text_field() below
            $raw_settings = wp_unslash( $_POST['settings'] );
            parse_str( $raw_settings, $settings );
            $settings = map_deep( $settings, 'sanitize_text_field' );
        }
        // Extract sensfrx_options from the parsed data
        if (isset($settings['sensfrx_options'])) {
            $options = $settings['sensfrx_options'];
            // Validate and sanitize the options
            $validated_options = $this->validate_settings($options);
            // Update the options
            update_option('sensfrx_options', $validated_options);
            wp_send_json_success([
                'message' => 'Settings saved successfully',
            ]);
        } else {
            wp_send_json_error([
                'message' => 'Invalid settings data',
            ]);
        }
        wp_die();
    }
            /**
             * AJAX handler for resetting account/onboarding
             *
             * @since 1.0.0
             */
    public function reset_onboarding_ajax()
    {
        // Verify nonce
        if (! check_ajax_referer('sensfrx_reset_onboarding', 'nonce', false)) {
            wp_send_json_error([
                'message' => 'Security check failed',
            ]);
            wp_die();
        }
        // Clear the Getting Started dismissed state
        delete_option('sensfrx_getting_started_dismissed');
        // Clear the checklist items state
        delete_option('sensfrx_checklist_items');
        wp_send_json_success([
            'message' => 'Account reset successfully',
        ]);
        wp_die();
    }
            /**
             * AJAX handler for setting demo mode
             *
             * @since 1.0.0
             */
    public function set_demo_mode_ajax()
    {
        // Verify nonce
        if (! check_ajax_referer('sensfrx_demo_mode', 'nonce', false)) {
            wp_send_json_error([
                'message' => 'Security check failed',
            ]);
            wp_die();
        }
        // Get mode from request
        $mode = isset($_POST['mode']) ? sanitize_text_field($_POST['mode']) : 'auto';
        // Validate mode
        if (! in_array($mode, ['auto', 'enabled', 'disabled'])) {
            wp_send_json_error([
                'message' => 'Invalid mode',
            ]);
            wp_die();
        }
        // Update option
        update_option('sensfrx_demo_mode', $mode);
        wp_send_json_success([
            'message' => 'Demo mode updated successfully',
            'mode'    => $mode,
        ]);
        wp_die();
    }
    /**
     * AJAX handler for auto-saving fraud protection settings
     *
     * @since 3.0.0
     */
    public function auto_save_settings_ajax()
    {
        // Verify nonce (using wp_rest nonce that's already created)
        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'sensfrx_auto_save_nonce' ) ) {
            wp_send_json_error(array(
                'message' => 'Security check failed',
                'debug' => 'Nonce verification failed'
            ));
            wp_die();
        }
        // Get settings from POST data
        $settings = isset($_POST['settings']) ? $settings = array_map( 'sanitize_text_field', wp_unslash( $_POST['settings'] )) : [];
        if (empty($settings)) {
            wp_send_json_error([
                'message' => 'No settings provided',
            ]);
            wp_die();
        }
        // Get current options
        $options = get_option('sensfrx_policy_options', SensFRX::default_policy_options());
        // Update options with new settings
        foreach ($settings as $key => $value) {
            // Sanitize the key and value
            $key   = sanitize_text_field($key);
            $value = sanitize_text_field($value);
            // Update the option
            $options[$key] = $value;
        }
        // AUTO-SYNC ADMIN MASTER TOGGLES
        // LOGIN
        if (
            (!empty($options['sensfrx_admin_challenge_login_email']) && $options['sensfrx_admin_challenge_login_email'] === '1') ||
            (!empty($options['sensfrx_admin_deny_login_email']) && $options['sensfrx_admin_deny_login_email'] === '1')
        ) {
            $options['sensfrx_admin_login_alerts'] = '1';
        } else {
            $options['sensfrx_admin_login_alerts'] = '0';
        }
        // PAYMENT
        if (
            (!empty($options['sensfrx_admin_challenge_payment_email']) && $options['sensfrx_admin_challenge_payment_email'] === '1') ||
            (!empty($options['sensfrx_admin_deny_payment_email']) && $options['sensfrx_admin_deny_payment_email'] === '1')
        ) {
            $options['sensfrx_admin_payment_alerts'] = '1';
        } else {
            $options['sensfrx_admin_payment_alerts'] = '0';
        }
        // REGISTRATION
        if (
            (!empty($options['sensfrx_admin_challenge_register_email']) && $options['sensfrx_admin_challenge_register_email'] === '1') ||
            (!empty($options['sensfrx_admin_deny_register_email']) && $options['sensfrx_admin_deny_register_email'] === '1')
        ) {
            $options['sensfrx_admin_registration_alerts'] = '1';
        } else {
            $options['sensfrx_admin_registration_alerts'] = '0';
        }
        // Save updated options
        $updated = update_option('sensfrx_policy_options', $options);
        if ($updated || $options === get_option('sensfrx_policy_options')) {
            // Check if admin alert settings were updated and sync to API
            $admin_alert_keys = [
                'sensfrx_admin_fraud_alerts', // Global master (still used for UI control)
                'sensfrx_admin_alert_email',
                // Individual master toggles (match customer dashboard)
                'sensfrx_admin_login_alerts',
                'sensfrx_admin_payment_alerts',
                'sensfrx_admin_registration_alerts',
                // Login alert toggles
                'sensfrx_admin_challenge_login_email',
                'sensfrx_admin_deny_login_email',
                // Payment alert toggles
                'sensfrx_admin_challenge_payment_email',
                'sensfrx_admin_deny_payment_email',
                // Registration alert toggles
                'sensfrx_admin_challenge_register_email',
                'sensfrx_admin_deny_register_email',
            ];
            // Check if any admin alert setting was changed
            $admin_settings_changed = false;
            foreach ($admin_alert_keys as $key) {
                if (isset($settings[$key])) {
                    $admin_settings_changed = true;
                    break;
                }
            }
            // Sync to API if admin alerts were changed
            if ($admin_settings_changed) {
                $sync_result = SensFRX_API_Callback_Handling::sync_admin_alerts_to_api();
                // Log sync result (success or failure)
                if (! $sync_result['success']) {
                    error_log('SensFRX: Admin alerts sync warning - ' . $sync_result['message']);
                }
            }
            wp_send_json_success([
                'message'       => 'Settings saved successfully',
                'settings'      => $settings,
                'count'         => count($settings),
                'synced_to_api' => $admin_settings_changed ? true : false,
            ]);
        } else {
            wp_send_json_error([
                'message' => 'Failed to save settings',
                'debug'   => 'Database update failed',
            ]);
        }
            wp_die();
    }
            /**
             * AJAX handler for manual sync from cloud (fetch latest settings from SensFRX API)
             *
             * @since 3.1.0
             */
    public function sync_from_cloud_ajax()
    {
        // Verify nonce
        if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'sensfrx_sync_nonce' ) ) {
            wp_send_json_error([
                'message' => 'Security check failed',
            ]);
            wp_die();
        }
        // Check user capabilities
        if (! current_user_can('manage_options')) {
            wp_send_json_error([
                'message' => 'Unauthorized access',
            ]);
            wp_die();
        }
        try {
            // Fetch settings from API
            $result = SensFRX_API_Callback_Handling::fetch_admin_alerts_from_api();
            // Ensure result is an array
            if (is_object($result)) {
                $result = json_decode(json_encode($result), true);
            }
            if (isset($result['success']) && $result['success']) {
                wp_send_json_success([
                    'message'    => 'Settings synced successfully from SensFRX cloud',
                    'data'       => isset($result['data']) ? $result['data'] : null,
                    'first_time' => isset($result['first_time']) ? $result['first_time'] : false,
                ]);
            } else {
                wp_send_json_error([
                    'message' => isset($result['message']) ? $result['message'] : 'Unknown error occurred',
                ]);
            }
        } catch (Exception $e) {
            error_log('SensFRX: Manual sync exception - ' . $e->getMessage());
            wp_send_json_error([
                'message' => 'Sync failed: ' . $e->getMessage(),
            ]);
        } catch (Error $e) {
            error_log('SensFRX: Manual sync fatal error - ' . $e->getMessage());
            wp_send_json_error([
                'message' => 'Sync failed: ' . $e->getMessage(),
            ]);
        }
        wp_die();
    }
    public function sensfrxLoginError()
    {
        $message = '';
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended -- GET parameter is sanitized immediately after condition check
        if (isset($_GET['action']) && $_GET['action'] === 'as_ch_dn' && isset($_GET['as_msg']) && ! empty($_GET['as_msg'])) {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Input is sanitized and escaped below
            $custom_message = esc_html( sanitize_text_field( wp_unslash( $_GET['as_msg'] ) ) );
            $message .= '<div class="notice notice-error" style="margin-bottom:15px;">
				<p>' . $custom_message . '</p>
			</div>';
        }
        return $message;
    }
}
