<?php
/**
 * VMPFence Login Security AJAX Handler
 * Handles 2FA setup, verification, enable/disable operations
 *
 * @package VMPFence
 * @since 2.1.0
 * @since 2.2.1 Updated text-domain to vmpfence-security
 * @since 2.2.3 Removed license check to allow 2FA for all users
 */

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

/**
 * AJAX handler for 2FA setup (generate QR code)
 */
function vmpfence_ajax_setup_2fa() {
    // Verify nonce
    check_ajax_referer('vmpfence_2fa_nonce', 'nonce');

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    $user_id = get_current_user_id();
    $api_key = VMPFence_Config::get('central_api_key');

    // 2FA is now available for all users (free and premium)
    // No license check needed

    if (empty($api_key)) {
        wp_send_json_error(array('message' => __('API key not configured.', 'vmpfence-security')), 400);
    }

    // Call API to setup 2FA
    $api_client = new VMPFence_API_Client();
    $response = $api_client->setup_2fa($api_key, $user_id);

    if (is_wp_error($response)) {
        // Get detailed error information
        $error_data = $response->get_error_data();
        $error_body = isset($error_data['body']) ? $error_data['body'] : '';
        
        VMPFence_Secure_Logger::error('2FA Setup Error', [
            'error' => $response->get_error_message(),
            'body' => $error_body
        ]);
        
        wp_send_json_error(array(
            'message' => $response->get_error_message(),
            'details' => $error_body
        ), 500);
    }

    // Debug: Log what we're sending to JavaScript
    VMPFence_Secure_Logger::debug('2FA Setup Success', ['response_code' => wp_remote_retrieve_response_code($response)]);
    
    // Response should contain: qr_code_url, secret, backup_codes
    wp_send_json_success($response);
}
add_action('wp_ajax_vmpfence_setup_2fa', 'vmpfence_ajax_setup_2fa');

/**
 * AJAX handler for 2FA setup verification
 */
function vmpfence_ajax_verify_2fa_setup() {
    // Verify nonce
    check_ajax_referer('vmpfence_2fa_nonce', 'nonce');

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    $user_id = get_current_user_id();
    $code = isset($_POST['code']) ? sanitize_text_field($_POST['code']) : '';
    $api_key = VMPFence_Config::get('central_api_key');

    if (empty($code) || !preg_match('/^[0-9]{6}$/', $code)) {
        wp_send_json_error(array('message' => __('Please enter a valid 6-digit code.', 'vmpfence-security')), 400);
    }

    // Call API to verify setup
    $api_client = new VMPFence_API_Client();
    $response = $api_client->verify_2fa_setup($api_key, $user_id, $code);

    if (is_wp_error($response)) {
        wp_send_json_error(array('message' => $response->get_error_message()), 500);
    }

    // Debug log
    VMPFence_Secure_Logger::debug('Verify 2FA Setup', ['response_code' => wp_remote_retrieve_response_code($response)]);

    // Check if verification was successful (API returns 'success' as true/1)
    if (isset($response['success']) && $response['success']) {
        wp_send_json_success($response);
    } else {
        $error_msg = isset($response['message']) ? $response['message'] : __('Invalid code. Please try again.', 'vmpfence-security');
        wp_send_json_error(array('message' => $error_msg), 400);
    }
}
add_action('wp_ajax_vmpfence_verify_2fa_setup', 'vmpfence_ajax_verify_2fa_setup');

/**
 * AJAX handler for enabling 2FA
 */
function vmpfence_ajax_enable_2fa() {
    // Verify nonce
    check_ajax_referer('vmpfence_2fa_nonce', 'nonce');

    // Check user capabilities - allow forced setup users even without manage_options
    $user_id = get_current_user_id();
    $force_setup_flag = get_user_meta($user_id, 'vmpfence_force_2fa_setup', true);
    
    if (!current_user_can('manage_options') && !$force_setup_flag) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    $api_key = VMPFence_Config::get('central_api_key');

    // Call API to enable 2FA
    $api_client = new VMPFence_API_Client();
    $response = $api_client->enable_2fa($api_key, $user_id);

    if (is_wp_error($response)) {
        wp_send_json_error(array('message' => $response->get_error_message()), 500);
    }

    // Store local flag that user has 2FA enabled
    update_user_meta($user_id, 'vmpfence_2fa_enabled', true);
    
    // Clear force setup flag if it was set (user completed required setup)
    delete_user_meta($user_id, 'vmpfence_force_2fa_setup');
    delete_transient('vmpfence_2fa_setup_required_' . $user_id);

    wp_send_json_success($response);
}
add_action('wp_ajax_vmpfence_enable_2fa', 'vmpfence_ajax_enable_2fa');

