<?php
/**
 * Main admin pages class for BotFend Anti-Bot Firewall
 * Routes to specific page handlers
 *
 * @package BotFend\Admin
 */

namespace BotFend\Admin;

use BotFend\Core\Config;
use BotFend\Core\Core;
use Exception;

defined('ABSPATH') || exit;

class AdminPages {

    private $core;
    private $config;
    private $handlers = [];

    public function __construct(Core $core) {
        $this->core = $core;
        $this->config = Config::get_instance();
        $this->load_handlers();
    }

    private function get_config_bool(string $key, bool $default = false): bool {
        return $this->config->get_bool($key, $default);
    }

    private function get_config_int(string $key, int $default = 0): int {
        return $this->config->get_int($key, $default);
    }

    private function get_config_string(string $key, string $default = ''): string {
        return $this->config->get_string($key, $default);
    }

    private function load_handlers(): void {
        $handler_config = [
            'dashboard' => [
                'class' => 'BotFend\\Admin\\Pages\\Dashboard',
                'feature' => null,
            ],
            'unblock' => [
                'class' => 'BotFend\\Admin\\Pages\\Unblock',
                'feature' => 'show_unblock_menu',
                'feature_default' => true,
            ],
            'settings' => [
                'class' => 'BotFend\\Admin\\Pages\\Settings',
                'feature' => null,
            ],
            'adaptive' => [
                'class' => 'BotFend\\Admin\\Pages\\Adaptive',
                'feature' => null,
                'feature_default' => true,
            ],
            'blocklist' => [
                'class' => 'BotFend\\Admin\\Pages\\Blocklist',
                'feature' => null,
            ],
            'logs' => [
                'class' => 'BotFend\\Admin\\Pages\\Logs',
                'feature' => null,
            ],
            'cloudflare' => [
                'class' => 'BotFend\\Admin\\Pages\\CloudflarePage',
                'feature' => null,
            ],
            'license' => [
                'class' => 'BotFend\\Admin\\Pages\\LicensePage',
                'feature' => null,
            ],
            'firewall' => [
                'class' => 'BotFend\\Admin\\Pages\\FirewallPage',
                'feature' => null,
            ],
        ];

        foreach ($handler_config as $key => $handler_info) {
            if ($handler_info['feature'] !== null) {
                $feature_enabled = $this->get_config_bool(
                    $handler_info['feature'],
                    $handler_info['feature_default'] ?? true
                );

                if (!$feature_enabled) {
                    continue;
                }
            }

            if (class_exists($handler_info['class'], true)) {
                try {
                    $this->handlers[$key] = new $handler_info['class']($this->core);
                } catch (Exception $e) {
                    $this->log_error('Error initializing handler ' . $handler_info['class'], $e->getMessage());
                }
            } else {
                $this->log_error('Class not found via PSR-4 Autoloader', $handler_info['class']);
            }
        }

        if (defined('WP_DEBUG') && WP_DEBUG && $this->get_config_bool('debug_mode', false)) {
            error_log('BotFend AdminPages loaded handlers: ' . implode(', ', array_keys($this->handlers)));
        }
    }

    private function log_error(string $message, string $context = ''): void {
        if (defined('WP_DEBUG') && WP_DEBUG && $this->get_config_bool('debug_mode', false)) {
            error_log('BotFend AdminPages: ' . $message . ' - ' . $context);
        }
    }

    public function render_dashboard(): void {
        $this->check_capability('manage_options');
        $this->check_handler('dashboard');
        $this->handlers['dashboard']->render();
    }

    public function render_unblock_requests(): void {
        $this->check_capability('manage_options');

        if (!$this->get_config_bool('show_unblock_menu', true)) {
            wp_die(
                '<h1>' . esc_html__('Feature Disabled', 'botfend-anti-bot-firewall') . '</h1><p>' . esc_html__('Unblock requests are currently disabled.', 'botfend-anti-bot-firewall') . '</p>',
                403
            );
        }

        $this->check_handler('unblock');
        $this->handlers['unblock']->render();
    }

    public function render_settings(): void {
        $this->check_capability('manage_options');
        $this->check_handler('settings');
        $this->handlers['settings']->render();
    }

    public function render_adaptive_dashboard(): void {
        $this->check_capability('manage_options');
        $this->check_handler('adaptive');
        $this->handlers['adaptive']->render();
    }

    public function render_blocklist(): void {
        $this->check_capability('manage_options');
        $this->check_handler('blocklist');
        $this->handlers['blocklist']->render();
    }

