<?php

namespace WPSecurityNinja\Plugin;

if (!defined('ABSPATH')) {
    exit;
}

class Wf_Sn_Woo_Protection {
    private static $json_response_sent = false;

    public static function init() {
        // Only proceed if WooCommerce is active
        if ( !class_exists( 'WooCommerce' ) ) {
            return;
        }

        $options = Wf_sn_cf::get_options();
        if (isset( $options['countryblock_loginonly'] ) && ( 1 === intval( $options['countryblock_loginonly'] ) ) ) {
            // Add hooks for WooCommerce login/register forms (display messages)
            add_action( 'woocommerce_login_form_start', array( __CLASS__, 'check_country_restriction' ) );
            add_action( 'woocommerce_register_form_start', array( __CLASS__, 'check_country_restriction' ) );

            // Add hooks to actually intercept login/registration attempts
            add_filter('authenticate', array(__CLASS__, 'intercept_login_attempt'), 30, 3);
            add_filter('woocommerce_process_registration_errors', array(__CLASS__, 'intercept_registration_attempt'), 10, 4);

            // Hook into WooCommerce registration auth to prevent auto-login
            add_filter('woocommerce_registration_auth_new_customer', array(__CLASS__, 'prevent_auto_login_for_restricted_countries'), 10, 2);
        }

        // Rate limiting for WooCommerce actions
        if (self::is_woo_rate_limiting_enabled()) {
            add_action('woocommerce_checkout_process', array(__CLASS__, 'check_checkout_rate_limit'));
            add_action('woocommerce_add_to_cart', array(__CLASS__, 'check_add_to_cart_rate_limit'), 10, 6);
            add_action('woocommerce_after_checkout_validation', array(__CLASS__, 'check_order_rate_limit'), 10, 2);
        }

        // Coupon protection
        if (self::is_woo_coupon_protection_enabled()) {
            
            // Core WooCommerce coupon validation hooks
            add_filter('woocommerce_coupon_is_valid_for_cart', array(__CLASS__, 'check_coupon_brute_force'), 99, 2);
            add_filter('woocommerce_coupon_is_valid', array(__CLASS__, 'check_coupon_brute_force'), 99, 2);
            add_filter('woocommerce_coupon_is_valid_for_product', array(__CLASS__, 'check_coupon_brute_force_for_product'), 99, 4);
            
            // Checkout validation hooks
            add_action('woocommerce_after_checkout_validation', array(__CLASS__, 'check_coupon_attempts'), 10, 2);
            
            // AJAX hooks for traditional forms
            add_action('wp_ajax_woocommerce_apply_coupon', array(__CLASS__, 'check_coupon_attempts_ajax'), 5);
            add_action('wp_ajax_nopriv_woocommerce_apply_coupon', array(__CLASS__, 'check_coupon_attempts_ajax'), 5);
            
            // Success hook to reset counter
            add_action('woocommerce_applied_coupon', array(__CLASS__, 'reset_coupon_attempts'), 10, 1);

            // Hook into all coupon validation attempts
            add_filter('woocommerce_coupon_error', array(__CLASS__, 'check_coupon_error'), 10, 3);
            
            // Store API hooks for blocks
            add_filter('woocommerce_store_api_cart_coupon_errors', array(__CLASS__, 'check_blocks_coupon_errors'), 10, 2);
            add_filter('woocommerce_store_api_cart_apply_coupon', array(__CLASS__, 'check_blocks_coupon_apply'), 10, 2);
            
            // Hook into WooCommerce blocks initialization
            add_action('woocommerce_blocks_loaded', array(__CLASS__, 'init_blocks_protection'));
            
            // Fallback hooks in case blocks_loaded doesn't fire
            add_action('wp_loaded', array(__CLASS__, 'init_blocks_protection'));
            add_action('woocommerce_init', array(__CLASS__, 'init_blocks_protection'));
            
            // Override coupon message when banned
            add_filter('woocommerce_checkout_coupon_message', array(__CLASS__, 'override_coupon_message'), 10);
            
            // Override coupon field HTML output
            add_filter('woocommerce_form_field', array(__CLASS__, 'override_coupon_field_output'),  PHP_INT_MAX - 1, 4);
            
            // Add JavaScript for blocks support
            add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_blocks_js'));
        }
    }



    /**
     * Check if WooCommerce rate limiting is enabled
     */
    private static function is_woo_rate_limiting_enabled()
    {
        $firewall_options = Wf_sn_cf::get_options();
        return !empty($firewall_options['woo_rate_limiting_enabled']);
    }

    /**
     * Check if WooCommerce coupon protection is enabled
     */
    private static function is_woo_coupon_protection_enabled()
    {
        $firewall_options = Wf_sn_cf::get_options();
        return !empty($firewall_options['woo_coupon_protection_enabled']);
    }

    /**
     * Rate limiting for checkout process
     */
    public static function check_checkout_rate_limit()
    {
        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return;
        }

        $firewall_options = Wf_sn_cf::get_options();