/**
 * AJAX handler for disabling 2FA
 */
function vmpfence_ajax_disable_2fa() {
    // Verify nonce
    check_ajax_referer('vmpfence_2fa_nonce', 'nonce');

    // Check user capabilities - during forced setup, user shouldn't be disabling anyway
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    $user_id = get_current_user_id();
    
    // Clear force setup flag if set (should not happen, but defensive programming)
    delete_user_meta($user_id, 'vmpfence_force_2fa_setup');
    
    $api_key = VMPFence_Config::get('central_api_key');

    // Call API to disable 2FA
    $api_client = new VMPFence_API_Client();
    $response = $api_client->disable_2fa($api_key, $user_id);

    if (is_wp_error($response)) {
        wp_send_json_error(array('message' => $response->get_error_message()), 500);
    }

    // Remove local flag
    delete_user_meta($user_id, 'vmpfence_2fa_enabled');

    wp_send_json_success($response);
}
add_action('wp_ajax_vmpfence_disable_2fa', 'vmpfence_ajax_disable_2fa');

/**
 * AJAX handler for regenerating backup codes
 */
function vmpfence_ajax_regenerate_backup_codes() {
    // Verify nonce
    check_ajax_referer('vmpfence_2fa_nonce', 'nonce');

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    $user_id = get_current_user_id();
    $api_key = VMPFence_Config::get('central_api_key');

    // Call API to regenerate backup codes
    $api_client = new VMPFence_API_Client();
    $response = $api_client->regenerate_backup_codes($api_key, $user_id);

    if (is_wp_error($response)) {
        wp_send_json_error(array('message' => $response->get_error_message()), 500);
    }

    wp_send_json_success($response);
}
add_action('wp_ajax_vmpfence_regenerate_backup_codes', 'vmpfence_ajax_regenerate_backup_codes');

/**
 * AJAX handler for saving Login Security settings (Phase 1-3)
 * Saves settings to wp_vmpfence_config table via VMPFence_Config class
 */
