<?php
/**
 * Cloudflare Integration Admin Page for BotFend Anti-Bot Firewall
 *
 * Provides the settings UI, connection testing, and sync management
 * for the Cloudflare integration feature.
 *
 * @package BotFend\Admin\Pages
 * @since 4.9.0
 */

namespace BotFend\Admin\Pages;

use BotFend\Core\Core;
use BotFend\Cloudflare\CloudflareAPI;
use BotFend\Cloudflare\CloudflareSync;
use BotFend\Core\Config;
use BotFend\Security\Encryption;

defined( 'ABSPATH' ) || exit;

/**
 * Cloudflare Integration Admin Page class.
 *
 * Renders the Cloudflare settings page and handles all AJAX actions
 * for connection testing, IP syncing, and cache purging.
 *
 * @since 4.9.0
 */
class CloudflarePage {

    /**
     * Core instance (optional - can be null).
     *
     * @since 4.9.0
     * @var Core|null
     */
    private $core;

    /**
     * Config instance.
     *
     * @since 4.9.0
     * @var Config
     */
    private $config;

    /**
     * Encryption instance.
     *
     * @since 4.9.0
     * @var Encryption
     */
    private $encryption;

    /**
     * Cloudflare API instance.
     *
     * @since 4.9.0
     * @var CloudflareAPI|null
     */
    private $api;

    /**
     * Cloudflare Sync instance.
     *
     * @since 4.9.0
     * @var CloudflareSync|null
     */
    private $sync;

    /**
     * Admin nonce action name.
     *
     * @since 4.9.0
     * @var string
     */
    const NONCE_ACTION = 'botfend_cf_admin';

    /**
     * Settings group name for WordPress settings API.
     *
     * @since 4.9.0
     * @var string
     */
    const SETTINGS_GROUP = 'botfend_cf_settings';

    /**
     * Whether Cloudflare is configured with valid credentials.
     *
     * @since 4.9.0
     * @var bool
     */
    private $is_configured = false;

    /**
     * Whether Cloudflare integration is enabled.
     *
     * @since 4.9.0
     * @var bool
     */
    private $is_enabled = false;

    /**
     * Whether this is a Pro installation with Cloudflare feature.
     *
     * @since 4.9.0
     * @var bool
     */
    private $is_pro = false;

