<?php
/**
 * Handles the Admin Settings page for Guard Dog.
 *
 * @package GuardDog
 * @since 1.1.0
 */

if (!defined('ABSPATH')) exit; // Exit if accessed directly

class Guard_Dog_Admin_Settings {

    /**
     * Settings page slug.
     * @var string
     */
    const PAGE_SLUG = 'guard-dog';

    /**
     * Activity Log page slug.
     * @var string
     */
    const LOG_PAGE_SLUG = 'guard-dog-logs';

    /**
     * Option group name for settings saved via options.php.
     * @var string
     */
    const OPTION_GROUP = 'guard_dog_options_group';

    /**
     * Nonce action for user search AJAX.
     * @var string
     */
    const NONCE_ACTION_USER_SEARCH = 'guard_dog_user_search';

    /**
     * Option key for the generic login error message.
     * @var string
     */
    const OPTION_GENERIC_ERROR = 'guard_dog_generic_login_error';

    // Access Control Option Keys
    const OPTION_ACCESS_MODE = 'guard_dog_access_mode';
    const OPTION_IP_BLACKLIST = 'guard_dog_ip_blacklist';
    const OPTION_IP_WHITELIST = 'guard_dog_ip_whitelist';
    const OPTION_USER_BLACKLIST = 'guard_dog_user_blacklist';
    const OPTION_USER_WHITELIST = 'guard_dog_user_whitelist';

    // CAPTCHA Option Keys
    const OPTION_CAPTCHA_PROVIDER = 'guard_dog_captcha_provider';
    const OPTION_CAPTCHA_SITE_KEY = 'guard_dog_captcha_site_key';
    const OPTION_CAPTCHA_SECRET_KEY = 'guard_dog_captcha_secret_key';
    const OPTION_CAPTCHA_THEME = 'guard_dog_captcha_theme';
    const OPTION_CAPTCHA_SIZE = 'guard_dog_captcha_size';
    const OPTION_CAPTCHA_V3_THRESHOLD = 'guard_dog_captcha_v3_threshold';
    const OPTION_CAPTCHA_ERROR_MESSAGE = 'guard_dog_captcha_error_message';
    const OPTION_CAPTCHA_USE_ENTERPRISE = 'guard_dog_captcha_use_enterprise';

    // Debug Option Keys
    const OPTION_DEBUG_ENABLED = 'guard_dog_debug_enabled';
    const OPTION_DEBUG_LEVEL = 'guard_dog_debug_level';

    /**
     * References to the loaded feature classes.
     * @var array
     */
    private $features = [];

    /**
     * Constructor.
     *
     * @since 1.1.0
     * @param array $features Array of loaded feature class instances.
     */

    public function __construct($features) {
        $this->features = $features;
        $this->add_hooks();

        // Register settings
        add_action('admin_init', [$this, 'register_settings']);
        
        // Handle screen option saving
        add_filter('set-screen-option', [$this, 'set_screen_option'], 10, 3);
    }

    /**
     * Add admin hooks.
     *
     * @since 1.1.0
     */
    private function add_hooks() {
        add_action('admin_menu', [$this, 'add_admin_menu_pages']);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']); // Hook for scripts/styles
        add_action('load-guard-dog_page_guard-dog-logs', [$this, 'add_screen_options']);
    }

    /**
     * Enqueue admin scripts and styles.
     *
     * @since 1.1.0
     */
    public function enqueue_admin_assets($hook_suffix) {
        // Only load on Guard Dog admin pages
        if (strpos($hook_suffix, 'guard-dog') === false) {
            return;
        }

        wp_enqueue_script(
            'guard-dog-admin-settings',
            GUARD_DOG_URL . 'assets/js/guard-dog-admin-settings.js',
            ['jquery'],
            GUARD_DOG_VERSION,
            true
        );

        // Localize script with translatable strings
        wp_localize_script(
            'guard-dog-admin-settings',
            'guard_dog_admin_settings',
            [
                'clearLogConfirm' => esc_html__('Are you sure you want to clear the debug log?', 'guard-dog'),
                'clearAllLogsConfirm' => esc_html__('Are you sure you want to delete all log entries? This action cannot be undone.', 'guard-dog'),
                'clearLogsConfirm' => esc_html__('Are you sure you want to clear all activity logs? This action cannot be undone.', 'guard-dog'),
                'resetLockoutsConfirm' => esc_html__('Are you sure you want to reset all lockouts? This will allow all blocked IPs and usernames to attempt login again.', 'guard-dog'),
                'resetAllSettingsConfirm' => esc_html__('WARNING: This will reset ALL Guard Dog settings to defaults and clear all data. This action cannot be undone. Are you absolutely sure?', 'guard-dog'),
                'revokeUserConfirm' => esc_html__('Are you sure you want to revoke this temporary user?', 'guard-dog'),
                'deleteExpiredUserConfirm' => esc_html__('Are you sure you want to permanently delete this expired user?', 'guard-dog'),
                'unlockIpConfirm' => esc_html__('Are you sure you want to unlock this IP?', 'guard-dog')
            ]
        );

        wp_enqueue_style(
            'guard-dog-admin-settings',
            GUARD_DOG_URL . 'assets/css/guard-dog-admin-settings.css',
            [],
            GUARD_DOG_VERSION
        );
    }

    /**
     * Add the options page to the Settings menu.
     *
     * @since 1.1.0
     */
    public function add_admin_menu_pages() {
        // Add top-level menu page for Guard Dog
        add_menu_page(
            __('Guard Dog', 'guard-dog'),          // Page title
            __('Guard Dog', 'guard-dog'),          // Menu title
            'manage_options',                  // Capability
            self::PAGE_SLUG,                   // Menu slug (for the top-level page)
            [$this, 'render_settings_page'],     // Callback function for the top-level page content
            'dashicons-pets'                   // Icon URL or dashicon class
        );

        // Add submenu for Settings (can often be the same as the top-level if its slug matches)
        add_submenu_page(
            self::PAGE_SLUG,                   // Parent slug
            __('Guard Dog Settings', 'guard-dog'), // Page title
            __('Settings', 'guard-dog'),          // Menu title
            'manage_options',                  // Capability
            self::PAGE_SLUG,                   // Menu slug (same as parent makes it the default)
            [$this, 'render_settings_page']     // Callback function
        );

        // Add submenu for Activity Log
        add_submenu_page(
            self::PAGE_SLUG,                   // Parent slug
            __('Guard Dog Activity Log', 'guard-dog'), // Page title
            __('Activity Log', 'guard-dog'),      // Menu title
            'manage_options',                  // Capability (consider a more specific capability later if needed)
            self::LOG_PAGE_SLUG,               // Menu slug for the log page
            [$this, 'render_log_viewer_page']   // Callback function
        );
    }

