<?php
if (!defined('ABSPATH')) {
    exit;
}

class BotBlocker_Settings {
    const OPTION = 'bot_blocker_settings';

    public static function init() {
        add_action('admin_init', [__CLASS__, 'register_privacy_text']);
        add_filter('wp_privacy_personal_data_exporters', [__CLASS__, 'register_exporter']);
        add_filter('wp_privacy_personal_data_erasers', [__CLASS__, 'register_eraser']);
    }

    public static function defaults() {
        return [
            'enforcement_enabled'     => 1,
            'logging_enabled'         => 1,
            'store_full_ip'           => 0,
            'log_query_strings'       => 0,
            'log_referrers'           => 0,
            'geolocation_enabled'     => 1,
            'dns_verification_enabled'=> 1,
            'trust_cloudflare_headers'=> 0,
            'trusted_proxy_ips'       => '',
            'monitor_refresh_seconds' => 3,
            'log_retention_days'      => 30,
            'rules' => [
                'verified_bots'        => 'allow',
                'claimed_trusted_bots' => 'log',
                'fake_trusted_bots'    => 'block',
                'ai_crawlers'          => 'rate_limit',
                'ai_assistants'        => 'log',
                'search_bots'          => 'allow',
                'preview_bots'         => 'allow',
                'monitoring_bots'      => 'allow',
                'service_bots'         => 'allow',
                'scanner_bots'         => 'temporary_block',
                'scraper_bots'         => 'rate_limit',
                'spam_bots'            => 'temporary_block',
                'sensitive_paths'      => 'block',
            ],
            'rate_limits' => [
                'ai_crawlers'   => 20,
                'scraper_bots'  => 15,
                'scanner_bots'  => 8,
                'spam_bots'     => 8,
            ],
            'lists' => [
                'allow_ips'    => '',
                'block_ips'    => '',
                'allow_agents' => '',
                'block_agents' => '',
                'allow_paths'  => '',
                'block_paths'  => '',
            ],
            'sensitive_paths' => "/xmlrpc.php\n/.env\n/.git\n/.well-known/\n/wp-json/wp/v2/users\n",
            // Pro settings - always present so sanitize_settings() does not strip them
            'pro_blocked_countries'       => [],
            'pro_country_block_action'    => 'block',
            'pro_auto_escalate_fake_bots' => false,
            'pro_digest_frequency'        => 'disabled',
            'pro_digest_email'            => '',
            'pro_custom_block_html'       => '',
        ];
    }

    public static function get() {
        return self::sanitize_settings(wp_parse_args(get_option(self::OPTION, []), self::defaults()));
    }

    public static function update($settings) {
        update_option(self::OPTION, self::sanitize_settings(wp_parse_args($settings, self::defaults())));
    }

    public static function sanitize_settings($settings) {
        $defaults = self::defaults();
        $settings = wp_parse_args(is_array($settings) ? $settings : [], $defaults);

        foreach (['enforcement_enabled', 'logging_enabled', 'store_full_ip', 'log_query_strings', 'log_referrers', 'geolocation_enabled', 'dns_verification_enabled', 'trust_cloudflare_headers'] as $key) {
            $settings[$key] = empty($settings[$key]) ? 0 : 1;
        }

        $settings['monitor_refresh_seconds'] = max(2, min(30, (int) $settings['monitor_refresh_seconds']));
        $settings['log_retention_days'] = max(1, min(365, (int) $settings['log_retention_days']));
        $settings['trusted_proxy_ips'] = self::sanitize_line_list($settings['trusted_proxy_ips']);
        $settings['sensitive_paths'] = self::sanitize_sensitive_paths($settings['sensitive_paths']);

        if (!isset($settings['lists']) || !is_array($settings['lists'])) {
            $settings['lists'] = $defaults['lists'];
        }
        foreach (array_keys($defaults['lists']) as $list_key) {
            $settings['lists'][$list_key] = self::sanitize_line_list($settings['lists'][$list_key] ?? '');
        }

        if (!isset($settings['rules']) || !is_array($settings['rules'])) {
            $settings['rules'] = $defaults['rules'];
        }
        $valid_actions = array_keys(self::actions());
        foreach ($defaults['rules'] as $category => $default_action) {
            $candidate = isset($settings['rules'][$category]) ? sanitize_key($settings['rules'][$category]) : $default_action;
            $settings['rules'][$category] = in_array($candidate, $valid_actions, true) ? $candidate : $default_action;
        }

        if (!isset($settings['rate_limits']) || !is_array($settings['rate_limits'])) {
            $settings['rate_limits'] = $defaults['rate_limits'];
        }
        foreach ($defaults['rate_limits'] as $category => $default_limit) {
            $settings['rate_limits'][$category] = max(1, min(5000, (int) ($settings['rate_limits'][$category] ?? $default_limit)));
        }

        return $settings;
    }