    /**
     * Constructor.
     *
     * @since 4.9.0
     *
     * @param Core|null $core Core instance (optional).
     */
    public function __construct( ?Core $core = null ) {
        $this->core       = $core;
        $this->config     = Config::get_instance();
        $this->encryption = Encryption::get_instance();

        // Check if Pro feature is available
        $this->is_pro = $this->check_pro_feature();

        $this->is_enabled = $this->config->get_bool( 'cf_enabled', false );

        if ( $this->is_pro && $this->is_enabled ) {
            $this->init_cloudflare_components();
        }

        add_action( 'admin_init', array( $this, 'register_settings' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );

        // AJAX handlers - only register if Pro
        if ( $this->is_pro ) {
            add_action( 'wp_ajax_botfend_cf_test_connection', array( $this, 'ajax_test_connection' ) );
            add_action( 'wp_ajax_botfend_cf_sync_now', array( $this, 'ajax_sync_now' ) );
            add_action( 'wp_ajax_botfend_cf_purge_cache', array( $this, 'ajax_purge_cache' ) );
            add_action( 'wp_ajax_botfend_cf_get_status', array( $this, 'ajax_get_status' ) );
            add_action( 'wp_ajax_botfend_cf_remove_ip', array( $this, 'ajax_remove_ip' ) );
            add_action( 'wp_ajax_botfend_cf_delete_rule', array( $this, 'ajax_delete_rule' ) );
            add_action( 'wp_ajax_botfend_cf_fix_integrity', array( $this, 'ajax_fix_integrity' ) );
        }
    }

    /**
     * Check if Cloudflare Pro feature is available.
     *
     * @since 4.9.0
     *
     * @return bool
     */
    private function check_pro_feature(): bool {
        // Check if license class exists
        if ( ! class_exists( 'BotFend\\License\\LicenseKey' ) ) {
            // If license class doesn't exist, treat as free version
            return false;
        }

        $license = \BotFend\License\LicenseKey::get_instance();
        return $license->has_feature( 'cloudflare' );
    }

    /**
     * Initialize Cloudflare API and Sync components.
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function init_cloudflare_components(): void {
        if ( ! class_exists( 'BotFend\\Cloudflare\\CloudflareAPI' ) ) {
            $api_file = BOTFEND_PATH . 'includes/cloudflare/CloudflareAPI.php';
            if ( file_exists( $api_file ) ) {
                require_once $api_file;
            } else {
                if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                    error_log( 'BotFend: CloudflareAPI.php not found' );
                }
                return;
            }
        }

        if ( ! class_exists( 'BotFend\\Cloudflare\\CloudflareSync' ) ) {
            $sync_file = BOTFEND_PATH . 'includes/cloudflare/CloudflareSync.php';
            if ( file_exists( $sync_file ) ) {
                require_once $sync_file;
            } else {
                if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                    error_log( 'BotFend: CloudflareSync.php not found' );
                }
                return;
            }
        }

        try {
            $this->api           = new CloudflareAPI( $this->config, $this->encryption );
            $this->sync          = new CloudflareSync( $this->api, $this->config );
            $this->is_configured = $this->api->is_configured();
        } catch ( \Throwable $e ) {
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                error_log( 'BotFend Cloudflare init error: ' . $e->getMessage() );
            }
            $this->is_configured = false;
        }
    }

    /**
     * Register all Cloudflare settings with the WordPress Settings API.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function register_settings(): void {
        // Basic settings
        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_enabled',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => false,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_auth_method',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_auth_method' ),
                'default'           => 'key',
            )
        );

        // Credentials with masked value preservation
        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_api_token',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_api_token' ),
                'default'           => '',
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_email',
            array(
                'type'              => 'string',
                'sanitize_callback' => 'sanitize_email',
                'default'           => '',
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_api_key',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_api_key' ),
                'default'           => '',
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_zone_id',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_zone_id' ),
                'default'           => '',
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_account_id',
            array(
                'type'              => 'string',
                'sanitize_callback' => 'sanitize_text_field',
                'default'           => '',
            )
        );

        // Sync settings
        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_sync_blocks',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => true,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_min_block_score',
            array(
                'type'              => 'integer',
                'sanitize_callback' => array( $this, 'sanitize_min_score' ),
                'default'           => 5,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_universal_action',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_universal_action' ),
                'default'           => 'block',
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_async_sync',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => true,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_restore_ip',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => true,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_debug_log',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => false,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_api_timeout',
            array(
                'type'              => 'integer',
                'sanitize_callback' => array( $this, 'sanitize_api_timeout' ),
                'default'           => 30,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_max_rules',
            array(
                'type'              => 'integer',
                'sanitize_callback' => array( $this, 'sanitize_max_rules' ),
                'default'           => 5,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_max_ips_per_rule',
            array(
                'type'              => 'integer',
                'sanitize_callback' => array( $this, 'sanitize_max_ips_per_rule' ),
                'default'           => 50,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_reject_private_ips',
            array(
                'type'              => 'boolean',
                'sanitize_callback' => array( $this, 'sanitize_checkbox' ),
                'default'           => false,
            )
        );

        register_setting(
            self::SETTINGS_GROUP,
            'botfend_cf_sync_whitelist',
            array(
                'type'              => 'string',
                'sanitize_callback' => array( $this, 'sanitize_ip_whitelist' ),
                'default'           => '',
            )
        );
    }

    /**
     * Sanitize checkbox value.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return bool
     */
    public function sanitize_checkbox( $input ): bool {
        return in_array( $input, array( '1', 1, true, 'on', 'yes' ), true );
    }

    /**
     * Sanitize authentication method.
     * NOTE: 'key' (Global API Key) is now the recommended method
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return string
     */
    public function sanitize_auth_method( $input ): string {
        $input = sanitize_text_field( $input );
        return in_array( $input, array( 'token', 'key' ), true ) ? $input : 'key';
    }

    /**
     * Sanitize API token with masked value preservation.
     *
     * Shows masked value like ******29px after save.
     * Preserves existing value if masked value is submitted.
     *
     * @since 4.9.0
     *
     * @param string $input Raw input value.
     * @return string Encrypted value.
     */
    public function sanitize_api_token( $input ): string {
        $input = trim( $input );
        $existing = get_option( 'botfend_cf_api_token', '' );

        if ( empty( $input ) ) {
            return '';
        }

        if ( strpos( $input, '*' ) === 0 ) {
            return $existing;
        }

        if ( ! empty( $existing ) ) {
            $decrypted = $this->get_decrypted_value( $existing );
            if ( ! empty( $decrypted ) ) {
                $masked = $this->mask_credential( $decrypted );
                if ( $input === $masked ) {
                    return $existing;
                }
            }
        }

        return $this->encryption->encrypt( $input );
    }

    /**
     * Sanitize API key with masked value preservation.
     *
     * @since 4.9.0
     *
     * @param string $input Raw input value.
     * @return string Encrypted value.
     */
    public function sanitize_api_key( $input ): string {
        $input = trim( $input );
        $existing = get_option( 'botfend_cf_api_key', '' );

        if ( empty( $input ) ) {
            return '';
        }

        if ( strpos( $input, '*' ) === 0 ) {
            return $existing;
        }

        if ( ! empty( $existing ) ) {
            $decrypted = $this->get_decrypted_value( $existing );
            if ( ! empty( $decrypted ) ) {
                $masked = $this->mask_credential( $decrypted );
                if ( $input === $masked ) {
                    return $existing;
                }
            }
        }

        return $this->encryption->encrypt( $input );
    }

    /**
     * Get decrypted value from encrypted or plain text.
     *
     * @since 4.9.0
     *
     * @param string $value Stored value.
     * @return string Decrypted value.
     */
    private function get_decrypted_value( string $value ): string {
        if ( empty( $value ) ) {
            return '';
        }

        if ( $this->encryption->is_encrypted( $value ) ) {
            $decrypted = $this->encryption->decrypt( $value );
            return $decrypted !== false ? $decrypted : '';
        }

        return $value;
    }

    /**
     * Mask credential for display.
     *
     * Shows format: ******29px (last 4 chars visible)
     *
     * @since 4.9.0
     *
     * @param string $value Credential value.
     * @return string Masked value.
     */
    private function mask_credential( string $value ): string {
        if ( empty( $value ) ) {
            return '';
        }

        $length = strlen( $value );

        if ( $length <= 4 ) {
            return str_repeat( '*', $length );
        }

        $visible = substr( $value, -4 );
        $masked_length = max( 6, $length - 4 );

        return str_repeat( '*', $masked_length ) . $visible;
    }

    /**
     * Sanitize zone ID.
     *
     * @since 4.9.0
     *
     * @param string $input Raw input value.
     * @return string
     */
    public function sanitize_zone_id( $input ): string {
        $input = sanitize_text_field( $input );
        if ( ! empty( $input ) && ! preg_match( '/^[a-f0-9]{32}$/i', $input ) ) {
            add_settings_error(
                self::SETTINGS_GROUP,
                'invalid_zone_id',
                __( 'Invalid Zone ID format. Must be 32 hexadecimal characters.', 'botfend-anti-bot-firewall' )
            );
        }
        return $input;
    }

    /**
     * Sanitize minimum score.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return int
     */
    public function sanitize_min_score( $input ): int {
        return min( 10, max( 1, absint( $input ) ) );
    }

    /**
     * Sanitize universal action.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return string
     */
    public function sanitize_universal_action( $input ): string {
        $input = sanitize_text_field( $input );
        $valid = array( 'block', 'challenge', 'js_challenge', 'managed_challenge' );
        return in_array( $input, $valid, true ) ? $input : 'block';
    }

    /**
     * Sanitize API timeout.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return int
     */
    public function sanitize_api_timeout( $input ): int {
        $value = absint( $input );
        return min( 60, max( 5, $value ) );
    }

    /**
     * Sanitize max rules.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return int
     */
    public function sanitize_max_rules( $input ): int {
        $value = absint( $input );
        return min( 1000, max( 1, $value ) );
    }

    /**
     * Sanitize max IPs per rule.
     *
     * @since 4.9.0
     *
     * @param mixed $input Raw input value.
     * @return int
     */
    public function sanitize_max_ips_per_rule( $input ): int {
        $value = absint( $input );
        return min( 60, max( 10, $value ) );
    }

    /**
     * Sanitize IP whitelist.
     *
     * @since 4.9.0
     *
     * @param string $input Raw input value.
     * @return string
     */
    public function sanitize_ip_whitelist( $input ): string {
        $input = sanitize_textarea_field( $input );
        $ips = array_filter( array_map( 'trim', explode( "\n", $input ) ) );
        $valid_ips = array();

        foreach ( $ips as $ip ) {
            if ( filter_var( $ip, FILTER_VALIDATE_IP ) ) {
                $valid_ips[] = $ip;
            }
        }

        return implode( "\n", $valid_ips );
    }

    /**
     * Enqueue admin assets.
     *
     * @since 4.9.0
     *
     * @param string $hook Current admin page hook.
     * @return void
     */
    public function enqueue_assets( string $hook ): void {
        if ( false === strpos( $hook, 'botfend-cloudflare' ) ) {
            return;
        }

        // Enqueue external CSS
        wp_enqueue_style(
            'botfend-cf-admin',
            BOTFEND_ASSETS_URL . 'css/cloudflare-admin.css',
            array(),
            BOTFEND_VERSION
        );

        // Enqueue external JavaScript
        wp_enqueue_script(
            'botfend-cf-admin',
            BOTFEND_ASSETS_URL . 'js/cloudflare-admin.js',
            array( 'jquery' ),
            BOTFEND_VERSION,
            true
        );

        // Localize script with proper translations
        wp_localize_script(
            'botfend-cf-admin',
            'botfendCF',
            array(
                'ajaxurl' => admin_url( 'admin-ajax.php' ),
                'nonce'   => wp_create_nonce( self::NONCE_ACTION ),
                'is_pro'  => $this->is_pro,
                'i18n'    => array(
                    'testing'             => esc_html__( 'Testing connection...', 'botfend-anti-bot-firewall' ),
                    'connection_ok'       => esc_html__( 'Connection successful!', 'botfend-anti-bot-firewall' ),
                    'connection_fail'     => esc_html__( 'Connection failed.', 'botfend-anti-bot-firewall' ),
                    'syncing'             => esc_html__( 'Syncing IPs to Cloudflare...', 'botfend-anti-bot-firewall' ),
                    'sync_complete'       => esc_html__( 'Sync complete! %d synced, %d failed.', 'botfend-anti-bot-firewall' ),
                    'purging'             => esc_html__( 'Purging cache...', 'botfend-anti-bot-firewall' ),
                    'purge_complete'      => esc_html__( 'Cache purged successfully!', 'botfend-anti-bot-firewall' ),
                    'fixing'              => esc_html__( 'Fixing integrity issues...', 'botfend-anti-bot-firewall' ),
                    'fix_complete'        => esc_html__( 'Integrity check complete! Fixed %d issues.', 'botfend-anti-bot-firewall' ),
                    'error'               => esc_html__( 'An error occurred. Please try again.', 'botfend-anti-bot-firewall' ),
                    'confirm_sync'        => esc_html__( 'Sync all blocked IPs to Cloudflare? This may take a moment.', 'botfend-anti-bot-firewall' ),
                    'confirm_purge'       => esc_html__( 'Purge all Cloudflare cache? This will clear the entire cache for this zone.', 'botfend-anti-bot-firewall' ),
                    'confirm_remove_ip'   => esc_html__( 'Remove IP %s from Cloudflare blocklist?', 'botfend-anti-bot-firewall' ),
                    'confirm_delete_rule' => esc_html__( 'Delete rule "%s"? This will remove all IPs in this rule.', 'botfend-anti-bot-firewall' ),
                    'confirm_fix'         => esc_html__( 'Run integrity check and fix any issues? This will verify and repair sync data.', 'botfend-anti-bot-firewall' ),
                    'removing'            => esc_html__( 'Removing...', 'botfend-anti-bot-firewall' ),
                    'deleting'            => esc_html__( 'Deleting...', 'botfend-anti-bot-firewall' ),
                    'remove'              => esc_html__( 'Remove', 'botfend-anti-bot-firewall' ),
                    'delete_rule'         => esc_html__( 'Delete Rule', 'botfend-anti-bot-firewall' ),
                    'pro_feature_title'   => esc_html__( 'Cloudflare Integration - Pro Feature', 'botfend-anti-bot-firewall' ),
                    'pro_feature_desc'    => esc_html__( 'Sync blocked IPs directly to Cloudflare firewall rules at the edge, blocking attacks before they reach your server.', 'botfend-anti-bot-firewall' ),
                    'upgrade_to_pro'      => esc_html__( 'Upgrade to Pro', 'botfend-anti-bot-firewall' ),
                    'learn_more'          => esc_html__( 'Learn More', 'botfend-anti-bot-firewall' ),
                    'pro_only'            => esc_html__( 'Pro Only Feature', 'botfend-anti-bot-firewall' ),
                ),
            )
        );
    }

    /**
     * Render the Cloudflare admin page.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function render(): void {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) );
        }

        // If not Pro, show upgrade notice
        if ( ! $this->is_pro ) {
            $this->render_pro_upgrade_notice();
            return;
        }

        $auth_method = $this->config->get_string( 'cf_auth_method', 'key' );
        $zone_id     = $this->config->get_string( 'cf_zone_id', '' );
        $email       = $this->config->get_string( 'cf_email', '' );

        // Get credentials with masking
        $token_raw     = $this->config->get_string( 'cf_api_token', '' );
        $token_value   = $this->get_decrypted_value( $token_raw );
        $token_masked  = $token_value ? $this->mask_credential( $token_value ) : '';
        $has_token     = ! empty( $token_raw );

        $key_raw       = $this->config->get_string( 'cf_api_key', '' );
        $key_value     = $this->get_decrypted_value( $key_raw );
        $key_masked    = $key_value ? $this->mask_credential( $key_value ) : '';
        $has_api_key   = ! empty( $key_raw );

        $status = $this->sync ? $this->sync->get_sync_status() : array(
            'total_synced'     => 0,
            'total_rules'      => 0,
            'pending_sync'     => 0,
            'last_sync'        => esc_html__( 'Never', 'botfend-anti-bot-firewall' ),
            'rule_stats'       => array(),
            'max_ips_per_rule' => 50,
            'health'           => array( 'healthy' => true, 'issues' => array() ),
        );
        $health = $status['health'] ?? array( 'healthy' => true, 'issues' => array() );
        ?>
        <div class="wrap">
            <h1><?php echo esc_html__( 'Cloudflare Integration', 'botfend-anti-bot-firewall' ); ?></h1>

            <?php $this->render_notices(); ?>

            <?php if ( $this->is_configured ) : ?>
                <?php $this->render_status_dashboard( $status, $health ); ?>
                <?php $this->render_rules_management(); ?>
            <?php endif; ?>

            <form method="post" action="options.php">
                <?php settings_fields( self::SETTINGS_GROUP ); ?>

                <?php $this->render_connection_settings( $auth_method, $zone_id, $email, $token_masked, $key_masked, $has_token, $has_api_key ); ?>
                <?php $this->render_sync_settings(); ?>
                <?php $this->render_advanced_settings(); ?>

                <p class="submit">
                    <button type="button" id="botfend-cf-test-connection" class="button button-secondary">
                        <span class="dashicons dashicons-plugins-checked"></span>
                        <?php esc_html_e( 'Test Connection', 'botfend-anti-bot-firewall' ); ?>
                    </button>
                    <span id="botfend-cf-test-result" style="margin-left: 10px; font-weight: 500;"></span>
                    <?php submit_button( null, 'primary', 'submit', false ); ?>
                </p>
            </form>
        </div>
        <?php
    }

    /**
     * Render Pro upgrade notice.
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function render_pro_upgrade_notice(): void {
        ?>
        <div class="wrap">
            <h1><?php echo esc_html__( 'Cloudflare Integration', 'botfend-anti-bot-firewall' ); ?></h1>
            
            <div class="notice notice-info botfend-pro-notice" style="margin: 20px 0; padding: 0;">
                <div class="botfend-pro-container" style="display: flex; flex-wrap: wrap; padding: 20px;">
                    <div class="botfend-pro-icon" style="flex: 0 0 80px; text-align: center; font-size: 48px;">
                        🚀
                    </div>
                    <div class="botfend-pro-content" style="flex: 1; min-width: 250px;">
                        <h2><?php echo esc_html__( 'Cloudflare Integration - Pro Feature', 'botfend-anti-bot-firewall' ); ?></h2>
                        <p><?php echo esc_html__( 'Sync blocked IPs directly to Cloudflare firewall rules at the edge, blocking attacks before they reach your server.', 'botfend-anti-bot-firewall' ); ?></p>
                        <ul style="margin: 15px 0; padding-left: 20px;">
                            <li>✓ <?php echo esc_html__( 'Automatic IP sync to Cloudflare firewall', 'botfend-anti-bot-firewall' ); ?></li>
                            <li>✓ <?php echo esc_html__( 'Edge-level blocking - saves server resources', 'botfend-anti-bot-firewall' ); ?></li>
                            <li>✓ <?php echo esc_html__( 'Bulk IP management across multiple rules', 'botfend-anti-bot-firewall' ); ?></li>
                            <li>✓ <?php echo esc_html__( 'Real-time cache purging', 'botfend-anti-bot-firewall' ); ?></li>
                            <li>✓ <?php echo esc_html__( 'Restore real visitor IP from Cloudflare headers', 'botfend-anti-bot-firewall' ); ?></li>
                        </ul>
                        <div class="botfend-pro-buttons" style="display: flex; gap: 15px; flex-wrap: wrap;">
                            <a href="<?php echo esc_url( admin_url( 'admin.php?page=botfend-license' ) ); ?>" class="button button-primary">
                                <?php echo esc_html__( 'Activate License', 'botfend-anti-bot-firewall' ); ?>
                            </a>
                            <a href="https://ejesgist.com/developer/" target="_blank" class="button button-secondary">
                                <?php echo esc_html__( 'Purchase Pro License →', 'botfend-anti-bot-firewall' ); ?>
                            </a>
                        </div>
                    </div>
                    <div class="botfend-pro-badge" style="flex: 0 0 120px; text-align: center;">
                        <span style="background: #f05a28; color: #fff; padding: 5px 12px; border-radius: 20px; font-size: 12px; font-weight: bold;">
                            <?php echo esc_html__( 'PRO ONLY', 'botfend-anti-bot-firewall' ); ?>
                        </span>
                    </div>
                </div>
            </div>
            
            <div class="botfend-card" style="margin-top: 20px; text-align: center; padding: 40px;">
                <p style="font-size: 16px; margin-bottom: 20px;">
                    <?php echo esc_html__( 'Cloudflare integration is a Pro feature. Upgrade to protect your site at the edge.', 'botfend-anti-bot-firewall' ); ?>
                </p>
                <a href="https://your-site.com/botfend-pro" target="_blank" class="button button-primary button-hero">
                    <?php echo esc_html__( 'Get BotFend Pro', 'botfend-anti-bot-firewall' ); ?>
                </a>
            </div>
        </div>
        <?php
    }

    /**
     * Render admin notices.
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function render_notices(): void {
        if ( ! $this->is_enabled ) {
            ?>
            <div class="notice notice-info">
                <p><?php esc_html_e( 'Enable Cloudflare integration below to get started.', 'botfend-anti-bot-firewall' ); ?></p>
            </div>
            <?php
        } elseif ( $this->is_enabled && ! $this->is_configured ) {
            ?>
            <div class="notice notice-warning">
                <p><?php esc_html_e( 'Cloudflare integration is enabled but not configured. Please enter your API credentials.', 'botfend-anti-bot-firewall' ); ?></p>
            </div>
            <?php
        } elseif ( $this->is_configured ) {
            ?>
            <div class="notice notice-success">
                <p><?php esc_html_e( 'Cloudflare integration is active and configured.', 'botfend-anti-bot-firewall' ); ?></p>
            </div>
            <?php
        }
    }

    /**
     * Render status dashboard.
     *
     * @since 4.9.0
     *
     * @param array $status Sync status.
     * @param array $health Health check results.
     * @return void
     */
    private function render_status_dashboard( array $status, array $health ): void {
        ?>
        <div class="botfend-cf-status-grid">
            <div class="botfend-card">
                <h3><?php esc_html_e( 'Sync Status', 'botfend-anti-bot-firewall' ); ?></h3>
                <p style="font-size: 28px; font-weight: 700; color: #2271b1; margin: 0;">
                    <?php echo esc_html( $status['total_synced'] ); ?>
                </p>
                <p style="color: #646970; margin: 5px 0 0 0;">
                    <?php esc_html_e( 'IPs synced to Cloudflare', 'botfend-anti-bot-firewall' ); ?>
                </p>
                <p style="font-size: 18px; font-weight: 600; margin: 15px 0 0 0;">
                    <?php echo esc_html( $status['total_rules'] ); ?> / <?php echo esc_html( $status['max_rules'] ?? 5 ); ?>
                </p>
                <p style="color: #646970; margin: 5px 0 0 0;">
                    <?php esc_html_e( 'Active rules', 'botfend-anti-bot-firewall' ); ?>
                </p>
                <?php if ( ! empty( $status['pending_sync'] ) ) : ?>
                    <p style="color: #d63638; margin: 8px 0 0 0; font-weight: 500;">
                        <?php
                        printf(
                            esc_html__( '%d IPs pending sync', 'botfend-anti-bot-firewall' ),
                            absint( $status['pending_sync'] )
                        );
                        ?>
                    </p>
                <?php endif; ?>
                <p style="color: #646970; font-size: 12px; margin: 5px 0 0 0;">
                    <?php
                    printf(
                        esc_html__( 'Last sync: %s', 'botfend-anti-bot-firewall' ),
                        esc_html( $status['last_sync'] )
                    );
                    ?>
                </p>
            </div>

            <div class="botfend-card">
                <h3><?php esc_html_e( 'Health Check', 'botfend-anti-bot-firewall' ); ?></h3>
                <?php if ( $health['healthy'] ) : ?>
                    <p class="botfend-health-good">
                        <span class="dashicons dashicons-yes"></span>
                        <?php esc_html_e( 'All systems healthy', 'botfend-anti-bot-firewall' ); ?>
                    </p>
                <?php else : ?>
                    <p class="botfend-health-warning">
                        <span class="dashicons dashicons-warning"></span>
                        <?php esc_html_e( 'Issues detected', 'botfend-anti-bot-firewall' ); ?>
                    </p>
                    <ul style="margin: 10px 0; font-size: 13px;">
                        <?php foreach ( $health['issues'] as $issue ) : ?>
                            <li><?php echo esc_html( $issue ); ?></li>
                        <?php endforeach; ?>
                    </ul>
                    <button type="button" id="botfend-cf-fix-integrity" class="button button-small">
                        <?php esc_html_e( 'Fix Issues', 'botfend-anti-bot-firewall' ); ?>
                    </button>
                <?php endif; ?>
            </div>

            <div class="botfend-card">
                <h3><?php esc_html_e( 'Quick Actions', 'botfend-anti-bot-firewall' ); ?></h3>
                <button type="button" id="botfend-cf-sync-now" class="button button-primary" style="width: 100%; margin-bottom: 10px;">
                    <span class="dashicons dashicons-update"></span>
                    <?php esc_html_e( 'Sync Blocked IPs Now', 'botfend-anti-bot-firewall' ); ?>
                </button>
                <button type="button" id="botfend-cf-purge-cache" class="button button-secondary" style="width: 100%; margin-bottom: 10px;">
                    <span class="dashicons dashicons-trash"></span>
                    <?php esc_html_e( 'Purge Cloudflare Cache', 'botfend-anti-bot-firewall' ); ?>
                </button>
                <button type="button" id="botfend-cf-refresh-status" class="button button-secondary" style="width: 100%;">
                    <span class="dashicons dashicons-image-rotate"></span>
                    <?php esc_html_e( 'Refresh Status', 'botfend-anti-bot-firewall' ); ?>
                </button>
                <p id="botfend-cf-action-status" style="margin-top: 10px; font-weight: 500; min-height: 20px;"></p>
            </div>
        </div>
        <?php
    }

    /**
     * Render connection settings section.
     * NOTE: Global API Key (Legacy) is now the recommended method (shown first)
     *
     * @since 4.9.0
     *
     * @param string $auth_method  Auth method.
     * @param string $zone_id      Zone ID.
     * @param string $email        Email.
     * @param string $token_masked Masked token.
     * @param string $key_masked   Masked key.
     * @param bool   $has_token    Has token.
     * @param bool   $has_api_key  Has API key.
     * @return void
     */
    private function render_connection_settings(
        string $auth_method,
        string $zone_id,
        string $email,
        string $token_masked,
        string $key_masked,
        bool $has_token,
        bool $has_api_key
    ): void {
        ?>
        <div class="botfend-card" style="margin-top: 20px;">
            <h3><?php esc_html_e( 'Connection Settings', 'botfend-anti-bot-firewall' ); ?></h3>
            <table class="form-table">
                <tr>
                    <th scope="row"><?php esc_html_e( 'Enable Integration', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_enabled" value="1" <?php checked( true, $this->config->get_bool( 'cf_enabled', false ) ); ?>>
                            <?php esc_html_e( 'Enable Cloudflare Integration', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Sync blocked IPs to Cloudflare firewall rules at the edge.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Authentication Method', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <select name="botfend_cf_auth_method" id="botfend-cf-auth-method">
                            <option value="key" <?php selected( 'key', $auth_method ); ?>>
                                <?php esc_html_e( 'Global API Key (Recommended - Easiest to set up)', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                            <option value="token" <?php selected( 'token', $auth_method ); ?>>
                                <?php esc_html_e( 'API Token (Advanced - Requires creating token with specific permissions)', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                        </select>
                        <p class="description">
                            <?php esc_html_e( 'Global API Key is recommended for most users as it only requires your Cloudflare email and API key from your profile page.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                
                <!-- Global API Key Section (Recommended - shown first) -->
                <tr id="cf-key-section" style="<?php echo 'key' !== $auth_method ? 'display: none;' : ''; ?>">
                    <th scope="row"><?php esc_html_e( 'Cloudflare Email', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="email" name="botfend_cf_email" value="<?php echo esc_attr( $email ); ?>" class="regular-text">
                        <p class="description">
                            <?php esc_html_e( 'Email address associated with your Cloudflare account.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr id="cf-key-row" style="<?php echo 'key' !== $auth_method ? 'display: none;' : ''; ?>">
                    <th scope="row"><?php esc_html_e( 'Global API Key', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="text" 
                               name="botfend_cf_api_key" 
                               value="<?php echo esc_attr( $key_masked ); ?>" 
                               class="regular-text botfend-credential-input" 
                               autocomplete="off">
                        <p class="description">
                            <?php if ( $has_api_key ) : ?>
                                <?php esc_html_e( 'API key saved and encrypted. Value shown is masked for security.', 'botfend-anti-bot-firewall' ); ?>
                                <br>
                                <em><?php esc_html_e( 'Enter a new key to update, or leave as-is to keep current value.', 'botfend-anti-bot-firewall' ); ?></em>
                            <?php else : ?>
                                <?php esc_html_e( 'Enter your Global API key from your Cloudflare profile page. Value will be stored encrypted.', 'botfend-anti-bot-firewall' ); ?>
                            <?php endif; ?>
                            <br>
                            <a href="https://dash.cloudflare.com/profile/api-tokens" target="_blank" rel="noopener noreferrer">
                                <?php esc_html_e( 'View/Generate API Key →', 'botfend-anti-bot-firewall' ); ?>
                            </a>
                        </p>
                    </td>
                </tr>
                
                <!-- API Token Section (Advanced - shown second) -->
                <tr id="cf-token-section" style="<?php echo 'token' !== $auth_method ? 'display: none;' : ''; ?>">
                    <th scope="row"><?php esc_html_e( 'API Token', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="text" 
                               name="botfend_cf_api_token" 
                               value="<?php echo esc_attr( $token_masked ); ?>" 
                               class="regular-text botfend-credential-input" 
                               autocomplete="off">
                        <p class="description">
                            <?php if ( $has_token ) : ?>
                                <?php esc_html_e( 'Token saved and encrypted. Value shown is masked for security.', 'botfend-anti-bot-firewall' ); ?>
                                <br>
                                <em><?php esc_html_e( 'Enter a new token to update, or leave as-is to keep current value.', 'botfend-anti-bot-firewall' ); ?></em>
                            <?php else : ?>
                                <?php esc_html_e( 'Enter your Cloudflare API token. Requires Zone:Read and Firewall Services:Edit permissions.', 'botfend-anti-bot-firewall' ); ?>
                            <?php endif; ?>
                            <br>
                            <a href="https://dash.cloudflare.com/profile/api-tokens" target="_blank" rel="noopener noreferrer">
                                <?php esc_html_e( 'Create API Token →', 'botfend-anti-bot-firewall' ); ?>
                            </a>
                        </p>
                    </td>
                </tr>
                
                <tr>
                    <th scope="row"><?php esc_html_e( 'Zone ID', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="text" name="botfend_cf_zone_id" value="<?php echo esc_attr( $zone_id ); ?>" class="regular-text">
                        <p class="description">
                            <?php esc_html_e( 'Found in your Cloudflare dashboard under domain overview.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Account ID', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="text" name="botfend_cf_account_id" value="<?php echo esc_attr( $this->config->get_string( 'cf_account_id', '' ) ); ?>" class="regular-text">
                        <p class="description">
                            <?php esc_html_e( 'Optional. Required for some enterprise features.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
            </table>
        </div>
        <?php
    }

    /**
     * Render sync settings section.
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function render_sync_settings(): void {
        ?>
        <div class="botfend-card" style="margin-top: 20px;">
            <h3><?php esc_html_e( 'Sync Settings', 'botfend-anti-bot-firewall' ); ?></h3>
            <table class="form-table">
                <tr>
                    <th scope="row"><?php esc_html_e( 'Sync Blocked IPs', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_sync_blocks" value="1" <?php checked( true, $this->config->get_bool( 'cf_sync_blocks', true ) ); ?>>
                            <?php esc_html_e( 'Automatically sync blocked IPs to Cloudflare', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'IPs blocked by BotFend will also be blocked at Cloudflare edge.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Minimum Score to Sync', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="number" name="botfend_cf_min_block_score" value="<?php echo esc_attr( $this->config->get_int( 'cf_min_block_score', 5 ) ); ?>" min="1" max="10" class="small-text">
                        <p class="description">
                            <?php esc_html_e( 'Only sync IPs with threat score at or above this threshold (1-10). All synced IPs will receive the universal action.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Universal Action', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <select name="botfend_cf_universal_action">
                            <option value="block" <?php selected( 'block', $this->config->get_string( 'cf_universal_action', 'block' ) ); ?>>
                                <?php esc_html_e( 'Block Immediately', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                            <option value="challenge" <?php selected( 'challenge', $this->config->get_string( 'cf_universal_action', 'block' ) ); ?>>
                                <?php esc_html_e( 'Challenge (CAPTCHA)', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                            <option value="js_challenge" <?php selected( 'js_challenge', $this->config->get_string( 'cf_universal_action', 'block' ) ); ?>>
                                <?php esc_html_e( 'JS Challenge', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                            <option value="managed_challenge" <?php selected( 'managed_challenge', $this->config->get_string( 'cf_universal_action', 'block' ) ); ?>>
                                <?php esc_html_e( 'Managed Challenge', 'botfend-anti-bot-firewall' ); ?>
                            </option>
                        </select>
                        <p class="description">
                            <?php esc_html_e( 'All synced IPs will receive this action regardless of score.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Async Processing', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_async_sync" value="1" <?php checked( true, $this->config->get_bool( 'cf_async_sync', true ) ); ?>>
                            <?php esc_html_e( 'Use async sync processing (recommended)', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Process sync via background jobs to prevent blocking requests. Disable only for debugging.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Max Rules', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="number" name="botfend_cf_max_rules" value="<?php echo esc_attr( $this->config->get_int( 'cf_max_rules', 5 ) ); ?>" min="1" max="1000" class="small-text">
                        <p class="description">
                            <?php esc_html_e( 'Maximum number of Cloudflare firewall rules to create. Free plan: 5, Pro: 100, Business: 1000.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Max IPs Per Rule', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="number" name="botfend_cf_max_ips_per_rule" value="<?php echo esc_attr( $this->config->get_int( 'cf_max_ips_per_rule', 50 ) ); ?>" min="10" max="60" class="small-text">
                        <p class="description">
                            <?php esc_html_e( 'Maximum IPs per firewall rule. Higher values use fewer rules but may hit expression limits. Recommended: 30-50.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
            </table>
        </div>
        <?php
    }

    /**
     * Render advanced settings section.
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function render_advanced_settings(): void {
        ?>
        <div class="botfend-card" style="margin-top: 20px;">
            <h3><?php esc_html_e( 'Advanced Settings', 'botfend-anti-bot-firewall' ); ?></h3>
            <table class="form-table">
                <tr>
                    <th scope="row"><?php esc_html_e( 'Restore Visitor IP', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_restore_ip" value="1" <?php checked( true, $this->config->get_bool( 'cf_restore_ip', true ) ); ?>>
                            <?php esc_html_e( 'Restore real visitor IP from Cloudflare headers', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Only enable if your server accepts traffic only from Cloudflare IPs to prevent IP spoofing.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'API Timeout', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <input type="number" name="botfend_cf_api_timeout" value="<?php echo esc_attr( $this->config->get_int( 'cf_api_timeout', 30 ) ); ?>" min="5" max="60" class="small-text">
                        <span><?php esc_html_e( 'seconds', 'botfend-anti-bot-firewall' ); ?></span>
                        <p class="description">
                            <?php esc_html_e( 'Timeout for Cloudflare API requests (5-60 seconds).', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    <tr>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Reject Private IPs', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_reject_private_ips" value="1" <?php checked( true, $this->config->get_bool( 'cf_reject_private_ips', false ) ); ?>>
                            <?php esc_html_e( 'Reject private and reserved IP ranges', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Prevent syncing of private IPs (10.x, 192.168.x, etc.) to Cloudflare.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'Debug Logging', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <label>
                            <input type="checkbox" name="botfend_cf_debug_log" value="1" <?php checked( true, $this->config->get_bool( 'cf_debug_log', false ) ); ?>>
                            <?php esc_html_e( 'Enable debug logging', 'botfend-anti-bot-firewall' ); ?>
                        </label>
                        <p class="description">
                            <?php esc_html_e( 'Log Cloudflare API requests and sync operations to error log.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><?php esc_html_e( 'IP Sync Whitelist', 'botfend-anti-bot-firewall' ); ?></th>
                    <td>
                        <textarea name="botfend_cf_sync_whitelist" class="large-text botfend-ip-whitelist" rows="4" placeholder="<?php esc_attr_e( '192.168.1.1\n10.0.0.1', 'botfend-anti-bot-firewall' ); ?>"><?php echo esc_textarea( $this->config->get_string( 'cf_sync_whitelist', '' ) ); ?></textarea>
                        <p class="description">
                            <?php esc_html_e( 'IPs to never sync to Cloudflare (one per line). Useful for trusted IPs.', 'botfend-anti-bot-firewall' ); ?>
                        </p>
                    </td>
                </tr>
            </table>
        </div>
        <?php
    }

    /**
     * Render rules management section.
     * NOTE: Action column has been REMOVED as requested
     *
     * @since 4.9.0
     *
     * @return void
     */
    private function render_rules_management(): void {
        if ( ! $this->sync ) {
            return;
        }

        $rules  = $this->sync->get_all_rules_with_ips();
        $status = $this->sync->get_sync_status();
        ?>
        <div class="botfend-card" style="margin-top: 20px;">
            <h3><?php esc_html_e( 'Cloudflare Rules Management', 'botfend-anti-bot-firewall' ); ?></h3>
            <p class="description">
                <?php
                printf(
                    esc_html__( 'Each rule can contain up to %d IPs. Expired IPs are automatically cleaned up daily.', 'botfend-anti-bot-firewall' ),
                    absint( $status['max_ips_per_rule'] )
                );
                ?>
            </p>

            <?php if ( empty( $rules ) ) : ?>
                <p><?php esc_html_e( 'No Cloudflare rules created yet. IPs will be automatically synced when blocked.', 'botfend-anti-bot-firewall' ); ?></p>
            <?php else : ?>
                <div id="botfend-cf-rules-container">
                    <?php foreach ( $rules as $rule ) : ?>
                        <div class="botfend-rule-card" data-rule-id="<?php echo esc_attr( $rule['rule_id'] ); ?>" style="border: 1px solid #ccd0d4; margin-bottom: 20px; background: #fff;">
                            <div style="padding: 15px; border-bottom: 1px solid #e5e5e5; background: #f9f9f9;">
                                <div style="display: flex; justify-content: space-between; align-items: center;">
                                    <div>
                                        <strong><?php echo esc_html( $rule['rule_name'] ); ?></strong>
                                        <span class="botfend-rule-badge <?php echo esc_attr( str_replace( '_', '-', $rule['action'] ) ); ?>" style="margin-left: 10px;">
                                            <?php echo esc_html( ucfirst( str_replace( '_', ' ', $rule['action'] ) ) ); ?>
                                        </span>
                                        <span style="margin-left: 10px; font-size: 12px; color: #646970;">
                                            <?php
                                            printf(
                                                esc_html__( '%1$d / %2$d IPs', 'botfend-anti-bot-firewall' ),
                                                count( $rule['ips'] ),
                                                absint( $status['max_ips_per_rule'] )
                                            );
                                            ?>
                                        </span>
                                    </div>
                                    <button type="button" class="button button-small botfend-delete-rule" data-rule-id="<?php echo esc_attr( $rule['rule_id'] ); ?>" data-rule-name="<?php echo esc_attr( $rule['rule_name'] ); ?>">
                                        <span class="dashicons dashicons-trash"></span>
                                        <?php esc_html_e( 'Delete Rule', 'botfend-anti-bot-firewall' ); ?>
                                    </button>
                                </div>
                                <div style="font-size: 11px; color: #8c8f94; margin-top: 5px;">
                                    <?php
                                    printf(
                                        esc_html__( 'Score range: %1$d - %2$d', 'botfend-anti-bot-firewall' ),
                                        absint( $rule['min_score'] ),
                                        absint( $rule['max_score'] )
                                    );
                                    ?>
                                    <span style="margin-left: 15px;">
                                        <?php
                                        printf(
                                            esc_html__( 'Created: %s', 'botfend-anti-bot-firewall' ),
                                            esc_html( $rule['created_at'] )
                                        );
                                        ?>
                                    </span>
                                </div>
                            </div>
                            <div style="padding: 15px;">
                                <?php if ( empty( $rule['ips'] ) ) : ?>
                                    <p style="color: #8c8f94; font-style: italic;"><?php esc_html_e( 'No IPs in this rule.', 'botfend-anti-bot-firewall' ); ?></p>
                                <?php else : ?>
                                    <div class="botfend-mobile-table">
                                        <table class="wp-list-table widefat fixed striped">
                                            <thead>
                                                <tr>
                                                    <th width="25%"><?php esc_html_e( 'IP Address', 'botfend-anti-bot-firewall' ); ?></th>
                                                    <th width="10%"><?php esc_html_e( 'Score', 'botfend-anti-bot-firewall' ); ?></th>
                                                    <th width="20%"><?php esc_html_e( 'Block Type', 'botfend-anti-bot-firewall' ); ?></th>
                                                    <th width="35%"><?php esc_html_e( 'Reason', 'botfend-anti-bot-firewall' ); ?></th>
                                                    <th width="10%"><?php esc_html_e( 'Expires', 'botfend-anti-bot-firewall' ); ?></th>
                                                    <!-- ACTION COLUMN REMOVED as requested -->
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <?php foreach ( $rule['ips'] as $ip_data ) : ?>
                                                    <tr data-ip="<?php echo esc_attr( $ip_data->ip ); ?>">
                                                        <td><code><?php echo esc_html( $ip_data->ip ); ?></code></td>
                                                        <td>
                                                            <?php
                                                            $score = $ip_data->score;
                                                            $class = $score >= 9 ? 'color: #dc3232; font-weight: bold;' : ( $score >= 7 ? 'color: #f0ad4e; font-weight: bold;' : '' );
                                                            echo '<span style="' . esc_attr( $class ) . '">' . esc_html( $score ) . '</span>';
                                                            ?>
                                                        </td>
                                        <td><?php echo esc_html( $ip_data->block_type ); ?></td>
                                                        <td><?php echo esc_html( substr( $ip_data->block_reason, 0, 60 ) ); ?>…</td>
                                                        <td>
                                                            <?php
                                                            if ( ! empty( $ip_data->expires_at ) ) {
                                                                $expires = get_date_from_gmt( $ip_data->expires_at, 'Y-m-d H:i:s' );
                                                                $expired = strtotime( $ip_data->expires_at ) < time();
                                                                if ( $expired ) {
                                                                    echo '<span style="color: #dc3232;">' . esc_html( $expires ) . ' <em>(' . esc_html__( 'expired', 'botfend-anti-bot-firewall' ) . ')</em></span>';
                                                                } else {
                                                                    echo esc_html( $expires );
                                                                }
                                                            } else {
                                                                echo '<em>' . esc_html__( 'Never', 'botfend-anti-bot-firewall' ) . '</em>';
                                                            }
                                                            ?>
                                                        </td>
                                                    </tr>
                                                <?php endforeach; ?>
                                            </tbody>
                                        </table>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * AJAX: Test connection.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_test_connection(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->api ) {
            $this->init_cloudflare_components();
            if ( ! $this->api ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Cloudflare not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->api->test_connection();

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

        wp_send_json_success( array( 'message' => esc_html__( 'Connection successful!', 'botfend-anti-bot-firewall' ) ) );
    }

    /**
     * AJAX: Sync now.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_sync_now(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->sync ) {
            $this->init_cloudflare_components();
            if ( ! $this->sync ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Sync not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->sync->sync_all_blocked_ips();
        wp_send_json_success( $result );
    }

    /**
     * AJAX: Purge cache.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_purge_cache(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->api ) {
            $this->init_cloudflare_components();
            if ( ! $this->api ) {
                wp_send_json_error( array( 'message' => esc_html__( 'API not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->api->purge_all_cache();

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

        wp_send_json_success( array( 'message' => esc_html__( 'Cache purged successfully!', 'botfend-anti-bot-firewall' ) ) );
    }

    /**
     * AJAX: Get status.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_get_status(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->sync ) {
            $this->init_cloudflare_components();
            if ( ! $this->sync ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Sync not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        wp_send_json_success( $this->sync->get_sync_status() );
    }

    /**
     * AJAX: Remove IP.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_remove_ip(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( empty( $_POST['ip'] ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'IP address required.', 'botfend-anti-bot-firewall' ) ) );
        }

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

        if ( ! $this->sync ) {
            $this->init_cloudflare_components();
            if ( ! $this->sync ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Sync not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->sync->manually_remove_ip( $ip );
        wp_send_json( $result );
    }

    /**
     * AJAX: Delete rule.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_delete_rule(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( empty( $_POST['rule_id'] ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Rule ID required.', 'botfend-anti-bot-firewall' ) ) );
        }

        $rule_id = sanitize_text_field( wp_unslash( $_POST['rule_id'] ) );

        if ( ! $this->sync ) {
            $this->init_cloudflare_components();
            if ( ! $this->sync ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Sync not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->sync->manually_delete_rule( $rule_id );
        wp_send_json( $result );
    }

    /**
     * AJAX: Fix integrity.
     *
     * @since 4.9.0
     *
     * @return void
     */
    public function ajax_fix_integrity(): void {
        check_ajax_referer( self::NONCE_ACTION, 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Insufficient permissions.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->is_pro ) {
            wp_send_json_error( array( 'message' => esc_html__( 'Pro license required for Cloudflare integration.', 'botfend-anti-bot-firewall' ) ) );
        }

        if ( ! $this->sync ) {
            $this->init_cloudflare_components();
            if ( ! $this->sync ) {
                wp_send_json_error( array( 'message' => esc_html__( 'Sync not initialized.', 'botfend-anti-bot-firewall' ) ) );
            }
        }

        $result = $this->sync->fix_sync_integrity();
        wp_send_json_success( $result );
    }
}