    /**
     * Register settings, sections, and fields.
     *
     * @since 1.1.0
     */
    public function register_settings() {
        // Register the main option group used by the settings API form
        // Default MUST stay empty. register_setting()'s 'default' installs a
        // default_option_{$option} filter, so a non-empty value here would make
        // get_option( 'guard_dog_login_slug' ) return that slug on installs where
        // the option row does not exist - silently switching the custom login URL
        // on and 404ing wp-login.php. Empty means "custom login URL disabled".
        register_setting(self::OPTION_GROUP, Guard_Dog_Login_Url::OPTION_NAME, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key',
            'default' => '',
        ]);

        // Register setting for generic login error
        register_setting(self::OPTION_GROUP, self::OPTION_GENERIC_ERROR, [
            'type' => 'string',
            'sanitize_callback' => 'wp_kses_post', // Allow basic HTML potentially
            'default' => '', // Default is empty (disabled)
        ]);

        // --- Login URL Section ---
        add_settings_section(
            'guard_dog_login_section',
            __('Login URL Settings', 'guard-dog'),
            null, // No description callback needed for this section itself
            self::PAGE_SLUG // Page slug where this section appears
        );

        add_settings_field(
            Guard_Dog_Login_Url::OPTION_NAME,
            __('Custom Login URL Slug', 'guard-dog'),
            [$this, 'render_login_slug_field'], // Use a method in this class to render
            self::PAGE_SLUG,
            'guard_dog_login_section' // Section ID
        );

        add_settings_field(
            self::OPTION_GENERIC_ERROR,
            __('Generic Login Error Message', 'guard-dog'),
            [$this, 'render_generic_error_field'], // Field rendering callback
            self::PAGE_SLUG,
            'guard_dog_login_section' // Add to the login section for now
        );

        // --- Temporary Access Section (handled differently as it uses admin-post) ---
        // We don't register settings/fields via Settings API for this one,
        // but we can still add its section heading via the feature class method if needed.
        // The content rendering will handle the form.
        if (isset($this->features['temp_access']) && method_exists($this->features['temp_access'], 'add_settings_section')) {
             // Currently, the render_settings_content in Temp_Access includes the heading.
             // If we wanted a separate section registered via Settings API:
             // $this->features['temp_access']->add_settings_section(self::PAGE_SLUG . '-temp-access'); // Pass a unique page slug for the section
        }

        // --- Access Control Settings ---
        add_settings_section(
            'guard_dog_access_control_section',
            __('Access Control Settings', 'guard-dog'),
            [$this, 'render_access_control_section_description'],
            self::PAGE_SLUG
        );