    public static function register_exporter($exporters) {
        $exporters['bot-blocker'] = [
            'exporter_friendly_name' => __('Bot Blocker logs', 'sera-bot-blocker'),
            'callback'               => [__CLASS__, 'privacy_exporter'],
        ];
        return $exporters;
    }

    public static function register_eraser($erasers) {
        $erasers['bot-blocker'] = [
            'eraser_friendly_name' => __('Bot Blocker logs', 'sera-bot-blocker'),
            'callback'             => [__CLASS__, 'privacy_eraser'],
        ];
        return $erasers;
    }

    public static function privacy_exporter($email_address, $page = 1) {
        $result = BotBlocker_Storage::privacy_export($email_address, $page);
        return [
            'data' => $result['data'],
            'done' => $result['done'],
        ];
    }

    public static function privacy_eraser($email_address, $page = 1) {
        $result = BotBlocker_Storage::privacy_erase($email_address, $page);
        return [
            'items_removed'  => $result['items_removed'],
            'items_retained' => false,
            'messages'       => $result['messages'],
            'done'           => $result['done'],
        ];
    }

    public static function register_privacy_text() {
        if (!function_exists('wp_add_privacy_policy_content')) {
            return;
        }

        $content = '<p>' . esc_html__('Bot Blocker can store bot event logs including IP-derived data, masked IP, optional raw IP, user agent, requested path, action taken, and optional geolocation data. Query strings and referrers are off by default because they may contain personal or sensitive data. Geolocation uses a third-party service only when that feature is explicitly enabled.', 'sera-bot-blocker') . '</p>';
        wp_add_privacy_policy_content('Bot Blocker', wp_kses_post($content));
    }

    public static function categories() {
        return [
            'verified_bots'        => __('Verified bots', 'sera-bot-blocker'),
            'claimed_trusted_bots' => __('Claimed trusted bots', 'sera-bot-blocker'),
            'fake_trusted_bots'    => __('Fake trusted bots', 'sera-bot-blocker'),
            'ai_crawlers'          => __('AI crawlers', 'sera-bot-blocker'),
            'ai_assistants'        => __('AI assistants / fetchers', 'sera-bot-blocker'),
            'search_bots'          => __('Search / SEO bots', 'sera-bot-blocker'),
            'preview_bots'         => __('Preview / unfurl bots', 'sera-bot-blocker'),
            'monitoring_bots'      => __('Monitoring bots', 'sera-bot-blocker'),
            'service_bots'         => __('Service / integration bots', 'sera-bot-blocker'),
            'scanner_bots'         => __('Scanner bots', 'sera-bot-blocker'),
            'scraper_bots'         => __('Scraper bots', 'sera-bot-blocker'),
            'spam_bots'            => __('Spam bots', 'sera-bot-blocker'),
            'sensitive_paths'      => __('Sensitive paths', 'sera-bot-blocker'),
        ];
    }

    public static function log_categories() {
        $categories = self::categories();
        $categories['manual_block'] = __('Manual block rule', 'sera-bot-blocker');
        return $categories;
    }

    public static function actions() {
        return [
            'allow'           => __('Allow', 'sera-bot-blocker'),
            'log'             => __('Log', 'sera-bot-blocker'),
            'rate_limit'      => __('Rate limit', 'sera-bot-blocker'),
            'temporary_block' => __('Temporary block', 'sera-bot-blocker'),
            'block'           => __('Block', 'sera-bot-blocker'),
        ];
    }

    private static function sanitize_sensitive_paths($value) {
        $lines = self::split_lines($value);
        $disallowed = ['/wp-admin/', '/wp-login.php', '/wp-register.php', '/wp-signup.php', '/wp-activate.php', '/admin-ajax.php', '/admin-post.php'];
        $clean = [];

        foreach ($lines as $line) {
            $line = trim($line);
            if ($line === '' || in_array($line, $disallowed, true)) {
                continue;
            }
            if ($line[0] !== '/') {
                $line = '/' . ltrim($line, '/');
            }
            $clean[] = $line;
        }

        return implode("\n", array_values(array_unique($clean)));
    }

    private static function sanitize_line_list($value) {
        return implode("\n", array_values(array_unique(self::split_lines($value))));
    }

    private static function split_lines($value) {
        $lines = preg_split('/\r\n|\r|\n/', (string) $value);
        $clean = [];
        foreach ($lines as $line) {
            $line = trim(wp_unslash((string) $line));
            if ($line === '') {
                continue;
            }
            $clean[] = $line;
        }
        return $clean;
    }
}