    public function render_logs(): void {
        $this->check_capability('manage_options');
        $this->check_handler('logs');
        $this->handlers['logs']->render();
    }

    /**
     * Render Cloudflare settings page
     */
    public function render_cloudflare(): void {
        $this->check_capability('manage_options');
        $this->check_handler('cloudflare');
        $this->handlers['cloudflare']->render();
    }

    /**
     * Render License page
     */
    public function render_license(): void {
        $this->check_capability('manage_options');
        $this->check_handler('license');
        $this->handlers['license']->render();
    }

    public function render_firewall(): void {
        $this->check_capability('manage_options');
        $this->check_handler('firewall');
        $this->handlers['firewall']->render();
    }

    public function handle_unblock_request_actions(): bool {
        $this->check_capability('manage_options');

        if (!$this->get_config_bool('show_unblock_menu', true)) {
            return false;
        }

        $this->check_handler('unblock');

        if (method_exists($this->handlers['unblock'], 'handle_actions')) {
            return $this->handlers['unblock']->handle_actions();
        }

        return false;
    }

    public function show_iphub_test_results(string $api_key): array {
        $this->check_capability('manage_options');
        if (!$this->get_config_bool('enable_iphub', false)) {
            return ['success' => false, 'message' => esc_html__('IPHub integration is not enabled', 'botfend-anti-bot-firewall')];
        }
        $this->check_handler('settings');
        $api_key = sanitize_text_field($api_key);
        if (method_exists($this->handlers['settings'], 'show_iphub_test_results')) {
            return $this->handlers['settings']->show_iphub_test_results($api_key);
        }
        return ['success' => false, 'message' => esc_html__('Method not available', 'botfend-anti-bot-firewall')];
    }

    public function show_abuseipdb_test_results(string $api_key): array {
        $this->check_capability('manage_options');
        if (!$this->get_config_bool('enable_abuseipdb', false)) {
            return ['success' => false, 'message' => esc_html__('AbuseIPDB integration is not enabled', 'botfend-anti-bot-firewall')];
        }
        $this->check_handler('settings');
        $api_key = sanitize_text_field($api_key);
        if (method_exists($this->handlers['settings'], 'show_abuseipdb_test_results')) {
            return $this->handlers['settings']->show_abuseipdb_test_results($api_key);
        }
        return ['success' => false, 'message' => esc_html__('Method not available', 'botfend-anti-bot-firewall')];
    }

    public function get_waf_statistics(int $hours = 24): array {
        $this->check_capability('manage_options');
        if (!$this->get_config_bool('enable_waf', true)) {
            return ['success' => false, 'message' => esc_html__('WAF is not enabled', 'botfend-anti-bot-firewall')];
        }

        $hours = min(absint($hours), $this->get_config_int('waf_stats_max_hours', 720));
        $cache_ttl = $this->get_config_int('waf_stats_cache_ttl', 300);
        $cache_key = 'botfend_waf_stats_' . $hours;
        
        $cached = wp_cache_get($cache_key, 'botfend_admin');
        if ($cached !== false) {
            return $cached;
        }

        $components = $this->core->get_components();
        $waf = $components['waf'] ?? null;

        if (!$waf) {
            $result = ['success' => false, 'message' => esc_html__('WAF not available', 'botfend-anti-bot-firewall')];
            wp_cache_set($cache_key, $result, 'botfend_admin', 15);
            return $result;
        }

        if (method_exists($waf, 'get_waf_statistics')) {
            try {
                $stats = $waf->get_waf_statistics($hours);
                $result = [
                    'success' => true,
                    'data' => [
                        'total_detections' => absint($stats['total_detections'] ?? 0),
                        'avg_score' => floatval($stats['avg_score'] ?? 0),
                        'critical_detections' => absint($stats['critical_detections'] ?? 0),
                        'unique_attackers' => absint($stats['unique_attackers'] ?? 0),
                        'top_rules' => $stats['top_rules'] ?? [],
                        'rules_count' => method_exists($waf, 'get_rules_count') ? absint($waf->get_rules_count() ?? 0) : 0
                    ]
                ];
                wp_cache_set($cache_key, $result, 'botfend_admin', $cache_ttl);
                return $result;
            } catch (Exception $e) {
                $result = ['success' => false, 'message' => esc_html__('Error getting WAF stats.', 'botfend-anti-bot-firewall')];
                wp_cache_set($cache_key, $result, 'botfend_admin', 60);
                return $result;
            }
        }
        $result = ['success' => false, 'message' => esc_html__('WAF stats not available', 'botfend-anti-bot-firewall')];
        wp_cache_set($cache_key, $result, 'botfend_admin', 15);
        return $result;
    }

