<?php
/**
 * Rate Limit AJAX Handler
 *
 * Handles AJAX requests for rate limiting settings and IP management.
 *
 * @package VMPFence
 * @since 2.0.0
 */

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

/**
 * VMPFence Rate Limit AJAX Handler
 *
 * @since 2.0.0
 */
class VMPFence_Rate_Limit_Ajax {

    /**
     * Rate limit controller instance
     *
     * @var VMPFence_Rate_Limit_Controller
     */
    private $controller;

    /**
     * Constructor
     *
     * @since 2.0.0
     */
    public function __construct() {
        $this->controller = new VMPFence_Rate_Limit_Controller();
        $this->init_hooks();
    }

    /**
     * Initialize AJAX hooks
     *
     * @since 2.0.0
     * @return void
     */
    private function init_hooks() {
        // IP management
        add_action('wp_ajax_vmpfence_unblock_ip', array($this, 'unblock_ip'));
        add_action('wp_ajax_vmpfence_get_rate_limit_stats', array($this, 'get_rate_limit_stats'));
        add_action('wp_ajax_vmpfence_get_blocked_ips', array($this, 'get_blocked_ips'));
    }

    /**
     * Unblock an IP address
     *
     * @since 2.0.0
     * @return void
     */
    public function unblock_ip() {
        // Verify nonce
        if (!wp_verify_nonce($_POST['nonce'] ?? '', 'vmpfence_admin_action')) {
            wp_send_json_error(array('message' => 'Security check failed'));
            return;
        }

        // Check capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Insufficient permissions'));
            return;
        }

        $ip = sanitize_text_field($_POST['ip'] ?? '');

        if (empty($ip)) {
            wp_send_json_error(array('message' => 'IP address is required'));
            return;
        }

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

        try {
            $result = $this->controller->unblock_ip($ip);

            if ($result) {
                wp_send_json_success(array(
                    'message' => 'IP address unblocked successfully',
                    'ip' => $ip
                ));
            } else {
                wp_send_json_error(array('message' => 'Failed to unblock IP address'));
            }

        } catch (Exception $e) {
            wp_send_json_error(array('message' => 'Error unblocking IP: ' . $e->getMessage()));
        }
    }

    /**
     * Get rate limiting statistics
     *
     * @since 2.0.0
     * @return void
     */
    public function get_rate_limit_stats() {
        // Verify nonce
        if (!wp_verify_nonce($_GET['nonce'] ?? '', 'vmpfence_admin_action')) {
            wp_send_json_error(array('message' => 'Security check failed'));
            return;
        }

        // Check capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Insufficient permissions'));
            return;
        }

        try {
            $stats = $this->controller->get_stats();
            
            // Add configuration info
            $stats['settings'] = array(
                'rate_limiting_enabled' => VMPFence_Config::get('rate_limiting_enabled', 0),
                'global_rate_limit' => VMPFence_Config::get('global_rate_limit', 'unlimited'),
                'global_rate_action' => VMPFence_Config::get('global_rate_action', 'throttle'),
                'rate_block_duration' => VMPFence_Config::get('rate_block_duration', 5)
            );

            wp_send_json_success($stats);

        } catch (Exception $e) {
            wp_send_json_error(array('message' => 'Error getting stats: ' . $e->getMessage()));
        }
    }

    /**
     * Get list of blocked IPs
     *
     * @since 2.0.0
     * @return void
     */
    public function get_blocked_ips() {
        // Verify nonce
        if (!wp_verify_nonce($_GET['nonce'] ?? '', 'vmpfence_admin_action')) {
            wp_send_json_error(array('message' => 'Security check failed'));
            return;
        }

        // Check capabilities
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'Insufficient permissions'));
            return;
        }

        try {
            $blocked_ips = $this->controller->get_blocked_ips();
            
            // Format data for display
            $formatted_ips = array();
            foreach ($blocked_ips as $ip_data) {
                $formatted_ips[] = array(
                    'ip' => $ip_data['ip'],
                    'blocked_at' => date('Y-m-d H:i:s', $ip_data['blocked_at'] * 60), // Convert minute window to timestamp
                    'hit_count' => $ip_data['hit_count'],
                    'time_remaining' => $this->calculate_time_remaining($ip_data['blocked_at'])
                );
            }

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

        } catch (Exception $e) {
            wp_send_json_error(array('message' => 'Error getting blocked IPs: ' . $e->getMessage()));
        }
    }

    /**
     * Calculate time remaining for IP block
     *
     * @since 2.0.0
     * @param int $blocked_window The minute window when IP was blocked
     * @return string Human-readable time remaining
     */
    private function calculate_time_remaining($blocked_window) {
        $block_duration = VMPFence_Config::get('rate_block_duration'); // minutes
        $current_window = floor(time() / 60);
        $blocked_until = $blocked_window + $block_duration;
        $minutes_remaining = $blocked_until - $current_window;
        if ($minutes_remaining <= 0) {
            return 'Expired';
        }
        
        if ($minutes_remaining < 60) {
            return $minutes_remaining . ' minutes';
        }
        
        $hours = floor($minutes_remaining / 60);
        $mins = $minutes_remaining % 60;
        
        if ($mins > 0) {
            return $hours . 'h ' . $mins . 'm';
        }
        
        return $hours . ' hours';
    }
}