        // Register Access Control settings
        register_setting(self::OPTION_GROUP, self::OPTION_ACCESS_MODE, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key', // 'blacklist' or 'whitelist'
            'default' => 'blacklist',
        ]);
        register_setting(self::OPTION_GROUP, self::OPTION_IP_BLACKLIST, [
            'type' => 'string',
            'sanitize_callback' => [$this, 'sanitize_ip_list'],
            'default' => '',
        ]);
        register_setting(self::OPTION_GROUP, self::OPTION_IP_WHITELIST, [
            'type' => 'string',
            'sanitize_callback' => [$this, 'sanitize_ip_list'],
            'default' => '',
        ]);
        register_setting(self::OPTION_GROUP, self::OPTION_USER_BLACKLIST, [
            'type' => 'string',
            'sanitize_callback' => [$this, 'sanitize_newline_list'],
            'default' => '',
        ]);
        register_setting(self::OPTION_GROUP, self::OPTION_USER_WHITELIST, [
            'type' => 'string',
            'sanitize_callback' => [$this, 'sanitize_newline_list'],
            'default' => '',
        ]);

        // Add Access Control fields
        add_settings_field(
            self::OPTION_ACCESS_MODE,
            __('Access Mode', 'guard-dog'),
            [$this, 'render_access_mode_field'],
            self::PAGE_SLUG,
            'guard_dog_access_control_section'
        );
        add_settings_field(
            self::OPTION_IP_BLACKLIST,
            __('IP Blacklist', 'guard-dog'),
            [$this, 'render_textarea_field'],
            self::PAGE_SLUG,
            'guard_dog_access_control_section',
            ['option_name' => self::OPTION_IP_BLACKLIST, 'description' => __('One IP address or CIDR range per line. Access will be denied if the user\'s IP matches any entry in this list (only active in Blacklist Mode).', 'guard-dog')]
        );
        add_settings_field(
            self::OPTION_IP_WHITELIST,
            __('IP Whitelist', 'guard-dog'),
            [$this, 'render_textarea_field'],
            self::PAGE_SLUG,
            'guard_dog_access_control_section',
            ['option_name' => self::OPTION_IP_WHITELIST, 'description' => __('One IP address or CIDR range per line. Access will only be allowed if the user\'s IP matches an entry in this list (only active in Whitelist Mode).', 'guard-dog')]
        );
        add_settings_field(
            self::OPTION_USER_BLACKLIST,
            __('Username Blacklist', 'guard-dog'),
            [$this, 'render_textarea_field'],
            self::PAGE_SLUG,
            'guard_dog_access_control_section',
            [
                'option_name' => self::OPTION_USER_BLACKLIST,
                'description' => __('Enter usernames to block. Access will be denied if the username matches any entry in this list (only active in Blacklist Mode).', 'guard-dog'),
                'is_user_list' => true // Flag this as a user list field
            ]
        );
        add_settings_field(
            self::OPTION_USER_WHITELIST,
            __('Username Whitelist', 'guard-dog'),
            [$this, 'render_textarea_field'],
            self::PAGE_SLUG,
            'guard_dog_access_control_section',
            [
                'option_name' => self::OPTION_USER_WHITELIST,
                'description' => __('Enter usernames to allow. Access will only be allowed if the username matches an entry in this list (only active in Whitelist Mode).', 'guard-dog'),
                'is_user_list' => true // Flag this as a user list field
            ]
        );

        // --- Limit Login Attempts Settings ---
        register_setting(self::OPTION_GROUP, Guard_Dog_Limit_Login_Attempts::OPTION_ENABLED, [
            'type' => 'boolean',
            'sanitize_callback' => 'rest_sanitize_boolean',
            'default' => false,
        ]);

        register_setting(self::OPTION_GROUP, Guard_Dog_Limit_Login_Attempts::OPTION_MAX_RETRIES, [
            'type' => 'integer',
            'sanitize_callback' => [$this, 'sanitize_positive_integer'],
            'default' => 5,
        ]);

        register_setting(self::OPTION_GROUP, Guard_Dog_Limit_Login_Attempts::OPTION_LOCKOUT_DURATION, [
            'type' => 'integer',
            'sanitize_callback' => [$this, 'sanitize_positive_integer'],
            'default' => 15, // Default in minutes
        ]);

        add_settings_section(
            'guard_dog_lla_section',
            __('Limit Login Attempts', 'guard-dog'),
            [$this, 'render_lla_section_header'],
            self::PAGE_SLUG
        );

        add_settings_field(
            Guard_Dog_Limit_Login_Attempts::OPTION_ENABLED,
            __('Enable Limiting', 'guard-dog'),
            [$this, 'render_lla_enabled_field'],
            self::PAGE_SLUG,
            'guard_dog_lla_section'
        );

        add_settings_field(
            Guard_Dog_Limit_Login_Attempts::OPTION_MAX_RETRIES,
            __('Max Retries', 'guard-dog'),
            [$this, 'render_lla_max_retries_field'],
            self::PAGE_SLUG,
            'guard_dog_lla_section'
        );

        add_settings_field(
            Guard_Dog_Limit_Login_Attempts::OPTION_LOCKOUT_DURATION,
            __('Lockout Duration (minutes)', 'guard-dog'),
            [$this, 'render_lla_lockout_duration_field'],
            self::PAGE_SLUG,
            'guard_dog_lla_section'
        );

        // --- CAPTCHA Settings ---
        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_PROVIDER, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key',
            'default' => 'none',
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_SITE_KEY, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '',
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_SECRET_KEY, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default' => '',
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_THEME, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key',
            'default' => 'light',
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_SIZE, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key',
            'default' => 'normal',
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_V3_THRESHOLD, [
            'type' => 'number',
            'sanitize_callback' => [$this, 'sanitize_captcha_threshold'],
            'default' => 0.5,
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_ERROR_MESSAGE, [
            'type' => 'string',
            'sanitize_callback' => 'wp_kses_post',
            'default' => __('Please complete the CAPTCHA verification.', 'guard-dog'),
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_CAPTCHA_USE_ENTERPRISE, [
            'type' => 'boolean',
            'sanitize_callback' => 'rest_sanitize_boolean',
            'default' => true,
        ]);

        add_settings_section(
            'guard_dog_captcha_section',
            __('CAPTCHA Protection', 'guard-dog'),
            [$this, 'render_captcha_section_header'],
            self::PAGE_SLUG
        );

        add_settings_field(
            self::OPTION_CAPTCHA_PROVIDER,
            __('CAPTCHA Provider', 'guard-dog'),
            [$this, 'render_captcha_provider_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_SITE_KEY,
            __('Site Key', 'guard-dog'),
            [$this, 'render_captcha_site_key_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_SECRET_KEY,
            __('Secret Key', 'guard-dog'),
            [$this, 'render_captcha_secret_key_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_THEME,
            __('Theme', 'guard-dog'),
            [$this, 'render_captcha_theme_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_SIZE,
            __('Size', 'guard-dog'),
            [$this, 'render_captcha_size_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_V3_THRESHOLD,
            __('reCAPTCHA v3 Score Threshold', 'guard-dog'),
            [$this, 'render_captcha_threshold_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_USE_ENTERPRISE,
            __('Use Enterprise API', 'guard-dog'),
            [$this, 'render_captcha_enterprise_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        add_settings_field(
            self::OPTION_CAPTCHA_ERROR_MESSAGE,
            __('Error Message', 'guard-dog'),
            [$this, 'render_captcha_error_message_field'],
            self::PAGE_SLUG,
            'guard_dog_captcha_section'
        );

        // --- Debug Settings ---
        register_setting(self::OPTION_GROUP, self::OPTION_DEBUG_ENABLED, [
            'type' => 'boolean',
            'sanitize_callback' => 'rest_sanitize_boolean',
            'default' => false,
        ]);

        register_setting(self::OPTION_GROUP, self::OPTION_DEBUG_LEVEL, [
            'type' => 'string',
            'sanitize_callback' => 'sanitize_key',
            'default' => 'error',
        ]);

        add_settings_section(
            'guard_dog_debug_section',
            __('Debug Settings', 'guard-dog'),
            [$this, 'render_debug_section_header'],
            self::PAGE_SLUG
        );

        add_settings_field(
            self::OPTION_DEBUG_ENABLED,
            __('Enable Debug Logging', 'guard-dog'),
            [$this, 'render_debug_enabled_field'],
            self::PAGE_SLUG,
            'guard_dog_debug_section'
        );

        add_settings_field(
            self::OPTION_DEBUG_LEVEL,
            __('Debug Level', 'guard-dog'),
            [$this, 'render_debug_level_field'],
            self::PAGE_SLUG,
            'guard_dog_debug_section'
        );

        // Register other feature settings here in the future...

    }

    /**
     * Render the settings page wrapper and delegate content rendering.
     *
     * @since 1.1.0
     */
    public function render_settings_page() {
        $temp_access_feature = isset($this->features['temp_access']) ? $this->features['temp_access'] : null;
        
        $this->render_settings_page_content($temp_access_feature);
    }

    /**
     * Callback function to render the Custom Login URL Slug field.
     *
     * @since 1.1.0
     */
    public function render_login_slug_field() {
        // Render an empty field (with a placeholder hint) rather than pre-filling a
        // slug. Pre-filling meant simply saving this page switched the custom login
        // URL on without the administrator ever choosing a slug.
        $slug = get_option(Guard_Dog_Login_Url::OPTION_NAME, '');
        $description = esc_html__(
            'Enter the desired slug for your custom login URL (e.g., "secure-login"). Leave blank to keep the standard WordPress login URL.',
            'guard-dog'
        );
        ?>
        <input type="text" name="<?php echo esc_attr(Guard_Dog_Login_Url::OPTION_NAME); ?>" value="<?php echo esc_attr($slug); ?>" placeholder="my-login" />
        <p class="description"><?php echo wp_kses_post($description); ?></p>
        <?php
    }

    /**
     * Callback function to render the Generic Login Error Message field.
     *
     * @since 1.3.0
     */
    public function render_generic_error_field() {
        $message = esc_textarea(get_option(Guard_Dog_Admin_Settings::OPTION_GENERIC_ERROR, ''));
        $placeholder = esc_attr__('Example: Invalid login details entered. Please try again.', 'guard-dog');
        ?>
        <textarea name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_GENERIC_ERROR); ?>" rows="3" cols="50" class="large-text" placeholder="<?php echo esc_attr($placeholder); ?>"><?php echo esc_textarea($message); ?></textarea>
        <p class="description"><?php esc_html_e('Enter a generic error message to display for all failed login attempts (username or password errors). Leave blank to use default WordPress errors.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Callback function to render the description for the Access Control section.
     *
     * @since 1.4.0
     */
    public function render_access_control_section_description() {
        ?>
        <p><?php esc_html_e('Control login access based on IP address or username using blacklists or whitelists.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Callback function to render the Access Mode radio buttons.
     *
     * @since 1.3.0
     */
    public function render_access_mode_field() {
        $current_mode = get_option(Guard_Dog_Admin_Settings::OPTION_ACCESS_MODE, 'blacklist');
        ?>
        <fieldset>
            <legend class="screen-reader-text"><span><?php esc_html_e('Access Mode', 'guard-dog'); ?></span></legend>
            <label>
                <input type="radio" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_ACCESS_MODE); ?>" value="blacklist" <?php checked($current_mode, 'blacklist'); ?> />
                <?php esc_html_e('Blacklist Mode', 'guard-dog'); ?>
                <p class="description"><?php esc_html_e('Allow all users except those matching the blacklist rules.', 'guard-dog'); ?></p>
            </label>
            <br/>
            <label>
                <input type="radio" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_ACCESS_MODE); ?>" value="whitelist" <?php checked($current_mode, 'whitelist'); ?> />
                <?php esc_html_e('Whitelist Mode', 'guard-dog'); ?>
                <p class="description"><?php esc_html_e('Deny all users except those matching the whitelist rules.', 'guard-dog'); ?></p>
            </label>
        </fieldset>
        <?php
    }

    /**
     * Renders a standard textarea field for lists.
     *
     * @since 1.3.0
     * @param array $args Field arguments (must contain 'option_name' and 'description').
     *                  Can optionally contain 'is_user_list' => true to render tag input.
     */
    public function render_textarea_field($args) {
        if (empty($args['option_name']) || empty($args['description'])) {
            return;
        }
        
        $option_name = $args['option_name'];
        $description = $args['description'];
        $is_user_list = $args['is_user_list'] ?? false;
        $value = get_option($option_name, '');

        if ($is_user_list) {
            // Render the tag input structure
            $escaped_value = esc_attr($value); // Value for hidden input is comma-separated
            ?>
            <div class="guard-dog-tag-input-wrapper">
                <div class="guard-dog-tags-container">
                    <?php /* Tags will be populated by JS */ ?>
                </div>
                <input type="text" class="guard-dog-tag-input regular-text" placeholder="<?php esc_attr_e('Type to search for users...', 'guard-dog'); ?>">
                <ul class="guard-dog-suggestions-container"></ul>
                <?php // IMPORTANT: The name attribute is on the hidden input for form submission ?>
                <input type="hidden" name="<?php echo esc_attr($option_name); ?>" id="<?php echo esc_attr($option_name); ?>" value="<?php echo esc_attr($escaped_value); ?>">
            </div>
            <p class="description"><?php echo esc_html($description); ?></p>
            <?php
        } else {
            // Render standard textarea for IP lists or other textareas
            $escaped_value = esc_textarea($value); // Value for textarea is newline-separated
            ?>
            <textarea name="<?php echo esc_attr($option_name); ?>" id="<?php echo esc_attr($option_name); ?>" rows="5" cols="50" class="large-text code"><?php echo esc_textarea($escaped_value); ?></textarea>
            <p class="description"><?php echo esc_html($description); ?></p>
            <?php
        }
    }

    /**
     * Render the header for the Limit Login Attempts section.
     *
     * @since 1.5.0
     */
    public function render_lla_section_header() {
        ?>
        <p><?php esc_html_e('Protect your site against brute-force login attacks.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render the checkbox field for enabling Limit Login Attempts.
     *
     * @since 1.5.0
     */
    public function render_lla_enabled_field() {
        $option_name = Guard_Dog_Limit_Login_Attempts::OPTION_ENABLED;
        $checked = get_option($option_name, false);
        ?>
        <input type="checkbox" name="<?php echo esc_attr($option_name); ?>" value="1" <?php checked(1, $checked, false); ?> />
        <label for="<?php echo esc_attr($option_name); ?>"><?php esc_html_e('Enable login attempt limiting', 'guard-dog'); ?></label>
        <p class="description"><?php esc_html_e('If checked, users will be temporarily locked out after too many failed login attempts from the same IP address.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render the number field for Maximum Login Retries.
     *
     * @since 1.5.0
     */
    public function render_lla_max_retries_field() {
        $option_name = Guard_Dog_Limit_Login_Attempts::OPTION_MAX_RETRIES;
        $value = get_option($option_name, 5);
        ?>
        <input type="number" name="<?php echo esc_attr($option_name); ?>" value="<?php echo esc_attr($value); ?>" min="1" step="1" class="small-text" />
        <p class="description"><?php esc_html_e('Number of attempts allowed before locking out the IP address.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render the number field for Lockout Duration.
     *
     * @since 1.8.0
     */
    public function render_lla_lockout_duration_field() {
        $option_name = Guard_Dog_Limit_Login_Attempts::OPTION_LOCKOUT_DURATION;
        $value = get_option($option_name, 15);
        ?>
        <input type="number" name="<?php echo esc_attr($option_name); ?>" value="<?php echo esc_attr($value); ?>" min="1" step="1" class="small-text" />
        <p class="description"><?php esc_html_e('Duration in minutes for which the IP address will be locked out.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render the Activity Log Viewer page.
     *
     * @since 1.6.0
     */
    public function render_log_viewer_page() {
        // Ensure the List Table class file is loaded.
        require_once GUARD_DOG_PATH . 'includes/admin/class-activity-log-list-table.php';

        // Instantiate the list table FIRST
        $log_list_table = new Guard_Dog_Activity_Log_List_Table();

        // Handle Clear All Logs action (now a GET action)
        if (isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) === 'guard_dog_clear_all_logs') {
            // Verify nonce for clear all logs action - fail early if missing or invalid
            if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'guard_dog_clear_all_logs_action')) {
                return; // Exit early if nonce is missing or invalid
            }
            
            // Nonce is valid, proceed with action
            if (true) {
                if (current_user_can('manage_options')) {
                    global $wpdb;
                    // Validate table name statically - table names cannot be parameterized in prepared statements
                    $table_name = esc_sql($wpdb->prefix . 'guard_dog_logs');
                    // Execute DELETE directly without storing in variable
                    $result = $wpdb->query("DELETE FROM $table_name"); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Table operations require direct queries, names cannot be parameterized

                    if ($result !== false) {
                        add_settings_error('guard_dog_logs', 'logs_cleared', __('All activity logs have been cleared.', 'guard-dog'), 'updated');
                    } else {
                        add_settings_error('guard_dog_logs', 'clear_failed', __('Failed to clear activity logs. Database error: ', 'guard-dog') . $wpdb->last_error, 'error');
                    }
                } else {
                    add_settings_error('guard_dog_logs', 'capability_fail', __('You do not have permission to clear logs.', 'guard-dog'), 'error');
                }
            } else {
                add_settings_error('guard_dog_logs', 'nonce_fail', __('Security check failed for clear logs. Please try again.', 'guard-dog'), 'error');
            }
            // Redirect after processing to remove action from URL
            wp_safe_redirect(admin_url('admin.php?page=' . self::LOG_PAGE_SLUG));
            exit;
        }

        // Handle Bulk Delete action by checking GET parameters directly
        $action_taken = '';
        if (isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) !== '-1') {
            $action_taken = sanitize_text_field(wp_unslash($_GET['action']));
        } elseif (isset($_GET['action2']) && sanitize_text_field(wp_unslash($_GET['action2'])) !== '-1') {
            $action_taken = sanitize_text_field(wp_unslash($_GET['action2']));
        }

        if ($action_taken === 'bulk_delete') {
            // Verify WP_List_Table's bulk action nonce.
            // The plural name in Guard_Dog_Activity_Log_List_Table is now 'guard_dog_log_entries_plural'
            $nonce_action_string = 'bulk-guard_dog_log_entries_plural';
            check_admin_referer($nonce_action_string); 
            
            if (current_user_can('manage_options')) {
                // log_ids will be in $_GET when form method is GET
                $log_ids_to_delete = isset($_GET['log_ids']) ? array_map('absint', wp_unslash((array) $_GET['log_ids'])) : [];
                $log_ids_to_delete = array_filter($log_ids_to_delete);

                if (!empty($log_ids_to_delete)) {
                    global $wpdb;
                    // Use individual deletes to avoid complex prepared statement issues
                    $deleted_count = 0;
                    $table_name = esc_sql($wpdb->prefix . 'guard_dog_logs');
                    
                    foreach ($log_ids_to_delete as $log_id) {
                        $delete_result = $wpdb->delete( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk delete operations require direct queries
                            $table_name,
                            array('id' => $log_id),
                            array('%d')
                        );
                        if ($delete_result !== false) {
                            $deleted_count++;
                        }
                    }
                    $result = $deleted_count;

                    if ($result !== false) {
                        // Translators: %d is the number of log entries deleted.
                        add_settings_error('guard_dog_logs', 'logs_deleted', sprintf(_n('%d log entry deleted.', '%d log entries deleted.', $result, 'guard-dog'), $result), 'updated');
                    } else {
                        add_settings_error('guard_dog_logs', 'delete_failed', __('Failed to delete selected log entries. Database error: ', 'guard-dog') . $wpdb->last_error, 'error');
                    }
                } else {
                    add_settings_error('guard_dog_logs', 'no_logs_selected', __('No log entries selected for deletion.', 'guard-dog'), 'warning');
                }
            } else {
                 add_settings_error('guard_dog_logs', 'capability_fail_bulk', __('You do not have permission to delete logs.', 'guard-dog'), 'error');
            }
            // Redirect after processing to remove action parameters from URL and show messages
            // Using a simple redirect like for 'Clear All Logs' to avoid issues with remove_query_arg.
            
            // Forcefully clean any output buffers before redirecting // Temporarily removing for testing
            // while (ob_get_level() > 0) {
            //    ob_end_clean();
            // }
            wp_safe_redirect(admin_url('admin.php?page=' . self::LOG_PAGE_SLUG));
            exit;
        }

        // Prepare items for display AFTER actions are handled and redirected
        $log_list_table->prepare_items();

        $this->render_activity_log_viewer($log_list_table);
    }

    /**
     * Sanitize a newline-separated list of items (e.g., IPs, usernames).
     *
     * @since 1.3.0
     * @param string $input The input string from the textarea.
     * @return string Sanitized string with one item per line OR comma-separated string.
     */
    public function sanitize_newline_list($input) {
        // This function is now used for both user lists (comma-separated expected from tag input's hidden field)
        // and potentially other future newline-separated textareas.
        // We need to determine the format based on context or make it robust for both.
        // For now, let's assume if it contains commas but no newlines, it's the tag input.
        // If it contains newlines, it's a textarea. This is brittle.

        // A better approach might be to have separate sanitizers or pass context.
        // Let's stick to the tag input format (comma-separated) for user lists for now.

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

        // Assume comma-separated input from the tag field
        $items = explode(",", $input);
        $sanitized_items = [];
        foreach ($items as $item) {
            $trimmed_item = trim($item);
            if (!empty($trimmed_item)) {
                // Basic sanitization, further validation happens during usage
                // For usernames, ensure they are valid login characters
                 if (validate_username($trimmed_item)) { // Check if it's a potentially valid username format
                     $sanitized_items[] = sanitize_user($trimmed_item, true); // Sanitize strictly
                 }
                 // Optionally log/warn about invalid usernames removed?
            }
        }
        // Return comma-separated string
        return implode(",", array_unique($sanitized_items));
    }

    /**
     * Sanitize a newline-separated list of IP addresses or CIDR ranges.
     *
     * @since 1.3.0
     * @param string $input The input string from the textarea.
     * @return string Sanitized string with one valid IP/CIDR per line.
     */
    public function sanitize_ip_list($input) {
        if (empty($input)) {
            return '';
        }
        $lines = explode("\n", $input);
        $sanitized_lines = [];
        foreach ($lines as $line) {
            $trimmed_line = trim($line);
            if (!empty($trimmed_line)) {
                // Very basic validation: Check if it looks like an IP or CIDR
                // More robust validation (filter_var) happens during usage
                if (preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}(\/[0-9]{1,2})?$/', $trimmed_line)) {
                    $sanitized_lines[] = $trimmed_line;
                } 
                // Could add IPv6 validation here too if needed
            }
        }
        return implode("\n", array_unique($sanitized_lines));
    }

    /**
     * Sanitize positive integer input.
     *
     * @since 1.5.0
     * @param mixed $value Input value.
     * @return int Sanitized positive integer.
     */
    public function sanitize_positive_integer($value) {
        $value = absint($value); // Ensure it's a non-negative integer
        return ($value > 0) ? $value : 1; // Ensure it's at least 1
    }

    /**
     * Sanitize CAPTCHA threshold value.
     *
     * @since 1.2.0
     * @param mixed $value Input value.
     * @return float Sanitized threshold between 0.0 and 1.0.
     */
    public function sanitize_captcha_threshold($value) {
        $value = floatval($value);
        return max(0.0, min(1.0, $value)); // Clamp between 0.0 and 1.0
    }

    /**
     * Render CAPTCHA section header.
     *
     * @since 1.2.0
     */
    public function render_captcha_section_header() {
        ?>
        <p><?php esc_html_e('Configure CAPTCHA protection for login, registration, and password reset forms. Choose from multiple providers including Google reCAPTCHA and Cloudflare Turnstile.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA provider field.
     *
     * @since 1.2.0
     */
    public function render_captcha_provider_field() {
        $current_provider = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_PROVIDER, 'none');
        $providers = Guard_Dog_Captcha::get_available_providers();
        ?>
        <select id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_PROVIDER); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_PROVIDER); ?>">
            <?php foreach ($providers as $value => $label): ?>
                <option value="<?php echo esc_attr($value); ?>"<?php selected($current_provider, $value, false); ?>><?php echo esc_html($label); ?></option>
            <?php endforeach; ?>
        </select>
        <p class="description"><?php esc_html_e('Select the CAPTCHA provider you want to use. Note: Cloudflare Turnstile is a privacy-focused alternative to Google reCAPTCHA.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA site key field.
     *
     * @since 1.2.0
     */
    public function render_captcha_site_key_field() {
        $site_key = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SITE_KEY, '');
        ?>
        <input type="text" id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SITE_KEY); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SITE_KEY); ?>" value="<?php echo esc_attr($site_key); ?>" class="regular-text" autocomplete="off" />
        <p class="description"><?php esc_html_e('Enter your CAPTCHA site key (public key). Get this from your provider\'s dashboard.', 'guard-dog'); ?></p>
        <div class="captcha-setup-links guard-dog-captcha-setup-links">
            <a href="https://www.google.com/recaptcha/admin" target="_blank"><?php esc_html_e('Get Google reCAPTCHA Keys', 'guard-dog'); ?></a> | 
            <a href="https://dashboard.hcaptcha.com/sites" target="_blank"><?php esc_html_e('Get hCaptcha Keys', 'guard-dog'); ?></a> | 
            <a href="https://dash.cloudflare.com/?to=/:account/turnstile" target="_blank"><?php esc_html_e('Get Cloudflare Turnstile Keys', 'guard-dog'); ?></a>
        </div>
        <?php
    }

    /**
     * Render CAPTCHA secret key field.
     *
     * @since 1.2.0
     */
    public function render_captcha_secret_key_field() {
        $secret_key = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SECRET_KEY, '');
        ?>
        <input type="password" id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SECRET_KEY); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SECRET_KEY); ?>" value="<?php echo esc_attr($secret_key); ?>" class="regular-text" autocomplete="new-password" />
        <p class="description"><?php esc_html_e('Enter your CAPTCHA secret key (private key). This is kept secure and used for server-side verification.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA theme field.
     *
     * @since 1.2.0
     */
    public function render_captcha_theme_field() {
        $theme = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_THEME, 'light');
        $themes = [
            'light' => __('Light', 'guard-dog'),
            'dark' => __('Dark', 'guard-dog')
        ];
        ?>
        <select id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_THEME); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_THEME); ?>">
            <?php foreach ($themes as $value => $label): ?>
                <option value="<?php echo esc_attr($value); ?>"<?php selected($theme, $value, false); ?>><?php echo esc_html($label); ?></option>
            <?php endforeach; ?>
        </select>
        <p class="description"><?php esc_html_e('Choose the visual theme for the CAPTCHA widget.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA size field.
     *
     * @since 1.2.0
     */
    public function render_captcha_size_field() {
        $size = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SIZE, 'normal');
        $sizes = [
            'normal' => __('Normal', 'guard-dog'),
            'compact' => __('Compact', 'guard-dog')
        ];
        ?>
        <select id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SIZE); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_SIZE); ?>">
            <?php foreach ($sizes as $value => $label): ?>
                <option value="<?php echo esc_attr($value); ?>"<?php selected($size, $value, false); ?>><?php echo esc_html($label); ?></option>
            <?php endforeach; ?>
        </select>
        <p class="description"><?php esc_html_e('Choose the size of the CAPTCHA widget (applies to reCAPTCHA v2 and hCaptcha).', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA threshold field.
     *
     * @since 1.2.0
     */
    public function render_captcha_threshold_field() {
        $threshold = get_option(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_V3_THRESHOLD, 0.5);
        ?>
        <input type="number" id="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_V3_THRESHOLD); ?>" name="<?php echo esc_attr(Guard_Dog_Admin_Settings::OPTION_CAPTCHA_V3_THRESHOLD); ?>" value="<?php echo esc_attr($threshold); ?>" min="0" max="1" step="0.1" class="small-text" />
        <p class="description"><?php esc_html_e('Set the minimum score required for reCAPTCHA v3 (0.0 = likely bot, 1.0 = likely human). Recommended: 0.5. Only applies to reCAPTCHA v3.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA enterprise field.
     *
     * @since 1.2.0
     */
    public function render_captcha_enterprise_field() {
        $use_enterprise = get_option('guard_dog_captcha_use_enterprise', false);
        ?>
        <input type="checkbox" id="guard_dog_captcha_use_enterprise" name="guard_dog_captcha_use_enterprise" value="1" <?php checked(1, $use_enterprise, false); ?> />
        <label for="guard_dog_captcha_use_enterprise"><?php esc_html_e('Use reCAPTCHA Enterprise API (recommended)', 'guard-dog'); ?></label>
        <p class="description"><?php esc_html_e('Enable this to use Google\'s Enterprise reCAPTCHA API. If having issues, try disabling this to use the standard API. Only applies to reCAPTCHA v3.', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render CAPTCHA error message field.
     *
     * @since 1.2.0
     */
    public function render_captcha_error_message_field() {
        $error_message = get_option(self::OPTION_CAPTCHA_ERROR_MESSAGE, __('Please complete the CAPTCHA verification.', 'guard-dog'));
        ?>
        <input type="text" id="<?php echo esc_attr(self::OPTION_CAPTCHA_ERROR_MESSAGE); ?>" name="<?php echo esc_attr(self::OPTION_CAPTCHA_ERROR_MESSAGE); ?>" value="<?php echo esc_attr($error_message); ?>" class="regular-text" />
        <p class="description"><?php esc_html_e('Custom error message shown when CAPTCHA verification fails.', 'guard-dog'); ?></p>
        
        <?php
        // Add debug information if CAPTCHA class exists (always show for troubleshooting)
        if (class_exists('Guard_Dog_Captcha')) {
            $debug_info = Guard_Dog_Captcha::instance()->get_debug_info();
            ?>
            <div class="notice notice-info inline guard-dog-captcha-debug">
                <h4><?php esc_html_e('CAPTCHA Debug Information', 'guard-dog'); ?></h4>
                <p><strong><?php esc_html_e('Provider:', 'guard-dog'); ?></strong> <?php echo esc_html($debug_info['provider']); ?></p>
                <p><strong><?php esc_html_e('Site Key:', 'guard-dog'); ?></strong> <?php echo esc_html($debug_info['site_key_prefix']); ?> (<?php echo esc_html($debug_info['site_key_length']); ?> <?php esc_html_e('characters', 'guard-dog'); ?>)</p>
                <p><strong><?php esc_html_e('Secret Key Length:', 'guard-dog'); ?></strong> <?php echo esc_html($debug_info['secret_key_length']); ?> <?php esc_html_e('characters', 'guard-dog'); ?></p>
                <p><strong><?php esc_html_e('Current Domain:', 'guard-dog'); ?></strong> <?php echo esc_html($debug_info['current_domain']); ?></p>
                <?php if ($debug_info['provider'] === 'recaptcha_v3'): ?>
                    <p><strong><?php esc_html_e('v3 Threshold:', 'guard-dog'); ?></strong> <?php echo esc_html($debug_info['v3_threshold']); ?></p>
                <?php endif; ?>
                <p><em><?php esc_html_e('Make sure the domain above is configured in your reCAPTCHA console and the provider matches your key type.', 'guard-dog'); ?></em></p>
                
                <?php
                // Add troubleshooting tips
                ?>
                <h5><?php esc_html_e('Common Issues:', 'guard-dog'); ?></h5>
                <ul class="guard-dog-troubleshooting-list">
                    <li><strong><?php esc_html_e('"Invalid key type" error:', 'guard-dog'); ?></strong> <?php esc_html_e('Provider type doesn\'t match your Google Console setup', 'guard-dog'); ?></li>
                    <li><strong><?php esc_html_e('Domain mismatch:', 'guard-dog'); ?></strong> <?php esc_html_e('Add the exact domain above to your reCAPTCHA console configuration', 'guard-dog'); ?></li>
                    <li><strong><?php esc_html_e('Still having issues?', 'guard-dog'); ?></strong> <a href="https://dash.cloudflare.com/?to=/:account/turnstile" target="_blank"><?php esc_html_e('Try Cloudflare Turnstile instead', 'guard-dog'); ?></a></li>
                </ul>
            </div>
            <?php
        }
    }

    /**
     * Render debug section header.
     * 
     * Displays debug configuration instructions and current debug status.
     * Also shows database table status for troubleshooting.
     *
     * @since 1.2.0
     */
    public function render_debug_section_header() {
        ?>
        <p><?php esc_html_e('Enable debug logging to troubleshoot issues with Guard Dog features. Debug logs will be written to the WordPress debug log (wp-content/debug.log)', 'guard-dog'); ?></p>
        
        <?php
        // Check database table status first
        $this->render_database_status();
        
        // Show debug statistics if debugging is enabled
        if (class_exists('Guard_Dog_Debug')) {
            $debug = Guard_Dog_Debug::instance();
            $stats = $debug->get_debug_stats();
            
            if ($stats['enabled']) {
                ?>
                <div class="notice notice-info inline guard-dog-debug-status">
                    <h4><?php esc_html_e('Debug Status', 'guard-dog'); ?></h4>
                    <ul>
                        <li><strong><?php esc_html_e('Status:', 'guard-dog'); ?></strong> <?php echo esc_html($stats['enabled'] ? __('Enabled', 'guard-dog') : __('Disabled', 'guard-dog')); ?></li>
                        <li><strong><?php esc_html_e('Level:', 'guard-dog'); ?></strong> <?php echo esc_html(ucfirst($stats['level'])); ?></li>
                        <li><strong><?php esc_html_e('Log File:', 'guard-dog'); ?></strong> <?php echo esc_html($stats['log_exists'] ? __('Exists', 'guard-dog') : __('Not Created', 'guard-dog')); ?></li>
                        <?php if ($stats['log_exists']): ?>
                            <li><strong><?php esc_html_e('Log Size:', 'guard-dog'); ?></strong> <?php echo esc_html(size_format($stats['log_size'])); ?></li>
                        <?php endif; ?>
                        <li><strong><?php esc_html_e('Writable:', 'guard-dog'); ?></strong> <?php echo esc_html($stats['log_writable'] ? __('Yes', 'guard-dog') : __('No', 'guard-dog')); ?></li>
                    </ul>
                    
                    <?php if ($stats['log_exists']): ?>
                        <p>
                            <a href="<?php echo esc_url(wp_nonce_url(admin_url('admin-post.php?action=guard_dog_view_debug_log'), 'guard_dog_debug_log')); ?>" class="button button-secondary" target="_blank"><?php esc_html_e('View Debug Log', 'guard-dog'); ?></a>
                            <a href="<?php echo esc_url(wp_nonce_url(admin_url('admin-post.php?action=guard_dog_clear_debug_log'), 'guard_dog_debug_log')); ?>" class="button button-secondary guard-dog-clear-log-btn"><?php esc_html_e('Clear Debug Log', 'guard-dog'); ?></a>
                        </p>
                    <?php endif; ?>
                </div>
                <?php
            }
        }
    }

    /**
     * Render database status information.
     * 
     * Checks for the existence of required Guard Dog database tables
     * and displays warnings if any are missing with instructions to fix.
     *
     * @since 1.2.0
     */
    private function render_database_status() {
        global $wpdb;
        
        $tables_to_check = [
            'guard_dog_logs' => esc_html__('Activity Log Table', 'guard-dog'),
            'guard_dog_limit_login_attempts' => esc_html__('Login Attempts Table', 'guard-dog')
        ];
        
        $missing_tables = [];
        
        foreach ($tables_to_check as $table_suffix => $table_description) {
            $table_name = $wpdb->prefix . $table_suffix;
            // Execute SHOW TABLES directly without storing in variable
            if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) !== $table_name) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Table existence check requires direct query
                $missing_tables[] = $table_description;
            }
        }
        
        if (!empty($missing_tables)) {
            ?>
            <div class="notice notice-error inline guard-dog-database-error">
                <h4><?php esc_html_e('Database Issue Detected', 'guard-dog'); ?></h4>
                <p><strong><?php esc_html_e('Missing Tables:', 'guard-dog'); ?></strong> <?php echo esc_html(implode(', ', $missing_tables)); ?></p>
                <p><?php esc_html_e('Some Guard Dog features may not work correctly because required database tables are missing.', 'guard-dog'); ?></p>
                <p><strong><?php esc_html_e('Solution:', 'guard-dog'); ?></strong>
                    <a href="<?php echo esc_url(admin_url('plugins.php')); ?>"><?php esc_html_e('Deactivate and reactivate the Guard Dog plugin', 'guard-dog'); ?></a>
                    <?php esc_html_e('to recreate the missing tables.', 'guard-dog'); ?>
                </p>
            </div>
            <?php
        } else {
            ?>
            <div class="notice notice-success inline guard-dog-database-success">
                <p><strong><?php esc_html_e('Database Status:', 'guard-dog'); ?></strong> <?php esc_html_e('All required tables are present.', 'guard-dog'); ?></p>
            </div>
            <?php
        }
    }

    /**
     * Render debug enabled field.
     * 
     * Displays checkbox to enable/disable debug logging with description.
     *
     * @since 1.2.0
     */
    public function render_debug_enabled_field() {
        $debug_enabled = get_option('guard_dog_debug_enabled', false);
        ?>
        <input type="checkbox" id="guard_dog_debug_enabled" name="guard_dog_debug_enabled" value="1" <?php checked(1, $debug_enabled, false); ?> />
        <label for="guard_dog_debug_enabled"><?php esc_html_e('Enable debug logging', 'guard-dog'); ?></label>
        <p class="description"><?php esc_html_e('Enable detailed logging for troubleshooting. Logs are stored in the WordPress debug log (wp-content/debug.log)', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render debug level field.
     * 
     * Displays dropdown to select debug logging level (Error, Warning, Info, Debug).
     *
     * @since 1.2.0
     */
    public function render_debug_level_field() {
        $debug_level = get_option('guard_dog_debug_level', 'error');
        $levels = [
            'error' => __('Error', 'guard-dog'),
            'warning' => __('Warning', 'guard-dog'),
            'info' => __('Info', 'guard-dog'),
            'debug' => __('Debug', 'guard-dog')
        ];
        ?>
        <select id="guard_dog_debug_level" name="guard_dog_debug_level">
            <?php foreach ($levels as $value => $label): ?>
                <option value="<?php echo esc_attr($value); ?>"<?php selected($debug_level, $value, false); ?>><?php echo esc_html($label); ?></option>
            <?php endforeach; ?>
        </select>
        <p class="description"><?php esc_html_e('Set the minimum log level to record. Higher levels include lower levels (Debug includes all, Error only includes errors).', 'guard-dog'); ?></p>
        <?php
    }

    /**
     * Render the settings page content
     *
     * @param object|null $temp_access_feature The temporary access feature instance
     */
    private function render_settings_page_content($temp_access_feature) {
        $option_group = self::OPTION_GROUP;
        $page_slug = self::PAGE_SLUG;
        $debug_log_cleared = isset($_GET['debug_log_cleared']) && sanitize_text_field(wp_unslash($_GET['debug_log_cleared'])) === '1';
        ?>
        <?php if ($debug_log_cleared): ?>
            <div class="notice notice-success is-dismissible">
                <p><?php esc_html_e('Debug log cleared successfully.', 'guard-dog'); ?></p>
            </div>
        <?php endif; ?>

        <div class="wrap">
            <h1><?php esc_html_e('Guard Dog Settings', 'guard-dog'); ?></h1>

            <?php // Optional: Add tabs here in the future if needed ?>

            <!-- Form for standard settings managed by Settings API -->
            <form method="post" action="options.php">
                <?php
                settings_fields($option_group); // Output nonce, action, option_page fields for the group
                do_settings_sections($page_slug); // Render sections and fields registered for this page slug
                submit_button(__('Save Guard Dog Settings', 'guard-dog')); // General save button
                ?>
            </form>

            <hr>

            <!-- Section for Temporary Access Link (managed via admin-post) -->
            <h2><?php esc_html_e('Temporary Access Link', 'guard-dog'); ?></h2>
            <?php
            // Call the method from the Temp_Access feature class to render its content
            if (isset($temp_access_feature) && method_exists($temp_access_feature, 'render_settings_content')) {
                $temp_access_feature->render_settings_content();
            }
            ?>

            <?php // Add sections for other features here in the future... ?>

        </div>
        <?php
    }

    /**
     * Render the activity log viewer
     *
     * @param object $log_list_table The log list table instance
     */
    private function render_activity_log_viewer($log_list_table) {
        // Check if logs were cleared (for display purposes only)
        $logs_cleared = false;
        if (isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) === 'guard_dog_clear_all_logs') {
            if (isset($_GET['_wpnonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'guard_dog_clear_all_logs_action')) {
                $logs_cleared = true;
            }
        }
        ?>
        <div class="wrap">
            <h1><?php esc_html_e('Guard Dog - Activity Log', 'guard-dog'); ?></h1>
            <?php settings_errors('guard_dog_logs'); ?>

            <?php // Clear All Logs button - now a GET link ?>
            <form method="get" class="guard-dog-clear-logs-form">
                 <input type="hidden" name="page" value="<?php echo esc_attr(self::LOG_PAGE_SLUG); ?>" />
                 <input type="hidden" name="action" value="guard_dog_clear_all_logs" />
                 <?php wp_nonce_field('guard_dog_clear_all_logs_action'); // _wpnonce will be added by this function ?>
                 <button type="submit" class="button button-link-delete guard-dog-clear-all-logs-btn">
                     <?php esc_html_e('Clear All Logs', 'guard-dog'); ?>
                 </button>
            </form>

            <?php if ($log_list_table): ?>
                <form id="guard-dog-activity-log-form" method="get"> 
                    <input type="hidden" name="page" value="<?php echo esc_attr(self::LOG_PAGE_SLUG); ?>" />
                    <?php // Removed our custom nonce, WP_List_Table handles its own for bulk actions via GET ?>
                    <?php
                    $log_list_table->display(); // This will include search_box, extra_tablenav (with filters), and the table itself.
                    ?>
                </form>
            <?php else: ?>
                <p><?php esc_html_e('Unable to load activity log table.', 'guard-dog'); ?></p>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * Add screen options for the Activity Log table.
     *
     * @since 1.6.0
     */
    public function add_screen_options() {
        $option = 'per_page';
        $args = [
            'label' => __('Activity Logs', 'guard-dog'),
            'default' => 20,
            'option' => 'guard_dog_logs_per_page'
        ];
        add_screen_option($option, $args);
    }

    /**
     * Handle saving of screen options.
     *
     * @since 1.6.0
     * @param mixed $status Screen option value. Default false.
     * @param string $option The option name.
     * @param mixed $value The number of rows per page.
     * @return mixed Screen option value.
     */
    public function set_screen_option($status, $option, $value) {
        if ($option == 'guard_dog_logs_per_page') {
            return $value;
        }
        return $status;
    }

} // End class Guard_Dog_Admin_Settings