function vmpfence_ajax_save_login_settings() {
    // Verify nonce
    check_ajax_referer('vmpfence_login_security_settings_nonce', 'nonce');

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    // Get settings JSON
    $settings_json = isset($_POST['settings']) ? wp_unslash($_POST['settings']) : '';
    $settings = json_decode($settings_json, true);

    if (!is_array($settings)) {
        wp_send_json_error(array('message' => __('Invalid settings format.', 'vmpfence-security')), 400);
    }

    // Validate settings
    $validated_settings = array();

    // Phase 1 settings
    if (isset($settings['show_last_login_column'])) {
        $validated_settings['vmpfence_show_last_login_column'] = (bool) $settings['show_last_login_column'];
    }

    if (isset($settings['delete_on_deactivate'])) {
        $validated_settings['vmpfence_delete_on_deactivate'] = (bool) $settings['delete_on_deactivate'];
    }

    // Phase 2 settings
    if (isset($settings['ntp_enabled'])) {
        $validated_settings['vmpfence_ntp_enabled'] = (bool) $settings['ntp_enabled'];
    }

    // Phase 3: 2FA Role Settings
    $valid_role_values = array('disabled', 'optional', 'required');
    $roles = array('administrator', 'editor', 'author', 'contributor', 'subscriber');
    $role_changes = array(); // Track role changes for after save
    
    foreach ($roles as $role) {
        $key = '2fa_role_' . $role;
        if (isset($settings[$key])) {
            $value = sanitize_text_field($settings[$key]);
            if (in_array($value, $valid_role_values, true)) {
                // Check if role is changing to 'required' or from 'required'
                $old_value = VMPFence_Config::get('vmpfence_2fa_role_' . $role, 'disabled');
                
                // Track changes for processing after successful save
                if ($old_value !== 'required' && $value === 'required') {
                    $role_changes[$role] = 'set_grace'; // Set grace period start time
                } elseif ($old_value === 'required' && $value !== 'required') {
                    $role_changes[$role] = 'clear_grace'; // Clear grace period meta
                }
                
                $validated_settings['vmpfence_2fa_role_' . $role] = $value;
            }
        }
    }

    // Phase 3: Grace Period (0-365 days)
    if (isset($settings['2fa_grace_period'])) {
        $grace_period = intval($settings['2fa_grace_period']);
        if ($grace_period >= 0 && $grace_period <= 365) {
            $validated_settings['vmpfence_2fa_grace_period'] = $grace_period;
        } else {
            wp_send_json_error(array('message' => __('Grace period must be between 0 and 365 days.', 'vmpfence-security')), 400);
        }
    }

    // Phase 3: Remember Device
    if (isset($settings['2fa_remember_device'])) {
        $validated_settings['vmpfence_2fa_remember_device'] = (bool) $settings['2fa_remember_device'];
    }

    // Phase 4: XML-RPC 2FA Required
    if (isset($settings['xmlrpc_2fa_required'])) {
        $validated_settings['vmpfence_xmlrpc_2fa_required'] = (bool) $settings['xmlrpc_2fa_required'];
    }

    // Phase 4: Disable XML-RPC Authentication
    if (isset($settings['disable_xmlrpc_auth'])) {
        $validated_settings['vmpfence_disable_xmlrpc_auth'] = (bool) $settings['disable_xmlrpc_auth'];
    }

    // Phase 5: WooCommerce Integration
    if (isset($settings['woocommerce_integration'])) {
        $validated_settings['vmpfence_woocommerce_integration'] = (bool) $settings['woocommerce_integration'];
    }

    // Phase 5: 2FA Shortcode
    if (isset($settings['2fa_shortcode_enabled'])) {
        $validated_settings['vmpfence_2fa_shortcode_enabled'] = (bool) $settings['2fa_shortcode_enabled'];
    }

    // Phase 6: reCAPTCHA Enabled
    if (isset($settings['recaptcha_enabled'])) {
        $validated_settings['vmpfence_recaptcha_enabled'] = (bool) $settings['recaptcha_enabled'];
    }

    // Phase 6: reCAPTCHA Site Key
    if (isset($settings['recaptcha_site_key'])) {
        $site_key = sanitize_text_field($settings['recaptcha_site_key']);
        // Validate: should be 40+ alphanumeric characters
        if (!empty($site_key) && (strlen($site_key) < 40 || !preg_match('/^[A-Za-z0-9_-]+$/', $site_key))) {
            wp_send_json_error(array('message' => __('Invalid reCAPTCHA Site Key format. Must be at least 40 characters.', 'vmpfence-security')), 400);
        }
        $validated_settings['vmpfence_recaptcha_site_key'] = $site_key;
    }

    // Phase 6: reCAPTCHA Secret Key
    if (isset($settings['recaptcha_secret_key'])) {
        $secret_key = sanitize_text_field($settings['recaptcha_secret_key']);
        // Validate: should be 40+ alphanumeric characters
        if (!empty($secret_key) && (strlen($secret_key) < 40 || !preg_match('/^[A-Za-z0-9_-]+$/', $secret_key))) {
            wp_send_json_error(array('message' => __('Invalid reCAPTCHA Secret Key format. Must be at least 40 characters.', 'vmpfence-security')), 400);
        }
        $validated_settings['vmpfence_recaptcha_secret_key'] = $secret_key;
    }

    // Phase 6: reCAPTCHA Threshold
    if (isset($settings['recaptcha_threshold'])) {
        $threshold = floatval($settings['recaptcha_threshold']);
        if ($threshold < 0.0 || $threshold > 1.0) {
            wp_send_json_error(array('message' => __('reCAPTCHA threshold must be between 0.0 and 1.0.', 'vmpfence-security')), 400);
        }
        $validated_settings['vmpfence_recaptcha_threshold'] = $threshold;
    }

    // PHASE 7: Validate IP allowlist if provided
    if (isset($settings['ip_allowlist'])) {
        $ip_allowlist = sanitize_textarea_field($settings['ip_allowlist']);
        
        // Validate IP list format
        if (class_exists('VMPFence_IP_Allowlist')) {
            $validation = VMPFence_IP_Allowlist::validate_ip_list($ip_allowlist);
            if (is_wp_error($validation)) {
                wp_send_json_error(array('message' => $validation->get_error_message()), 400);
            }
        }
        
        $validated_settings['vmpfence_ip_allowlist'] = $ip_allowlist;
    }

    // Ensure we have at least one setting to save
    if (empty($validated_settings)) {
        wp_send_json_error(array('message' => __('No valid settings provided.', 'vmpfence-security')), 400);
    }

    // Save all settings at once using VMPFence_Config
    try {
        $result = VMPFence_Config::set_multiple($validated_settings);

        if ($result) {
            // Process role changes AFTER successful save
            foreach ($role_changes as $role => $action) {
                if ($action === 'set_grace') {
                    // Role changed to required, set grace period start time
                    $paged = 0;
                    $batch_size = 100;
                    $grace_time = current_time('timestamp');
                    do {
                        $users = get_users(array(
                            'role' => $role,
                            'number' => $batch_size,
                            'offset' => $paged * $batch_size,
                            'fields' => array('ID')
                        ));
                        
                        foreach ($users as $user) {
                            $user_id = is_object($user) ? $user->ID : $user;
                            $has_2fa = get_user_meta($user_id, 'vmpfence_2fa_enabled', true);
                            if (!$has_2fa) {
                                update_user_meta($user_id, 'vmpfence_2fa_grace_start_' . $role, $grace_time);
                            }
                        }
                        $paged++;
                    } while (count($users) === $batch_size);
                } elseif ($action === 'clear_grace') {
                    // Role changed from required, clean up grace period meta
                    $paged = 0;
                    $batch_size = 100;
                    do {
                        $users = get_users(array(
                            'role' => $role,
                            'number' => $batch_size,
                            'offset' => $paged * $batch_size,
                            'fields' => array('ID')
                        ));
                        
                        foreach ($users as $user) {
                            $user_id = is_object($user) ? $user->ID : $user;
                            delete_user_meta($user_id, 'vmpfence_2fa_grace_start_' . $role);
                        }
                        $paged++;
                    } while (count($users) === $batch_size);
                }
            }
            
            wp_send_json_success(array(
                'message' => __('Settings saved successfully.', 'vmpfence-security'),
                'settings' => $settings
            ));
        } else {
            wp_send_json_error(array('message' => __('Failed to save settings. Please try again.', 'vmpfence-security')), 500);
        }
    } catch (Exception $e) {
        VMPFence_Secure_Logger::error('Save login settings error', array(
            'error' => $e->getMessage()
        ));
        wp_send_json_error(array('message' => __('An error occurred while saving settings.', 'vmpfence-security')), 500);
    }
}
add_action('wp_ajax_vmpfence_save_login_settings', 'vmpfence_ajax_save_login_settings');

