<?php
/**
 * Threat Intelligence Feed Integration for BotFend Anti-Bot Firewall
 *
 * @package BotFend\Detection
 * @since 4.4.2 - Fixed Cron scheduling, stale feed detection, and lock timeouts
 * @version 4.8.3 - External feeds disabled by default, rebranded from SafeBot
 */

namespace BotFend\Detection;

use BotFend\Core\Config;
use WP_Error;

defined('ABSPATH') || exit;

/**
 * Class ThreatIntel
 *
 * Provides IP-based threat intelligence using curated, high-reliability feeds.
 * Only includes feeds that are effective for IP blocking.
 * 
 * IMPORTANT: All external feeds are DISABLED BY DEFAULT. Users must explicitly
 * opt-in to enable threat intelligence features.
 */
class ThreatIntel {
    
    private static $instance = null;
    private $config;
    private $feeds = [];
    
    const CACHE_TIME = HOUR_IN_SECONDS;
    const MAX_FEED_SIZE = 26214400; // Increased to 25MB limit to prevent silent failures
    const MIN_RELIABILITY_SCORE = 30;
    const MAX_FAILURE_COUNT = 3;
    const PLUGIN_CREATED = 1734652800; // Dec 20, 2025
    
    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        $this->config = Config::get_instance();
        
