<?php
/**
 * Brute Force Protection AJAX Handler
 *
 * @package VMPFence
 * @since 2.0.0
 */

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

/**
 * VMPFence Brute Force AJAX Handler
 * 
 * Handles AJAX requests for brute force protection features
 * - Unlock IP addresses
 * - Settings form updates
 */
class VMPFence_Brute_Force_Ajax {

    /**
     * Brute Force Model instance
     *
     * @var VMPFence_Brute_Force_Model
     */
    private $model;

    /**
     * Constructor
     */
    public function __construct() {
        $this->model = new VMPFence_Brute_Force_Model();
        $this->init_hooks();
    }

    /**
     * Initialize AJAX hooks
     */
    private function init_hooks() {
        // Handle unlock IP requests
        add_action('wp_ajax_vmpfence_unlock_ip', array($this, 'handle_unlock_ip'));
        
        // Handle settings form updates
        add_action('wp_ajax_vmpfence_save_brute_force_settings', array($this, 'handle_settings_update'));
        
        // Handle getting locked IPs list
        add_action('wp_ajax_vmpfence_get_locked_ips', array($this, 'handle_get_locked_ips'));
        
        // Handle getting failed attempts list
        add_action('wp_ajax_vmpfence_get_failed_attempts', array($this, 'handle_get_failed_attempts'));
    }

    /**
     * Handle unlock IP AJAX request
     */
    public function handle_unlock_ip() {
        // Verify nonce for security
        if (!wp_verify_nonce($_POST['nonce'], 'vmpfence_admin_nonce')) {
            wp_send_json_error('Invalid security token');
            return;
        }

        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }

        // Get IP address from request
        $ip = sanitize_text_field($_POST['ip']);
        
        if (empty($ip)) {
            wp_send_json_error('No IP address provided');
            return;
        }

        // Validate IP format
        if (!filter_var($ip, FILTER_VALIDATE_IP)) {
            wp_send_json_error('Invalid IP address format');
            return;
        }

        // Attempt to unlock the IP
        $result = $this->model->clear_lockout($ip);

        if ($result) {
            wp_send_json_success(array(
                'message' => 'IP address ' . $ip . ' has been unlocked successfully',
                'ip' => $ip
            ));
        } else {
            wp_send_json_error('Failed to unlock IP address');
        }
    }

    /**
     * Handle settings form update AJAX request
     */
    public function handle_settings_update() {
        // Verify nonce for security
        if (!wp_verify_nonce($_POST['nonce'], 'vmpfence_admin_nonce')) {
            wp_send_json_error('Invalid security token');
            return;
        }

        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }

        // Process brute force settings
        $settings = array();
        
        // Boolean settings
        $boolean_settings = array(
            'brute_force_enabled',
            'lock_invalid_usernames',
            'prevent_leaked_passwords_enabled',
            'enforce_strong_passwords',
            'dont_reveal_users',
            'prevent_admin_username',
            'prevent_username_discovery',
            'disable_app_passwords',
            'block_post_requests',
            'check_password_strength',
            'participate_security_network'
        );

        foreach ($boolean_settings as $setting) {
            if (isset($_POST[$setting])) {
                $settings[$setting] = (bool) $_POST[$setting];
            }
        }

        // Integer settings
        $integer_settings = array(
            'max_login_attempts',
            'max_forgot_password_attempts',
            'count_failures_window',
            'lockout_duration',
            'permanent_ban_threshold'
        );

        foreach ($integer_settings as $setting) {
            if (isset($_POST[$setting])) {
                $value = intval($_POST[$setting]);
                if ($value > 0) {
                    $settings[$setting] = $value;
                }
            }
        }

        // String settings
        $string_settings = array(
            'prevent_leaked_passwords_scope',
            'strong_passwords_scope',
            'custom_block_text'
        );

        foreach ($string_settings as $setting) {
            if (isset($_POST[$setting])) {
                $settings[$setting] = sanitize_text_field($_POST[$setting]);                        
            }
        }

        // Array settings (blocked usernames)
        if (isset($_POST['blocked_usernames'])) {
            $usernames = sanitize_textarea_field($_POST['blocked_usernames']);
            $usernames_array = array_filter(array_map('trim', explode("\n", $usernames)));
            $settings['blocked_usernames'] = $usernames_array;
        }

        // Save all settings
        $saved_count = 0;
        foreach ($settings as $key => $value) {
            if (VMPFence_Config::set($key, $value)) {
                $saved_count++;
            }
        }

        if ($saved_count > 0) {
            wp_send_json_success(array(
                'message' => 'Brute force settings saved successfully',
                'saved_count' => $saved_count
            ));
        } else {
            wp_send_json_error('No settings were updated');
        }
    }

    /**
     * Handle get locked IPs AJAX request
     */
    public function handle_get_locked_ips() {
        // Verify nonce for security
        if (!wp_verify_nonce($_POST['nonce'], 'vmpfence_admin_nonce')) {
            wp_send_json_error('Invalid security token');
            return;
        }

        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }

        global $wpdb;
        $table_name = VMPFence_Constants::get_table_name(VMPFence_Constants::TABLE_LOCKED_OUT);

        $locked_ips = $wpdb->get_results($wpdb->prepare(
            "SELECT IP, countryCode, lockedOutUntil, reason, permanent, blockedHits 
             FROM `{$table_name}` 
             WHERE lockedOutUntil > %d OR permanent = 1
             ORDER BY lockedOutUntil DESC 
             LIMIT 100",
            time()
        ));

        $formatted_ips = array();
        foreach ($locked_ips as $ip) {
            $formatted_ips[] = array(
                'ip' => $ip->IP,
                'country' => $ip->countryCode,
                'locked_until' => $ip->permanent ? 'Permanent' : date('Y-m-d H:i:s', $ip->lockedOutUntil),
                'reason' => $ip->reason,
                'permanent' => (bool) $ip->permanent,
                'blocked_hits' => $ip->blockedHits,
                'time_remaining' => $ip->permanent ? 'Permanent' : max(0, $ip->lockedOutUntil - time())
            );
        }

        wp_send_json_success(array(
            'locked_ips' => $formatted_ips,
            'total_count' => count($formatted_ips)
        ));
    }

    /**
     * Handle get failed attempts AJAX request
     */
    public function handle_get_failed_attempts() {
        // Verify nonce for security
        if (!wp_verify_nonce($_POST['nonce'], 'vmpfence_admin_nonce')) {
            wp_send_json_error('Invalid security token');
            return;
        }

        // Check user permissions
        if (!current_user_can('manage_options')) {
            wp_send_json_error('Insufficient permissions');
            return;
        }

        global $wpdb;
        $table_name = VMPFence_Constants::get_table_name(VMPFence_Constants::TABLE_SECURITY_ATTEMPTS);

        $failed_attempts = $wpdb->get_results(
            "SELECT ip_address, username, event_type, attempt_time 
             FROM `{$table_name}` 
             ORDER BY attempt_time DESC 
             LIMIT 100"
        );

        $formatted_attempts = array();
        foreach ($failed_attempts as $attempt) {
            $formatted_attempts[] = array(
                'ip' => $attempt->ip_address,
                'country' => '', // geo_location not available in this context
                'username' => $attempt->username,
                'event_type' => $attempt->event_type,
                'time' => $attempt->attempt_time,
                'timestamp' => strtotime($attempt->attempt_time)
            );
        }

        wp_send_json_success(array(
            'failed_attempts' => $formatted_attempts,
            'total_count' => count($formatted_attempts)
        ));
    }
}