/**
 * AJAX handler for loading Login Security settings (Phase 1-3)
 * Loads settings from wp_vmpfence_config table via VMPFence_Config class
 */
function vmpfence_ajax_load_login_settings() {
    // Verify nonce
    check_ajax_referer('vmpfence_login_security_settings_nonce', 'nonce');

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    // Load settings from VMPFence_Config
    $settings = array(
        // Phase 1 settings
        'show_last_login_column' => VMPFence_Config::get('vmpfence_show_last_login_column', true), // Default: true
        'delete_on_deactivate' => VMPFence_Config::get('vmpfence_delete_on_deactivate', false), // Default: false
        // Phase 2 settings
        'ntp_enabled' => VMPFence_Config::get('vmpfence_ntp_enabled', true), // Default: true (enabled)
        // Phase 3: 2FA Role Settings (defaults: admin=optional, others=disabled)
        '2fa_role_administrator' => VMPFence_Config::get('vmpfence_2fa_role_administrator', 'optional'),
        '2fa_role_editor' => VMPFence_Config::get('vmpfence_2fa_role_editor', 'disabled'),
        '2fa_role_author' => VMPFence_Config::get('vmpfence_2fa_role_author', 'disabled'),
        '2fa_role_contributor' => VMPFence_Config::get('vmpfence_2fa_role_contributor', 'disabled'),
        '2fa_role_subscriber' => VMPFence_Config::get('vmpfence_2fa_role_subscriber', 'disabled'),
        // Phase 3: Grace Period (default: 10 days)
        '2fa_grace_period' => VMPFence_Config::get('vmpfence_2fa_grace_period', 10),
        // Phase 3: Remember Device (default: false)
        '2fa_remember_device' => VMPFence_Config::get('vmpfence_2fa_remember_device', false),
        // Phase 4: XML-RPC 2FA Required (default: false)
        'xmlrpc_2fa_required' => VMPFence_Config::get('vmpfence_xmlrpc_2fa_required', false),
        // Phase 4: Disable XML-RPC Auth (default: false)
        'disable_xmlrpc_auth' => VMPFence_Config::get('vmpfence_disable_xmlrpc_auth', false),
        // Phase 5: WooCommerce Integration (default: false)
        'woocommerce_integration' => VMPFence_Config::get('vmpfence_woocommerce_integration', false),
        // Phase 5: 2FA Shortcode (default: false)
        '2fa_shortcode_enabled' => VMPFence_Config::get('vmpfence_2fa_shortcode_enabled', false),
        // Phase 6: reCAPTCHA settings
        'recaptcha_enabled' => VMPFence_Config::get('vmpfence_recaptcha_enabled', false),
        'recaptcha_site_key' => VMPFence_Config::get('vmpfence_recaptcha_site_key', ''),
        'recaptcha_secret_key' => VMPFence_Config::get('vmpfence_recaptcha_secret_key', ''),
        'recaptcha_threshold' => VMPFence_Config::get('vmpfence_recaptcha_threshold', 0.5),
        // PHASE 7: IP Allowlist
        'ip_allowlist' => VMPFence_Config::get('vmpfence_ip_allowlist', '')
    );

    wp_send_json_success($settings);
}
add_action('wp_ajax_vmpfence_load_login_settings', 'vmpfence_ajax_load_login_settings');