    private function check_capability(string $capability = 'manage_options'): void {
        if (!current_user_can($this->get_config_string('admin_capability', $capability))) {
            wp_die(
                '<h1>' . esc_html__('Permission Denied', 'botfend-anti-bot-firewall') . '</h1><p>' . esc_html__('Sorry, you are not allowed to access this page.', 'botfend-anti-bot-firewall') . '</p>',
                403
            );
        }
    }

    private function check_handler(string $handler_name): void {
        if (!isset($this->handlers[$handler_name])) {
            wp_die(
                '<h1>' . esc_html__('Page Handler Not Found', 'botfend-anti-bot-firewall') . '</h1><p>' . esc_html__('The requested page handler could not be loaded.', 'botfend-anti-bot-firewall') . '</p>',
                404
            );
        }
    }

    public function get_available_handlers(): array {
        return array_keys($this->handlers);
    }

    public function verify_ajax_nonce(string $action = 'botfend_admin_nonce'): void {
        if (!check_ajax_referer($action, 'nonce', false)) {
            wp_send_json_error(['message' => esc_html__('Security check failed.', 'botfend-anti-bot-firewall')]);
        }
    }

    private function sanitize_array_recursive(array $array): array {
        $sanitized = [];
        foreach ($array as $key => $value) {
            $key = sanitize_key($key);
            if (is_array($value)) {
                $sanitized[$key] = $this->sanitize_array_recursive($value);
            } else {
                $sanitized[$key] = sanitize_text_field((string) $value);
            }
        }
        return $sanitized;
    }

    public function sanitize_page_parameters(array $params): array {
        $sanitized = [];
        foreach ($params as $key => $value) {
            $key = sanitize_key($key);
            if (is_array($value)) {
                $sanitized[$key] = $this->sanitize_array_recursive($value);
            } elseif (is_float($value) || (is_numeric($value) && strpos((string)$value, '.') !== false)) {
                $sanitized[$key] = (float) $value;
            } elseif (is_numeric($value)) {
                $sanitized[$key] = (int) $value;
            } else {
                $sanitized[$key] = sanitize_text_field((string) $value);
            }
        }
        return $sanitized;
    }

    public function update_waf_rules(string $source_url = ''): array {
        $this->check_capability('manage_options');
        if (!$this->get_config_bool('enable_waf', true)) {
            return ['success' => false, 'message' => esc_html__('WAF is not enabled', 'botfend-anti-bot-firewall')];
        }
        if (!$this->get_config_bool('waf_auto_update', true)) {
            return ['success' => false, 'message' => esc_html__('WAF auto-updates disabled', 'botfend-anti-bot-firewall')];
        }

        $components = $this->core->get_components();
        $waf = $components['waf'] ?? null;
        if (!$waf) {
            return ['success' => false, 'message' => esc_html__('WAF not available', 'botfend-anti-bot-firewall')];
        }

        if (method_exists($waf, 'update_rules_from_feed')) {
            try {
                $source_url = empty($source_url) ? $this->get_config_string('waf_feed_url', '') : esc_url_raw($source_url);
                $rules_updated = $waf->update_rules_from_feed($source_url);

                if ($rules_updated > 0) {
                    wp_cache_delete('botfend_waf_stats_24', 'botfend_admin');
                    wp_cache_delete('botfend_waf_stats_168', 'botfend_admin');
                    wp_cache_delete('botfend_waf_rules', 'botfend');
                    return ['success' => true, 'message' => sprintf(esc_html__('Updated %d WAF rules.', 'botfend-anti-bot-firewall'), $rules_updated), 'rules_updated' => $rules_updated];
                } elseif ($rules_updated === 0) {
                    return ['success' => true, 'message' => esc_html__('No new rules found.', 'botfend-anti-bot-firewall'), 'rules_updated' => 0];
                } else {
                    return ['success' => false, 'message' => esc_html__('Failed to update WAF rules.', 'botfend-anti-bot-firewall')];
                }
            } catch (Exception $e) {
                return ['success' => false, 'message' => esc_html__('Error updating WAF rules.', 'botfend-anti-bot-firewall')];
            }
        }
        return ['success' => false, 'message' => esc_html__('WAF rule update not available', 'botfend-anti-bot-firewall')];
    }

    public function __get(string $name) {
        return $this->handlers[$name] ?? null;
    }

    public function __isset(string $name): bool {
        return isset($this->handlers[$name]);
    }
}