        // Threat intel is DISABLED BY DEFAULT (opt-in required)
        if ($this->is_enabled()) {
            $this->load_feeds_config();
            $this->schedule_preload();
            
            // FIX 1: Ensure schedule is registered on init
            add_action('init', [__CLASS__, 'register_schedule']);
            
            // Register standard hooks
            add_action('botfend_update_threat_feeds', [$this, 'update_feeds']);
            add_action('botfend_preload_threat_feeds', [$this, 'preload_intel_data']);
            
            // FIX 2 & 3: Run on admin init to catch stale data
            add_action('admin_init', [$this, 'maybe_update_stale_feeds']);
            
            // FIX 6: AJAX Handler for manual force update
            add_action('wp_ajax_botfend_force_update_threat_feeds', [__CLASS__, 'ajax_force_update_feeds']);
        }
    }
    
    public static function register_schedule() {
        if (!wp_next_scheduled('botfend_update_threat_feeds')) {
            wp_schedule_event(time(), 'hourly', 'botfend_update_threat_feeds');
        }
    }
    
    public static function clear_schedule() {
        wp_clear_scheduled_hook('botfend_update_threat_feeds');
        wp_clear_scheduled_hook('botfend_preload_threat_feeds');
    }
    
    /**
     * Check if threat intelligence is enabled
     * DISABLED BY DEFAULT - requires explicit user opt-in
     *
     * @return bool
     */
    private function is_enabled() {
        return $this->config->get_bool('enable_threat_intel', false);
    }
    
    private function load_feeds_config() {
        $this->feeds = [
            'blocklist_de' => [
                'url' => 'https://lists.blocklist.de/lists/all.txt',
                'type' => 'ip',
                'weight' => $this->config->get_int('feed_weight_blocklist_de', 8),
                'enabled' => $this->config->get_bool('threat_feed_blocklist_de', false),
                'name' => esc_html__('Blocklist.de', 'botfend-anti-bot-firewall'),
                'description' => esc_html__('Aggregated blocklist from various sources', 'botfend-anti-bot-firewall'),
                'update_frequency' => 'hourly',
            ],
            'firehol_level1' => [
                'url' => 'https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset',
                'type' => 'cidr',
                'weight' => $this->config->get_int('feed_weight_firehol_level1', 9),
                'enabled' => $this->config->get_bool('threat_feed_firehol_level1', false),
                'name' => esc_html__('FireHOL Level 1', 'botfend-anti-bot-firewall'),
                'description' => esc_html__('Active attackers and malware distribution', 'botfend-anti-bot-firewall'),
                'update_frequency' => 'hourly',
            ],
            'emerging_threats' => [
                'url' => 'https://rules.emergingthreats.net/blockrules/compromised-ips.txt',
                'type' => 'ip',
                'weight' => $this->config->get_int('feed_weight_emerging_threats', 7),
                'enabled' => $this->config->get_bool('threat_feed_emerging_threats', false),
                'name' => esc_html__('Emerging Threats', 'botfend-anti-bot-firewall'),
                'description' => esc_html__('Compromised IP addresses', 'botfend-anti-bot-firewall'),
                'update_frequency' => 'twicedaily',
            ],
        ];
        
        if ($this->config->get_bool('feed_auto_optimization', false)) {
            $this->apply_feed_optimization();
        }
    }
    
    private function schedule_preload() {
        // Removed is_admin() check so it can run in the backend
        if (wp_doing_ajax() || wp_doing_cron()) {
            return;
        }
        
        add_action('shutdown', [$this, 'preload_intel_data_async'], 5);
    }
    
    public function preload_intel_data_async() {
        if (!wp_next_scheduled('botfend_preload_threat_feeds')) {
            wp_schedule_single_event(time() + 2, 'botfend_preload_threat_feeds');
        }
    }
    
    /**
     * Check for stale feeds and update if needed
     */
    public function maybe_update_stale_feeds(): void {
        // Only check occasionally (1% of admin requests) to prevent backend slowdowns
        if (wp_rand(1, 100) > 1) {
            return;
        }
        
        $last_update = get_option('botfend_threat_intel_last_timestamp', 0);
        $stale_threshold = 6 * HOUR_IN_SECONDS; // 6 hours
        
        if (time() - $last_update > $stale_threshold) {
            // Run update in background
            if (!wp_next_scheduled('botfend_update_threat_feeds')) {
                wp_schedule_single_event(time() + 5, 'botfend_update_threat_feeds');
            }
        }
    }
    
    public function preload_intel_data() {
        // Don't run if threat intel is disabled
        if (!$this->is_enabled()) {
            return;
        }
        
        $lock_key = 'botfend_threat_intel_preload_lock';
        
        // FIX 4: Prevent the lock from getting permanently stuck
        $lock_time = get_transient($lock_key);
        if ($lock_time && (time() - (int)$lock_time) < 60) {
            return; // Only block if lock is fresh (< 60 seconds)
        }
        
        // If lock is missing or stale, set/override it
        set_transient($lock_key, time(), 300);
        
        foreach ($this->feeds as $feed_name => $feed_config) {
            if (!$feed_config['enabled']) {
                continue;
            }
            
            $last_update_key = 'botfend_feed_time_' . sanitize_key($feed_name);
            $last_update = get_option($last_update_key, false);
            
            if ($this->should_update_feed($feed_name, $last_update)) {
                $this->update_single_feed($feed_name, $feed_config);
            }
        }
        
        delete_transient($lock_key);
    }
    
    private function should_update_feed($feed_name, $last_update) {
        if (false === $last_update) {
            return true;
        }
        
        $config = $this->feeds[$feed_name] ?? null;
        if (!$config) {
            return false;
        }
        
        $intervals = [
            'hourly' => HOUR_IN_SECONDS,
            'twicedaily' => 12 * HOUR_IN_SECONDS,
            'daily' => DAY_IN_SECONDS,
        ];
        
        $interval = $intervals[$config['update_frequency']] ?? HOUR_IN_SECONDS;
        return (time() - (int)$last_update) > $interval;
    }
    
    private function get_feed_cache_key($feed_name) {
        return 'botfend_threat_feed_' . sanitize_key($feed_name);
    }
    
    private function update_single_feed($feed_name, $config) {
        $start = microtime(true);
        $data = $this->fetch_feed($config['url'], $config['type']);
        $duration = microtime(true) - $start;
        
        if ($data && !empty($data)) {
            return $this->store_feed_data($feed_name, $data, $duration);
        }
        
        $this->handle_feed_failure($feed_name, $duration);
        return false;
    }
    
    private function store_feed_data($feed_name, $data, $response_time) {
        $key = sanitize_key($feed_name);
        $cache_key = $this->get_feed_cache_key($feed_name);
        $timestamp = time();
        
        foreach ($data as &$entry) {
            $entry = trim($entry);
            $entry = preg_replace('/[\x00-\x1F\x7F]/', '', $entry);
            $entry = preg_replace('/\s+#.*$/', '', $entry);
            $entry = sanitize_text_field(trim($entry));
        }
        $sanitized = array_unique(array_filter($data));
        
        set_transient($cache_key, $sanitized, self::CACHE_TIME);
        
        update_option('botfend_feed_time_' . $key, $timestamp, false);
        update_option("botfend_threat_feed_{$key}_count", count($sanitized), false);
        update_option("botfend_threat_feed_{$key}_updated", current_time('mysql', true), false);
        update_option("botfend_threat_feed_{$key}_timestamp", $timestamp, false);
        update_option("botfend_threat_feed_{$key}_initialized", true, false);
        
        $this->track_performance($feed_name, true, $response_time, count($sanitized));
        update_option("botfend_feed_{$key}_failure_count", 0, false);
        
        return true;
    }
    
    private function handle_feed_failure($feed_name, $response_time) {
        $this->track_performance($feed_name, false, $response_time, 0);
        
        $key = sanitize_key($feed_name);
        $failures = (int) get_option("botfend_feed_{$key}_failure_count", 0) + 1;
        update_option("botfend_feed_{$key}_failure_count", $failures, false);
        
        if (defined('WP_DEBUG') && WP_DEBUG && $this->config->get_bool('debug_mode', false)) {
            error_log(sprintf('BotFend: Failed to fetch feed: %s', $feed_name));
        }
    }
    
    private function apply_feed_optimization() {
        $stats = get_option('botfend_feed_performance_stats', []);
        
        foreach ($this->feeds as $name => &$config) {
            $key = sanitize_key($name);
            $perf = $stats[$key] ?? null;
            
            if (!$perf) continue;
            
            $reliability = $perf['reliability_score'] ?? 0;
            
            if ($reliability > 80) {
                $config['weight'] = min(10, $config['weight'] + 1);
            } elseif ($reliability < 50) {
                $config['weight'] = max(1, $config['weight'] - 1);
            }
            
            if ($reliability < self::MIN_RELIABILITY_SCORE && $config['enabled']) {
                $failures = (int) get_option("botfend_feed_{$key}_failure_count", 0);
                if ($failures >= self::MAX_FAILURE_COUNT) {
                    $config['enabled'] = false;
                    $this->config->set("threat_feed_{$name}", '0');
                }
            }
        }
    }
    
    /**
     * Check IP against threat intelligence feeds
     * Returns empty result if threat intel is disabled (default)
     *
     * @param string $ip
     * @return array
     */
    public function check_ip($ip) {
        // CRITICAL: Threat intel is DISABLED BY DEFAULT
        if (!$this->is_enabled()) {
            return $this->empty_result(esc_html__('Threat intelligence is disabled', 'botfend-anti-bot-firewall'));
        }
        
        if (!$this->is_valid_ip($ip)) {
            return $this->empty_result(
                esc_html__('Invalid IP address', 'botfend-anti-bot-firewall'),
                true,
                'invalid_ip'
            );
        }
        
        $score = 0;
        $matched = [];
        $details = [];
        
        foreach ($this->feeds as $name => $config) {
            if (!$config['enabled']) continue;
            
            $cache_key = $this->get_feed_cache_key($name);
            $data = get_transient($cache_key);
            
            if ($data && $this->ip_matches_feed($ip, $data, $config['type'])) {
                $score += absint($config['weight']);
                $matched[] = $name;
                $details[$name] = [
                    'name' => $config['name'],
                    'weight' => absint($config['weight']),
                    'description' => $config['description'],
                    'category' => $config['type'],
                ];
            }
        }
        
        $result = [
            'score' => min(100, $score),
            'sources' => $matched,
            'feed_details' => $details,
            'threat_level' => $this->calculate_threat_level($score),
            'enabled' => true,
            'timestamp' => time(),
            'ip' => $ip,
        ];
        
        if ($this->config->get_bool('enable_threat_correlation', true) && !empty($matched)) {
            $result = $this->correlate_threats($ip, $result);
        }
        
        return $result;
    }
    
    private function empty_result($message = '', $enabled = false, $error = '') {
        $result = [
            'score' => 0,
            'sources' => [],
            'feed_details' => [],
            'threat_level' => 'none',
            'enabled' => $enabled,
            'timestamp' => time(),
        ];
        
        if ($message) $result['message'] = $message;
        if ($error) $result['error'] = $error;
        
        return $result;
    }
    
    private function is_valid_ip($ip) {
        if (empty($ip) || !is_string($ip)) return false;
        
        $dangerous = ['--', ';', '/*', '*/', 'UNION', 'SELECT', 'INSERT', 'DELETE', 'UPDATE', 'DROP', 'SCRIPT', 'JAVASCRIPT', '<', '>', '&#', '\\x', '0x'];
        $upper = strtoupper($ip);
        foreach ($dangerous as $pattern) {
            if (strpos($upper, $pattern) !== false) return false;
        }
        
        return filter_var($ip, FILTER_VALIDATE_IP) !== false;
    }
    
    private function fetch_feed($url, $type) {
        $args = [
            'timeout' => 45, // INCREASED to prevent timeouts on large files
            // Changed User-Agent to standard browser format to prevent GitHub/Feed blocking
            'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sslverify' => true,
            'redirection' => 3,
            'headers' => [
                'Accept' => 'text/plain,text/csv',
                'Cache-Control' => 'no-cache',
            ],
        ];
        
        $response = wp_safe_remote_get($url, $args);
        
        if (is_wp_error($response)) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('BotFend ThreatIntel Connection Error: ' . $response->get_error_message() . ' for URL: ' . $url);
            }
            $args['sslverify'] = false;
            $response = wp_safe_remote_get($url, $args);
            if (is_wp_error($response)) return [];
        }
        
        $code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        $body_size = strlen($body);
        
        if (200 !== $code) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log("BotFend ThreatIntel Error: HTTP $code for URL: $url");
            }
            return [];
        }
        
        if ($body_size > self::MAX_FEED_SIZE) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log("BotFend ThreatIntel Error: Feed too large ($body_size bytes) for URL: $url");
            }
            return [];
        }
        
        if (empty($body)) {
            return [];
        }
        
        return match ($type) {
            'ip' => $this->parse_ip_list($body),
            'cidr' => $this->parse_cidr_list($body),
            default => $this->parse_generic_list($body),
        };
    }
    
    private function parse_generic_list($content) {
        $entries = [];
        foreach (explode("\n", $content) as $line) {
            $line = trim($line);
            if (empty($line) || strpos($line, '#') === 0) continue;
            
            $entry = preg_replace('/[\x00-\x1F\x7F]/', '', $line);
            $entry = preg_replace('/\s+#.*$/', '', $entry);
            $entry = sanitize_text_field(trim($entry));
            
            if (!empty($entry)) $entries[] = $entry;
        }
        return $entries;
    }
    
    private function parse_ip_list($content) {
        $ips = [];
        foreach (explode("\n", $content) as $line) {
            $line = trim($line);
            if (empty($line) || strpos($line, '#') === 0) continue;
            
            $parts = preg_split('/\s+/', $line, 2);
            $ip = trim($parts[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                $ips[] = $ip;
            }
        }
        return $ips;
    }
    
    private function parse_cidr_list($content) {
        $cidrs = [];
        foreach (explode("\n", $content) as $line) {
            $line = trim($line);
            if (empty($line) || strpos($line, '#') === 0) continue;
            
            $parts = preg_split('/\s+/', $line, 2);
            $cidr = trim($parts[0]);
            
            if (strpos($cidr, '/') !== false) {
                list($ip, $mask) = explode('/', $cidr, 2);
                $mask = absint($mask);
                if (filter_var($ip, FILTER_VALIDATE_IP) && $mask >= 0 && $mask <= 128) {
                    $cidrs[] = $cidr;
                }
            }
        }
        return $cidrs;
    }
    
    private function ip_matches_feed($ip, $data, $type) {
        if (empty($data)) return false;
        
        if ('cidr' === $type) {
            foreach ($data as $cidr) {
                if ($this->ip_in_cidr($ip, $cidr)) return true;
            }
            return false;
        }
        
        return in_array($ip, $data, true);
    }
    
    private function ip_in_cidr($ip, $cidr) {
        if (strpos($cidr, '/') === false) return false;
        
        list($subnet, $bits) = explode('/', $cidr, 2);
        $bits = absint($bits);
        
        if ($bits < 0 || $bits > 128) return false;
        
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            if ($bits > 32) return false;
            $ip_long = ip2long($ip);
            $subnet_long = ip2long($subnet);
            if (false === $ip_long || false === $subnet_long) return false;
            $mask = -1 << (32 - $bits);
            return ($ip_long & $mask) === ($subnet_long & $mask);
        }
        
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
            $ip_bin = inet_pton($ip);
            $subnet_bin = inet_pton($subnet);
            if (false === $ip_bin || false === $subnet_bin) return false;
            $bytes = (int) ceil($bits / 8);
            return substr($ip_bin, 0, $bytes) === substr($subnet_bin, 0, $bytes);
        }
        
        return false;
    }
    
    private function calculate_threat_level($score) {
        if ($score >= 20) return 'critical';
        if ($score >= 15) return 'high';
        if ($score >= 8) return 'medium';
        if ($score >= 3) return 'low';
        return 'none';
    }
    
    private function track_performance($feed_name, $success, $response_time, $entry_count) {
        if (!$this->config->get_bool('feed_performance_tracking', false)) return;
        
        $key = sanitize_key($feed_name);
        $stats = get_option('botfend_feed_performance_stats', []);
        
        if (!isset($stats[$key])) {
            $stats[$key] = [
                'total_requests' => 0,
                'successful_requests' => 0,
                'total_response_time' => 0,
                'average_response_time' => 0,
                'reliability_score' => 0,
                'last_updated' => current_time('mysql'),
            ];
        }
        
        $stats[$key]['total_requests']++;
        
        if ($success) {
            $stats[$key]['successful_requests']++;
            $stats[$key]['total_response_time'] += $response_time;
            $stats[$key]['average_response_time'] = $stats[$key]['total_response_time'] / $stats[$key]['successful_requests'];
            $stats[$key]['last_success'] = current_time('mysql');
            $stats[$key]['last_entry_count'] = $entry_count;
        } else {
            $stats[$key]['last_failure'] = current_time('mysql');
        }
        
        if ($stats[$key]['total_requests'] > 0) {
            $stats[$key]['reliability_score'] = ($stats[$key]['successful_requests'] / $stats[$key]['total_requests']) * 100;
        }
        
        update_option('botfend_feed_performance_stats', $stats, false);
    }
    
    private function correlate_threats($ip, $result) {
        return $result;
    }
    
    public function get_feed_status() {
        $status = [];
        $plugin_created = defined('BOTFEND_PLUGIN_CREATED') ? BOTFEND_PLUGIN_CREATED : self::PLUGIN_CREATED;
        
        foreach ($this->feeds as $name => $config) {
            $key = sanitize_key($name);
            $timestamp = absint(get_option("botfend_threat_feed_{$key}_timestamp", 0));
            
            if ($timestamp <= 0 || $timestamp < $plugin_created || $timestamp > time() + DAY_IN_SECONDS) {
                $cache_time = get_option('botfend_feed_time_' . $key, false);
                if ($cache_time && $cache_time > $plugin_created) {
                    $timestamp = absint($cache_time);
                    update_option("botfend_threat_feed_{$key}_timestamp", $timestamp, false);
                } else {
                    $timestamp = time();
                }
            }
            
            $display_time = ($timestamp > 0 && $timestamp > $plugin_created)
                ? gmdate('Y-m-d H:i:s', $timestamp)
                : esc_html__('Never', 'botfend-anti-bot-firewall');
            
            $human_time = ($timestamp > 0 && $timestamp > $plugin_created)
                ? human_time_diff($timestamp, time()) . ' ' . esc_html__('ago', 'botfend-anti-bot-firewall')
                : '';
            
            $count = absint(get_option("botfend_threat_feed_{$key}_count", 0));
            $has_data = get_transient($this->get_feed_cache_key($name)) !== false || $count > 0;
            
            $perf = (get_option('botfend_feed_performance_stats', []))[$key] ?? null;
            
            $status[] = [
                'id' => $key,
                'name' => $config['name'],
                'enabled' => (bool) $config['enabled'],
                'last_updated' => $display_time,
                'last_updated_human' => $human_time,
                'entry_count' => $count,
                'weight' => absint($config['weight']),
                'description' => $config['description'],
                'type' => $config['type'],
                'has_data' => $has_data,
                'timestamp' => $timestamp,
                'reliability_score' => $perf['reliability_score'] ?? 0,
                'update_frequency' => $config['update_frequency'],
            ];
        }
        
        usort($status, function($a, $b) {
            return strcmp($a['name'], $b['name']);
        });
        
        return $status;
    }
    
    public function update_feeds() {
        // CRITICAL: Threat intel is DISABLED BY DEFAULT
        if (!$this->is_enabled()) {
            return ['success' => false, 'message' => esc_html__('Threat intelligence is disabled', 'botfend-anti-bot-firewall')];
        }
        
        $updated = 0;
        $failed = 0;
        
        foreach ($this->feeds as $name => $config) {
            if (!$config['enabled']) continue;
            
            if ($this->update_single_feed($name, $config)) {
                $updated++;
            } else {
                $failed++;
            }
        }
        
        if ($updated > 0) {
            update_option('botfend_threat_intel_last_update', current_time('mysql', true), false);
            update_option('botfend_threat_intel_last_timestamp', time(), false);
        }
        
        return [
            'success' => $updated > 0,
            'updated' => $updated,
            'failed' => $failed,
            'total' => $updated + $failed,
            'message' => esc_html(sprintf(
                _n(
                    'Updated %d feed, failed %d',
                    'Updated %d feeds, failed %d',
                    $updated + $failed,
                    'botfend-anti-bot-firewall'
                ),
                $updated,
                $failed
            )),
        ];
    }
    
    public function force_update_feeds() {
        foreach ($this->feeds as $name => $config) {
            $key = $this->get_feed_cache_key($name);
            delete_transient($key);
            delete_option('botfend_feed_time_' . sanitize_key($name));
        }
        return $this->update_feeds();
    }
    
    /**
     * AJAX handler to force update threat feeds
     */
    public static function ajax_force_update_feeds(): void {
        check_ajax_referer('botfend_threat_feeds', 'nonce');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => __('Insufficient permissions.', 'botfend-anti-bot-firewall')]);
        }
        
        $instance = self::get_instance();
        $result = $instance->force_update_feeds();
        
        // Add the last update time to the response
        if ($result['success']) {
            $result['last_update'] = get_option('botfend_threat_intel_last_update', current_time('mysql'));
        }
        
        wp_send_json_success($result);
    }
    
    public function reset_feeds() {
        $results = [];
        
        foreach ($this->feeds as $name => $config) {
            $key = sanitize_key($name);
            $cache_key = $this->get_feed_cache_key($name);
            
            delete_transient($cache_key);
            delete_option('botfend_feed_time_' . $key);
            delete_option("botfend_threat_feed_{$key}_count");
            delete_option("botfend_threat_feed_{$key}_updated");
            delete_option("botfend_threat_feed_{$key}_timestamp");
            delete_option("botfend_threat_feed_{$key}_initialized");
            
            $results[$name] = 'reset';
        }
        
        delete_option('botfend_feed_performance_stats');
        delete_option('botfend_threat_intel_last_update');
        delete_option('botfend_threat_intel_last_timestamp');
        
        return [
            'success' => true,
            'message' => esc_html__('All feed data has been reset', 'botfend-anti-bot-firewall'),
            'results' => $results
        ];
    }
    
    public function get_feed_statistics() {
        $stats = [];
        $total_entries = 0;
        $enabled_count = 0;
        
        foreach ($this->feeds as $name => $config) {
            if (!$config['enabled']) continue;
            
            $key = sanitize_key($name);
            $count = absint(get_option("botfend_threat_feed_{$key}_count", 0));
            $updated = get_option("botfend_threat_feed_{$key}_updated", esc_html__('Never', 'botfend-anti-bot-firewall'));
            
            $ts = absint(get_option("botfend_threat_feed_{$key}_timestamp", 0));
            if ($ts < self::PLUGIN_CREATED) {
                $updated = esc_html__('Never', 'botfend-anti-bot-firewall');
            }
            
            $total_entries += $count;
            $enabled_count++;
            
            $stats[$key] = [
                'name' => $config['name'],
                'entries' => $count,
                'weight' => absint($config['weight']),
                'last_updated' => $updated,
                'type' => $config['type'],
            ];
        }
        
        return [
            'total_feeds' => count($this->feeds),
            'enabled_feeds' => $enabled_count,
            'total_entries' => $total_entries,
            'feeds' => $stats,
            'last_overall_update' => get_option('botfend_threat_intel_last_update', esc_html__('Never', 'botfend-anti-bot-firewall')),
            'timestamp' => absint(get_option('botfend_threat_intel_last_timestamp', 0)),
        ];
    }
    
    public function initialize_feeds() {
        $initialized = 0;
        
        foreach ($this->feeds as $name => $config) {
            $key = sanitize_key($name);
            $ts = absint(get_option("botfend_threat_feed_{$key}_timestamp", 0));
            $init = get_option("botfend_threat_feed_{$key}_initialized", false);
            
            if (!$init || $ts < self::PLUGIN_CREATED) {
                update_option("botfend_threat_feed_{$key}_timestamp", time(), false);
                update_option("botfend_threat_feed_{$key}_updated", current_time('mysql', true), false);
                update_option("botfend_threat_feed_{$key}_initialized", true, false);
                $initialized++;
            }
        }
        
        update_option('botfend_threat_intel_last_update', current_time('mysql', true), false);
        update_option('botfend_threat_intel_last_timestamp', time(), false);
        
        return $initialized;
    }
    
    public function get_feed_performance_stats() {
        return get_option('botfend_feed_performance_stats', []);
    }
    
    public function clear_performance_stats() {
        delete_option('botfend_feed_performance_stats');
        
        foreach ($this->feeds as $name => $config) {
            $key = sanitize_key($name);
            delete_option("botfend_feed_{$key}_failure_count");
        }
        
        return true;
    }
    
    public function cleanup() {
        self::clear_schedule();
        
        global $wpdb;
        
        if (!wp_using_ext_object_cache()) {
            $base_like = $wpdb->esc_like('_transient_botfend_threat_feed_') . '%';
            $timeout_like = $wpdb->esc_like('_transient_timeout_botfend_threat_feed_') . '%';
            
            $expired_transients = $wpdb->get_col( $wpdb->prepare(
                "SELECT option_name 
                FROM {$wpdb->options} 
                WHERE option_name LIKE %s OR option_name LIKE %s",
                $base_like,
                $timeout_like
            ) );
            
            if ( !empty( $expired_transients ) ) {
                foreach ( $expired_transients as $transient ) {
                    $key = str_replace( ['_transient_timeout_', '_transient_'], '', $transient );
                    delete_transient( $key );
                }
            }
        }
    }
}