        $checkout_limit = $firewall_options['woo_checkout_rate_limit'] ?? 3; // 3 checkouts per window
        $checkout_window = $firewall_options['woo_checkout_window'] ?? 300; // 5 minutes

        // Check if IP is already banned from checkout
        if (get_transient('wf_sn_woo_checkout_banned_' . md5($ip))) {
            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_checkout_blocked', 'Checkout blocked - IP banned', array(
                    'ip' => $ip
                ));
            }

            wc_add_notice(__('Too many checkout attempts. Please wait before trying again.', 'security-ninja'), 'error');
            wp_redirect(wc_get_cart_url());
            exit;
        }

        $transient_key = 'wf_sn_woo_checkout_' . md5($ip);
        $count = (int) get_transient($transient_key);

        if ($count >= $checkout_limit) {
            // Ban the IP for a period
            $ban_time = $firewall_options['woo_checkout_ban_time'] ?? 600; // 10 minutes
            set_transient('wf_sn_woo_checkout_banned_' . md5($ip), 1, $ban_time);

            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_checkout_ip_banned', 'IP banned for checkout rate limit', array(
                    'ip' => $ip,
                    'count' => $count,
                    'limit' => $checkout_limit,
                    'ban_time' => $ban_time
                ));
            }

            wc_add_notice(__('Too many checkout attempts. Please wait before trying again.', 'security-ninja'), 'error');
            wp_redirect(wc_get_cart_url());
            exit;
        }

        $count++;
        set_transient($transient_key, $count, $checkout_window);
    }

    /**
     * Rate limiting for add to cart
     */
    public static function check_add_to_cart_rate_limit($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
    {
        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return;
        }

        $firewall_options = Wf_sn_cf::get_options();

        $add_to_cart_limit = $firewall_options['woo_add_to_cart_limit'] ?? 10; // 10 additions per window
        $add_to_cart_window = $firewall_options['woo_add_to_cart_window'] ?? 60; // 1 minute

        // Check if IP is already banned from add to cart
        if (get_transient('wf_sn_woo_add_to_cart_banned_' . md5($ip))) {
            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_add_to_cart_blocked', 'Add to cart blocked - IP banned', array(
                    'ip' => $ip,
                    'product_id' => $product_id
                ));
            }

            // Remove the item that was just added
            WC()->cart->remove_cart_item($cart_item_key);
            wc_add_notice(__('Too many add to cart attempts. Please wait before trying again.', 'security-ninja'), 'error');
            return;
        }

        $transient_key = 'wf_sn_woo_add_to_cart_' . md5($ip);
        $count = (int) get_transient($transient_key);

        if ($count >= $add_to_cart_limit) {
            // Ban the IP for a period
            $ban_time = $firewall_options['woo_add_to_cart_ban_time'] ?? 300; // 5 minutes
            set_transient('wf_sn_woo_add_to_cart_banned_' . md5($ip), 1, $ban_time);

            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_add_to_cart_ip_banned', 'IP banned for add to cart rate limit', array(
                    'ip' => $ip,
                    'count' => $count,
                    'limit' => $add_to_cart_limit,
                    'ban_time' => $ban_time,
                    'product_id' => $product_id
                ));
            }

            // Remove the item that was just added
            WC()->cart->remove_cart_item($cart_item_key);
            wc_add_notice(__('Too many add to cart attempts. Please wait before trying again.', 'security-ninja'), 'error');
            return;
        }

        $count++;
        set_transient($transient_key, $count, $add_to_cart_window);
    }

    /**
     * Rate limiting for order placement
     */
    public static function check_order_rate_limit($data, $errors)
    {
        if (!empty($errors->errors)) {
            return; // Don't rate limit if there are validation errors
        }

        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return;
        }

        $firewall_options = Wf_sn_cf::get_options();

        $order_limit = $firewall_options['woo_order_rate_limit'] ?? 2; // 2 orders per window
        $order_window = $firewall_options['woo_order_window'] ?? 600; // 10 minutes

        // Check if IP is already banned from order placement
        if (get_transient('wf_sn_woo_order_banned_' . md5($ip))) {
            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_order_blocked', 'Order blocked - IP banned', array(
                    'ip' => $ip
                ));
            }

            $errors->add('rate_limit', __('Too many order attempts. Please wait before trying again.', 'security-ninja'));
            return;
        }

        $transient_key = 'wf_sn_woo_order_' . md5($ip);
        $count = (int) get_transient($transient_key);

        if ($count >= $order_limit) {
            // Ban the IP for a period
            $ban_time = $firewall_options['woo_order_ban_time'] ?? 900; // 15 minutes
            set_transient('wf_sn_woo_order_banned_' . md5($ip), 1, $ban_time);

            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_order_ip_banned', 'IP banned for order rate limit', array(
                    'ip' => $ip,
                    'count' => $count,
                    'limit' => $order_limit,
                    'ban_time' => $ban_time
                ));
            }

            $errors->add('rate_limit', __('Too many order attempts. Please wait before trying again.', 'security-ninja'));
            return;
        }

        $count++;
        set_transient($transient_key, $count, $order_window);
    }

    /**
     * Check if the current user's country is restricted
     */
    public static function check_country_restriction()
    {
        $user_ip = Wf_sn_cf::get_user_ip();
        $options = Wf_sn_cf::get_options();
        $geolocate_ip = \WPSecurityNinja\Plugin\SN_Geolocation::geolocate_ip($user_ip, true);
        $country = isset($geolocate_ip['country']) ? $geolocate_ip['country'] : '';
        if (isset($country) && in_array($country, $options['blocked_countries'])) {
            // Display restriction message
            echo '<div class="woocommerce-info">' .
                esc_html__('Access to this form is restricted in your country.', 'security-ninja') .
                '</div>';

            // Log the attempt
            $data = array(
                'ip' => $user_ip,
                'country' => $country
            );
        }
    }

    /**
     * Intercept WooCommerce login attempts for restricted countries
     * 
     * @param null|WP_User|WP_Error $user
     * @param string $username
     * @param string $password
     * @return null|WP_User|WP_Error
     */
    public static function intercept_login_attempt($user, $username, $password)
    {
        // Only intercept if we don't already have an error and credentials are provided
        if (is_wp_error($user) || empty($username) || empty($password)) {
            return $user;
        }

        // Check if this is a WooCommerce login attempt
        if (!self::is_woocommerce_login_page()) {
            return $user;
        }

        $user_ip = Wf_sn_cf::get_user_ip();
        $options = Wf_sn_cf::get_options();
        $geolocate_ip = \WPSecurityNinja\Plugin\SN_Geolocation::geolocate_ip($user_ip, true);
        $country = isset($geolocate_ip['country']) ? $geolocate_ip['country'] : '';

        if (isset($country) && in_array($country, $options['blocked_countries'])) {
            // Log the blocked attempt
            $data = array(
                'ip' => $user_ip,
                'country' => $country,
                'username' => $username
            );
            \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_login_blocked', 'Blocked WooCommerce login attempt from restricted country', $data);
            return new \WP_Error(
                'country_restricted_login',
                esc_html__('Login is not allowed from your country.', 'security-ninja')
            );
        }

        return $user;
    }

    /**
     * Intercept WooCommerce registration attempts for restricted countries
     * 
     * @param \WP_Error $validation_error
     * @param string $username
     * @param string $password
     * @param string $email
     * @return \WP_Error
     */
    public static function intercept_registration_attempt($validation_error, $username, $password, $email)
    {
        $user_ip = Wf_sn_cf::get_user_ip();
        $options = Wf_sn_cf::get_options();
        $geolocate_ip = \WPSecurityNinja\Plugin\SN_Geolocation::geolocate_ip($user_ip, true);
        $country = isset($geolocate_ip['country']) ? $geolocate_ip['country'] : '';

        if (isset($country) && in_array($country, $options['blocked_countries'])) {
            // Log the blocked attempt
            $data = array(
                'ip' => $user_ip,
                'country' => $country,
                'username' => $username,
                'email' => $email
            );
            \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_registration_blocked', 'Blocked WooCommerce registration attempt from restricted country', $data);

            $validation_error->add(
                'country_restricted_registration',
                esc_html__('Registration is not allowed from your country.', 'security-ninja')
            );
        }

        return $validation_error;
    }

    /**
     * Prevent auto-login after registration for restricted countries
     * 
     * @param bool $auth_new_customer
     * @param int $new_customer_id
     * @return bool
     */
    public static function prevent_auto_login_for_restricted_countries($auth_new_customer, $new_customer_id)
    {
        $user_ip = Wf_sn_cf::get_user_ip();
        $options = Wf_sn_cf::get_options();
        $geolocate_ip = \WPSecurityNinja\Plugin\SN_Geolocation::geolocate_ip($user_ip, true);
        $country = isset($geolocate_ip['country']) ? $geolocate_ip['country'] : '';
        if (isset($country) && in_array($country, $options['blocked_countries'])) {
            // Prevent auto-login for restricted countries
            return false;
        }

        return $auth_new_customer;
    }

    /**
     * Check if the current request is for a WooCommerce login page
     * 
     * @return bool
     */
    private static function is_woocommerce_login_page()
    {
        // Check if we're on WooCommerce my-account page or processing WooCommerce login
        if (function_exists('is_account_page') && is_account_page()) {
            return true;
        }

        // Check if this is a WooCommerce login form submission
        if (isset($_POST['woocommerce-login-nonce']) || isset($_POST['login'])) {
            return true;
        }

        // Check if we're processing WooCommerce login via AJAX or standard form
        if (
            isset($_POST['username']) && isset($_POST['password']) &&
            (strpos($_SERVER['REQUEST_URI'], 'my-account') !== false ||
                strpos($_SERVER['HTTP_REFERER'], 'my-account') !== false)
        ) {
            return true;
        }

        return false;
    }

    /**
     * Check for coupon brute force attempts
     */
    public static function check_coupon_brute_force($is_valid, $coupon)
    {
        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return $is_valid;
        }

        // Ensure we have a valid coupon object with get_code method
        if (!is_object($coupon) || !method_exists($coupon, 'get_code')) {
            return $is_valid;
        }

        // Check if IP is already banned from coupon usage
        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_blocked', 'Coupon attempt blocked - IP banned', array(
                    'ip' => $ip,
                    'coupon_code' => $coupon->get_code()
                ));
            }

            // Return false to indicate invalid coupon, but don't show the actual error
            if (function_exists('wc_add_notice')) {
                wc_add_notice(__('This coupon code is not valid.', 'security-ninja'), 'error');
            }
            return false;
        }

        $firewall_options = Wf_sn_cf::get_options();
        $failed_attempts_limit = $firewall_options['woo_coupon_failed_attempts'] ?? 5;
        $window = $firewall_options['woo_coupon_window'] ?? 300;

        $transient_key = 'wf_sn_woo_coupon_failed_' . md5($ip);
        $failed_count = (int) get_transient($transient_key);

        // Log the attempt
        if (secnin_fs()->can_use_premium_code__premium_only()) {
            $log_data = array(
                'ip' => $ip,
                'coupon_code' => $coupon->get_code(),
                'attempt_count' => $failed_count,
                'limit' => $failed_attempts_limit,
                'is_valid' => $is_valid
            );

            if (!$is_valid) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_failed', 'Failed coupon attempt', $log_data);
            } else {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_success', 'Successful coupon attempt', $log_data);
            }
        }

        if ($is_valid) {
            // Reset failed attempts counter for successful coupons
            if ($failed_count > 0) {
                delete_transient($transient_key);
            }
            return $is_valid;
        } else {
            // Increment failed attempts counter for invalid coupons
            $failed_count++;
            set_transient($transient_key, $failed_count, $window);

            // Check if we should ban this IP
            if ($failed_count >= $failed_attempts_limit) {
                $ban_time = $firewall_options['woo_coupon_ban_time'] ?? 900; // 15 minutes
                set_transient('wf_sn_woo_coupon_banned_' . md5($ip), 1, $ban_time);

                if (secnin_fs()->can_use_premium_code__premium_only()) {
                    \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_ip_banned', 'IP banned for coupon brute force', array(
                        'ip' => $ip,
                        'failed_count' => $failed_count,
                        'ban_time' => $ban_time
                    ));
                }

                // Return false to block the attempt
                if (function_exists('wc_add_notice')) {
                    wc_add_notice(__('Too many invalid coupon attempts. Please wait before trying again.', 'security-ninja'), 'error');
                }
                return false;
            }
        }

        return $is_valid; // Return original validity
    }

    /**
     * Check for coupon brute force attempts (for product-specific validation)
     * This function handles the woocommerce_coupon_is_valid_for_product filter which has 4 parameters
     */
    public static function check_coupon_brute_force_for_product($is_valid, $product, $coupon, $values)
    {
        // For product-specific validation, we still want to check brute force protection
        // but we need to ensure we have a valid coupon object
        if (!is_object($coupon) || !method_exists($coupon, 'get_code')) {
            return $is_valid;
        }

        // Call the main brute force check function
        return self::check_coupon_brute_force($is_valid, $coupon);
    }

    /**
     * Check for coupon brute force attempts
     */
    public static function check_coupon_attempts($data, $errors)
    {
        $ip = Wf_sn_cf::get_user_ip();

        if (!empty($errors->errors)) {
            return; // Don't rate limit if there are validation errors
        }

        // Only check ban status, don't increment counter here
        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            $errors->add('rate_limit', __('Too many coupon attempts. Please wait before trying again.', 'security-ninja'));

            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_rate_limited', 'Coupon rate limited', array(
                    'ip' => $ip
                ));
            }
            return;
        }
    }

    /**
     * Check for coupon brute force attempts during AJAX requests
     */
    public static function check_coupon_attempts_ajax()
    {
        $ip = Wf_sn_cf::get_user_ip();

        // Only check ban status, don't increment counter here
        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_rate_limited', 'Coupon rate limited', array(
                    'ip' => $ip
                ));
            }

            // Send error response safely
            if (!self::$json_response_sent) {
                self::$json_response_sent = true;
                wp_send_json_error(array(
                    'error' => __('Too many coupon attempts. Please wait before trying again.', 'security-ninja')
                ));
            }
        }
    }

    /**
     * Reset coupon brute force attempts when a valid coupon is applied
     */
    public static function reset_coupon_attempts($coupon_code)
    {

        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return;
        }

        $transient_key = 'wf_sn_woo_coupon_failed_' . md5($ip);
        $failed_count = (int) get_transient($transient_key);

        // Reset the failed attempts counter when a valid coupon is applied
        if ($failed_count > 0) {
            delete_transient($transient_key);

            if (secnin_fs()->can_use_premium_code__premium_only()) {
                \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_reset', 'Coupon attempts reset after successful application', array(
                    'ip' => $ip,
                    'coupon_code' => $coupon_code,
                    'previous_failed_count' => $failed_count
                ));
            }
        }
    }



    /**
     * Hook into WooCommerce blocks initialization
     */
    public static function init_blocks_protection()
    {
        static $initialized = false;
        
        if ($initialized) {
            return; // Already initialized
        }
        
        // Add filters for blocks
        add_filter('woocommerce_store_api_cart_coupon_errors', array(__CLASS__, 'check_blocks_coupon_errors'), 10, 2);
        add_filter('woocommerce_store_api_cart_apply_coupon', array(__CLASS__, 'check_blocks_coupon_apply'), 10, 2);
        
        $initialized = true;
    }

    /**
     * Hook into all coupon validation attempts
     */
    public static function check_coupon_error($error, $coupon_code, $coupon)
    {

        $ip = Wf_sn_cf::get_user_ip();

        if (!$ip) {
            return $error;
        }

        // Only increment counter if there's an actual error
        if ($error) {
            $firewall_options = Wf_sn_cf::get_options();
            $failed_attempts_limit = $firewall_options['woo_coupon_failed_attempts'] ?? 5;
            $window = $firewall_options['woo_coupon_window'] ?? 300;

            $transient_key = 'wf_sn_woo_coupon_failed_' . md5($ip);
            $failed_count = (int) get_transient($transient_key);
            $failed_count++;
            set_transient($transient_key, $failed_count, $window);

            // Check if we should ban this IP
            if ($failed_count >= $failed_attempts_limit) {
                $ban_time = $firewall_options['woo_coupon_ban_time'] ?? 900; // 15 minutes
                set_transient('wf_sn_woo_coupon_banned_' . md5($ip), 1, $ban_time);

                if (secnin_fs()->can_use_premium_code__premium_only()) {
                    \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_ip_banned', 'IP banned for coupon errors', array(
                        'ip' => $ip,
                        'failed_count' => $failed_count,
                        'ban_time' => $ban_time,
                        'coupon_code' => $coupon_code
                    ));
                }
                \WPSecurityNinja\Plugin\Wf_sn_cf::kill_request($ip, 'Blocked due to excessive coupon attempts');
                // Reload page to ensure ban takes effect
                // Removed redirect since request is via AJAX
                return __('Too many invalid coupon attempts. Please wait before trying again.', 'security-ninja');
            }
        }

        return $error;
    }

    /**
     * Check blocks coupon errors
     */
    public static function check_blocks_coupon_errors($errors, $coupon_code) {

        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return $errors;
        }

        // Check if IP is banned
        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            $errors[] = __('Too many invalid coupon attempts. Please wait before trying again.', 'security-ninja');
            return $errors;
        }

        // If there are errors, increment failed attempts
        if (!empty($errors)) {
            $firewall_options = Wf_sn_cf::get_options();
            $failed_attempts_limit = $firewall_options['woo_coupon_failed_attempts'] ?? 5;
            $window = $firewall_options['woo_coupon_window'] ?? 300;

            $transient_key = 'wf_sn_woo_coupon_failed_' . md5($ip);
            $failed_count = (int) get_transient($transient_key);
            $failed_count++;
            set_transient($transient_key, $failed_count, $window);

            // Check if we should ban this IP
            if ($failed_count >= $failed_attempts_limit) {
                $ban_time = $firewall_options['woo_coupon_ban_time'] ?? 900; // 15 minutes
                set_transient('wf_sn_woo_coupon_banned_' . md5($ip), 1, $ban_time);

                if (secnin_fs()->can_use_premium_code__premium_only()) {
                    \WPSecurityNinja\Plugin\wf_sn_el_modules::log_event('security_ninja', 'woo_coupon_ip_banned', 'IP banned for blocks coupon errors', array(
                        'ip' => $ip,
                        'failed_count' => $failed_count,
                        'ban_time' => $ban_time,
                        'coupon_code' => $coupon_code
                    ));
                }

                $errors[] = __('Too many invalid coupon attempts. Please wait before trying again.', 'security-ninja');
            }
        }

        return $errors;
    }

    /**
     * Check blocks coupon apply
     */
    public static function check_blocks_coupon_apply($result, $coupon_code)
    {

        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return $result;
        }

        // Check if IP is banned
        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            return new \WP_Error('coupon_banned', __('Too many invalid coupon attempts. Please wait before trying again.', 'security-ninja'));
        }

        return $result;
    }









    /**
     * Override coupon message when banned
     */
    public static function override_coupon_message($message)
    {
        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return $message;
        }

        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            $ban_time = self::get_remaining_ban_time($ip);
            $ban_message = self::get_ban_message_with_duration($ban_time);
            return '<div class="woocommerce-info">' . $ban_message . '</div>';
        }
        return $message;
    }

    /**
     * Get remaining ban time in seconds
     */
    private static function get_remaining_ban_time($ip)
    {
        $transient_key = 'wf_sn_woo_coupon_banned_' . md5($ip);
        $transient_timeout = get_option('_transient_timeout_' . $transient_key);
        
        if (!$transient_timeout) {
            return 0; // No ban active
        }
        
        $remaining_time = $transient_timeout - time();
        return max(0, $remaining_time);
    }

    /**
     * Get ban message with duration
     */
    private static function get_ban_message_with_duration($remaining_seconds)
    {
        if ($remaining_seconds <= 0) {
            return esc_html__('Coupon application is temporarily disabled due to too many invalid attempts. Please wait before trying again.', 'security-ninja');
        }

        $minutes = floor($remaining_seconds / 60);
        $seconds = $remaining_seconds % 60;

        if ($minutes > 0) {
            if ($seconds > 0) {
                return sprintf(
                    esc_html__('Coupon application is temporarily disabled due to too many invalid attempts. Please wait %1$d minutes and %2$d seconds before trying again.', 'security-ninja'),
                    $minutes,
                    $seconds
                );
            } else {
                return sprintf(
                    esc_html__('Coupon application is temporarily disabled due to too many invalid attempts. Please wait %d minutes before trying again.', 'security-ninja'),
                    $minutes
                );
            }
        } else {
            return sprintf(
                esc_html__('Coupon application is temporarily disabled due to too many invalid attempts. Please wait %d seconds before trying again.', 'security-ninja'),
                $seconds
            );
        }
    }

    /**
     * Override coupon field output to show a message instead of input
     */
    public static function override_coupon_field_output($field, $key, $args, $value)
    {
        // Only process coupon-related fields
        if ($key !== 'coupon_code' && $key !== 'apply_coupon') {
            return $field;
        }

        $ip = Wf_sn_cf::get_user_ip();
        if (!$ip) {
            return $field;
        }

        if (get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            $ban_time = self::get_remaining_ban_time($ip);
            $ban_message = self::get_ban_message_with_duration($ban_time);
            return '<div class="woocommerce-info">' . $ban_message . '</div>';
        }
        return $field;
    }

    /**
     * Enqueue JavaScript for blocks support
     */
    public static function enqueue_blocks_js()
    {
        // Only enqueue on pages that might have blocks
        if (!is_cart() && !is_checkout()) {
            return;
        }

        wp_enqueue_script(
            'security-ninja-blocks-coupon',
            plugins_url('js/blocks-coupon.js', __FILE__),
            array('jquery'),
            '1.0.0',
            true
        );
        
        // Add ban status to JavaScript
        $ip = Wf_sn_cf::get_user_ip();
        $is_banned = false;
        $ban_message = '';
        $remaining_time = 0;
        
        if ($ip && get_transient('wf_sn_woo_coupon_banned_' . md5($ip))) {
            $is_banned = true;
            $remaining_time = self::get_remaining_ban_time($ip);
            $ban_message = self::get_ban_message_with_duration($remaining_time);
        }
        
        wp_localize_script('security-ninja-blocks-coupon', 'security_ninja_coupon', array(
            'is_banned' => $is_banned,
            'ban_message' => $ban_message,
            'remaining_time' => $remaining_time
        ));
    }

    /**
     * Get currently banned IPs for WooCommerce protection features
     * 
     * @return array Array of banned IPs with their protection type and expiry times
     */
    public static function get_currently_banned_ips()
    {
        global $wpdb;
        $banned_ips = array();
        
        // Get all transients that match our block prefixes
        $transient_prefixes = array(
            'wf_sn_woo_coupon_banned_' => 'coupon',
            'wf_sn_woo_checkout_banned_' => 'checkout',
            'wf_sn_woo_add_to_cart_banned_' => 'add_to_cart',
            'wf_sn_woo_order_banned_' => 'order'
        );
        
        foreach ($transient_prefixes as $prefix => $type) {
            $transient_prefix = '_transient_' . $prefix;
            $query = $wpdb->prepare(
                "SELECT option_name, option_value FROM {$wpdb->options} 
                WHERE option_name LIKE %s AND option_value != ''",
                $transient_prefix . '%'
            );
            
            $results = $wpdb->get_results($query);
            
            foreach ($results as $row) {
                $ip = str_replace($transient_prefix, '', $row->option_name);
                
                // Get the expiry time from the _transient_timeout_ option
                $timeout_option_name = '_transient_timeout_' . $prefix . $ip;
                $expiry_time = get_option($timeout_option_name);
                
                if ($expiry_time && $expiry_time > time()) {
                    if (!isset($banned_ips[$ip])) {
                        $banned_ips[$ip] = array();
                    }
                    $banned_ips[$ip][$type] = $expiry_time;
                }
            }
        }
        
        return $banned_ips;
    }

    /**
     * Get IPs currently being monitored for WooCommerce protection features
     * 
     * @return array Array of monitored IPs with their current counts and expiry times
     */
    public static function get_monitored_ips()
    {
        global $wpdb;
        $monitored_ips = array();
        
        // Get all transients that match our count prefixes
        $transient_prefixes = array(
            'wf_sn_woo_coupon_failed_' => 'coupon',
            'wf_sn_woo_checkout_' => 'checkout',
            'wf_sn_woo_add_to_cart_' => 'add_to_cart',
            'wf_sn_woo_order_' => 'order'
        );
        
        $firewall_options = Wf_sn_cf::get_options();
        
        foreach ($transient_prefixes as $prefix => $type) {
            $transient_prefix = '_transient_' . $prefix;
            $query = $wpdb->prepare(
                "SELECT option_name, option_value FROM {$wpdb->options} 
                WHERE option_name LIKE %s AND option_value != ''",
                $transient_prefix . '%'
            );
            
            $results = $wpdb->get_results($query);
            
            foreach ($results as $row) {
                $ip = str_replace($transient_prefix, '', $row->option_name);
                $count = (int) $row->option_value;
                
                // Get the appropriate threshold for this type
                $threshold = 0;
                switch ($type) {
                    case 'coupon':
                        $threshold = $firewall_options['woo_coupon_failed_attempts'] ?? 5;
                        break;
                    case 'checkout':
                        $threshold = $firewall_options['woo_checkout_rate_limit'] ?? 3;
                        break;
                    case 'add_to_cart':
                        $threshold = $firewall_options['woo_add_to_cart_limit'] ?? 10;
                        break;
                    case 'order':
                        $threshold = $firewall_options['woo_order_rate_limit'] ?? 2;
                        break;
                }
                
                // Check if this IP is currently banned for this type
                $block_timeout_option = '_transient_timeout_wf_sn_woo_' . $type . '_banned_' . $ip;
                $ban_expiry = get_option($block_timeout_option);
                $is_banned = $ban_expiry && $ban_expiry > time();
                
                // Only include if below threshold and not banned
                if ($count > 0 && $count < $threshold && !$is_banned) {
                    // Get expiry time for this count transient
                    $count_timeout_option = '_transient_timeout_' . $prefix . $ip;
                    $expiry_time = get_option($count_timeout_option);
                    
                    if (!isset($monitored_ips[$ip])) {
                        $monitored_ips[$ip] = array();
                    }
                    $monitored_ips[$ip][$type] = array(
                        'count' => $count,
                        'threshold' => $threshold,
                        'expiry' => $expiry_time
                    );
                }
            }
        }
        
        return $monitored_ips;
    }

    /**
     * Get WooCommerce protection statistics
     * 
     * @return array Array with comprehensive statistics
     */
    public static function get_statistics()
    {
        $banned_ips = self::get_currently_banned_ips();
        $monitored_ips = self::get_monitored_ips();
        
        // Get IPs expiring soon (within next 5 minutes)
        $expiring_soon = array();
        $current_time = time();
        $five_minutes = 5 * 60;
        
        foreach ($banned_ips as $ip => $ban_types) {
            foreach ($ban_types as $type => $expiry_time) {
                $time_until_expiry = $expiry_time - $current_time;
                if ($time_until_expiry <= $five_minutes && $time_until_expiry > 0) {
                    if (!isset($expiring_soon[$ip])) {
                        $expiring_soon[$ip] = array();
                    }
                    $expiring_soon[$ip][$type] = $time_until_expiry;
                }
            }
        }
        
        // Sort expiring soon by time remaining (closest to expiring first)
        uasort($expiring_soon, function($a, $b) {
            $min_a = min(array_values($a));
            $min_b = min(array_values($b));
            return $min_a <=> $min_b;
        });
        // Limit to top 5
        $expiring_soon = array_slice($expiring_soon, 0, 5, true);

        // Get the 5 oldest monitored IPs (closest to expiry)
        $oldest_monitored = $monitored_ips;
        // Remove any with no expiry (shouldn't happen, but just in case)
        $oldest_monitored = array_filter($oldest_monitored, function($item) { 
            return !empty($item) && is_array($item); 
        });
        // Sort by expiry ascending (oldest first)
        uasort($oldest_monitored, function($a, $b) { 
            $min_a = min(array_column($a, 'expiry'));
            $min_b = min(array_column($b, 'expiry'));
            return $min_a <=> $min_b; 
        });
        $oldest_monitored = array_slice($oldest_monitored, 0, 5, true);

        // Get recent WooCommerce protection events count (last 24 hours)
        $recent_events_count = self::get_recent_events_count();
        
        // Get all-time statistics
        $all_time_stats = self::get_all_time_statistics();
        
        return array(
            'banned_count' => count($banned_ips),
            'monitored_count' => count($monitored_ips),
            'expiring_soon_ips' => $expiring_soon,
            'oldest_monitored_ips' => $oldest_monitored,
            'recent_events_count' => $recent_events_count,
            'all_time_stats' => $all_time_stats
        );
    }

    /**
     * Get count of recent WooCommerce protection events (last 24 hours)
     * 
     * @return array Array with counts for different event types
     */
    public static function get_recent_events_count()
    {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'wf_sn_el';
        $event_types = array(
            'woo_checkout_rate_limited',
            'woo_checkout_ip_banned',
            'woo_checkout_blocked',
            'woo_add_to_cart_rate_limited',
            'woo_add_to_cart_ip_banned',
            'woo_add_to_cart_blocked',
            'woo_order_rate_limited',
            'woo_order_ip_banned',
            'woo_order_blocked',
            'woo_coupon_failed',
            'woo_coupon_success',
            'woo_coupon_ip_banned',
            'woo_coupon_blocked',
            'woo_coupon_rate_limited',
            'woo_coupon_reset',
            'woo_login_blocked',
            'woo_registration_blocked'
        );
        
        $placeholders = implode(',', array_fill(0, count($event_types), '%s'));
        $query = $wpdb->prepare(
            "SELECT action, COUNT(*) as count FROM {$table_name} 
            WHERE module = %s AND action IN ({$placeholders}) 
            AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
            GROUP BY action",
            array_merge(array('security_ninja'), $event_types)
        );
        
        $results = $wpdb->get_results($query);
        $counts = array();
        
        foreach ($event_types as $event_type) {
            $counts[$event_type] = 0;
        }
        
        foreach ($results as $row) {
            $counts[$row->action] = (int) $row->count;
        }
        
        return $counts;
    }

    /**
     * Get all-time statistics for WooCommerce protection
     * 
     * @return array Array with all-time statistics
     */
    public static function get_all_time_statistics()
    {
        global $wpdb;
        
        $table_name = $wpdb->prefix . 'wf_sn_el';
        $event_types = array(
            'woo_checkout_rate_limited',
            'woo_checkout_ip_banned',
            'woo_checkout_blocked',
            'woo_add_to_cart_rate_limited',
            'woo_add_to_cart_ip_banned',
            'woo_add_to_cart_blocked',
            'woo_order_rate_limited',
            'woo_order_ip_banned',
            'woo_order_blocked',
            'woo_coupon_failed',
            'woo_coupon_success',
            'woo_coupon_ip_banned',
            'woo_coupon_blocked',
            'woo_coupon_rate_limited',
            'woo_coupon_reset',
            'woo_login_blocked',
            'woo_registration_blocked'
        );
        
        $placeholders = implode(',', array_fill(0, count($event_types), '%s'));
        $query = $wpdb->prepare(
            "SELECT action, COUNT(*) as count FROM {$table_name} 
            WHERE module = %s AND action IN ({$placeholders})
            GROUP BY action",
            array_merge(array('security_ninja'), $event_types)
        );
        
        $results = $wpdb->get_results($query);
        $counts = array();
        
        foreach ($event_types as $event_type) {
            $counts[$event_type] = 0;
        }
        
        foreach ($results as $row) {
            $counts[$row->action] = (int) $row->count;
        }
        
        // Calculate totals by category
        $totals = array(
            'total_rate_limited' => $counts['woo_checkout_rate_limited'] + $counts['woo_add_to_cart_rate_limited'] + $counts['woo_order_rate_limited'],
            'total_coupon_events' => $counts['woo_coupon_failed'] + $counts['woo_coupon_success'] + $counts['woo_coupon_ip_banned'] + $counts['woo_coupon_blocked'] + $counts['woo_coupon_rate_limited'] + $counts['woo_coupon_reset'],
            'total_auth_blocked' => $counts['woo_login_blocked'] + $counts['woo_registration_blocked'],
            'total_events' => array_sum($counts)
        );
        
        return array_merge($counts, $totals);
    }

    /**
     * Format time remaining in human readable format
     * 
     * @param int $seconds Seconds remaining
     * @return string Formatted time string
     */
    public static function format_time_remaining($seconds)
    {
        if ($seconds < 60) {
            return sprintf(_n('%d second', '%d seconds', $seconds, 'security-ninja'), $seconds);
        } elseif ($seconds < 3600) {
            $minutes = floor($seconds / 60);
            return sprintf(_n('%d minute', '%d minutes', $minutes, 'security-ninja'), $minutes);
        } else {
            $hours = floor($seconds / 3600);
            return sprintf(_n('%d hour', '%d hours', $hours, 'security-ninja'), $hours);
        }
    }

    /**
     * Check if WooCommerce protection is loaded and enabled
     * This can be called from other parts of the system
     */
    public static function is_loaded_and_enabled()
    {
        return class_exists(__CLASS__) && (self::is_woo_rate_limiting_enabled() || self::is_woo_coupon_protection_enabled());
    }

    /**
     * Load WooCommerce protection on demand
     * This can be called from other parts of the system if needed
     */
    public static function load_on_demand()
    {
        if (!class_exists(__CLASS__)) {
            require_once WF_SN_PLUGIN_DIR . 'modules/woocommerce/class-wf-sn-woo-protection.php';
        }
        if (!self::is_loaded_and_enabled()) {
            return false;
        }
        return true;
    }


}

// Initialize the class
add_action('init', array('WPSecurityNinja\Plugin\Wf_Sn_Woo_Protection', 'init'));