/**
 * AJAX handler for getting user statistics by role with 2FA status (Phase 2)
 * Returns user counts per role with 2FA active/inactive breakdown
 */
function vmpfence_ajax_get_user_stats() {
    // Verify nonce
    check_ajax_referer('vmpfence_login_security_settings_nonce', 'nonce');
    
    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }
    
    // Check cache first (5 minute TTL)
    $cache_key = 'vmpfence_user_stats_' . md5(serialize(wp_roles()->get_names()));
    $cached = get_transient($cache_key);
    if (false !== $cached) {
        wp_send_json_success($cached);
        return;
    }
    
    // Get all WordPress roles
    $wp_roles = wp_roles();
    $all_roles = $wp_roles->get_names();
    $api_key = VMPFence_Config::get('central_api_key');
    $api_client = new VMPFence_API_Client();
    
    $roles_stats = array();
    
    foreach ($all_roles as $role_slug => $role_name) {
        $users = get_users(array('role' => $role_slug));
        $total = count($users);
        $twofa_active = 0;
        
        // Check 2FA status for each user (only if API available)
        // WARNING: This is an N+1 query - makes one API call per user
        if ($api_key && $total > 0) {
            foreach ($users as $user) {
                $status = $api_client->get_2fa_status($api_key, $user->ID);
                if (!is_wp_error($status) && isset($status['enabled']) && $status['enabled']) {
                    $twofa_active++;
                }
            }
        }
        
        $roles_stats[$role_slug] = array(
            'name' => translate_user_role($role_name),
            'total' => $total,
            'twofa_active' => $twofa_active,
            'twofa_inactive' => $total - $twofa_active
        );
    }
    
    $result = array('roles' => $roles_stats);
    
    // Cache for 5 minutes to reduce API load
    set_transient($cache_key, $result, 5 * MINUTE_IN_SECONDS);
    
    wp_send_json_success($result);
}
add_action('wp_ajax_vmpfence_get_user_stats', 'vmpfence_ajax_get_user_stats');

/**
 * AJAX handler for validating IP allowlist (Phase 7)
 * Validates without saving to database - just for instant feedback
 */
function vmpfence_ajax_validate_ip_allowlist() {
    // Verify nonce
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'vmpfence_login_security_settings_nonce')) {
        wp_send_json_error(array('message' => __('Security verification failed.', 'vmpfence-security')), 403);
    }

    // Check user capabilities
    if (!current_user_can('manage_options')) {
        wp_send_json_error(array('message' => __('Insufficient permissions.', 'vmpfence-security')), 403);
    }

    // Get IP allowlist
    $ip_allowlist = isset($_POST['ip_allowlist']) ? sanitize_textarea_field($_POST['ip_allowlist']) : '';
    
    // Empty is valid
    if (empty($ip_allowlist)) {
        wp_send_json_success(array('message' => __('IP allowlist is empty (no IPs will bypass security features).', 'vmpfence-security')));
    }
    
    // Validate IP list format
    if (class_exists('VMPFence_IP_Allowlist')) {
        $validation = VMPFence_IP_Allowlist::validate_ip_list($ip_allowlist);
        if (is_wp_error($validation)) {
            wp_send_json_error(array('message' => $validation->get_error_message()), 400);
        }
    }
    
    // Count valid IPs
    $lines = array_filter(array_map('trim', explode("\n", $ip_allowlist)));
    $count = count($lines);
    
    wp_send_json_success(array(
        'message' => sprintf(
            _n('%d IP address validated successfully.', '%d IP addresses validated successfully.', $count, 'vmpfence-security'),
            $count
        )
    ));
}
add_action('wp_ajax_vmpfence_validate_ip_allowlist', 'vmpfence_ajax_validate_ip_allowlist');

