<?php
/**
 * Core plugin class.
 *
 * @package WebtaruSiteOptionsLoginSecurity
 */

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

class WTOLS_Plugin
{
	const OPTION_KEY = 'wtols_settings';
	const TRANSIENT_REDIRECT = 'wtols_activation_redirect';
	const NONCE_ACTION_SAVE = 'wtols_save_settings';

	/**
	 * Singleton instance.
	 *
	 * @var WTOLS_Plugin|null
	 */
	private static $instance = null;

	/**
	 * Whether wp-login.php is being loaded through the custom endpoint.
	 *
	 * @var bool
	 */
	private $custom_login_request = false;

	/**
	 * Supported simple field keys.
	 *
	 * @var string[]
	 */
	private $field_keys = array('phone', 'phone_1', 'phone_2', 'email', 'email_1', 'email_2', 'address', 'fax');

	/**
	 * Login limiter constants.
	 */
	const LIMITER_ATTEMPTS_PREFIX = 'wtols_attempts_';
	const LIMITER_LOCKOUT_PREFIX = 'wtols_lockout_';

	/**
	 * Captured admin bar nodes.
	 *
	 * @var array
	 */
	public $captured_nodes = array();

	public static function instance()
	{
		if (null === self::$instance) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	public static function activate()
	{
		$defaults = self::get_default_options();
		$current = get_option(self::OPTION_KEY, array());

		if (!is_array($current)) {
			$current = array();
		}

		update_option(self::OPTION_KEY, wp_parse_args($current, $defaults));
		set_transient(self::TRANSIENT_REDIRECT, 1, 30);
	}

	public static function deactivate()
	{
		flush_rewrite_rules();
	}

	private function __construct()
	{
		add_action('admin_menu', array($this, 'register_admin_menu'));
		add_action('admin_init', array($this, 'maybe_save_settings'));
		add_action('admin_init', array($this, 'maybe_redirect_after_activation'));
		add_action('wp_dashboard_setup', array($this, 'register_dashboard_widget'));
		add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
		// add_action('admin_enqueue_scripts', array($this, 'enqueue_media_replace_assets'));
		add_filter('admin_footer_text', array($this, 'filter_admin_footer_text'));
		add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
		add_action('init', array($this, 'check_ip_whitelist_blacklist'), 0);
		add_action('init', array($this, 'maybe_block_wp_admin_direct_access'), 0);
		add_action('init', array($this, 'maybe_load_custom_login'), 1);
		add_action('init', array($this, 'register_shortcodes'));
		add_action('login_init', array($this, 'maybe_block_default_login'), 1);
		add_action('init', array($this, 'maybe_block_login_by_ip'), 2);
		add_action('login_init', array($this, 'maybe_block_login_by_ip'), 2);
		add_action('login_enqueue_scripts', array($this, 'render_login_custom_styles'));
		add_filter('login_headerurl', array($this, 'filter_login_header_url'));
		add_filter('login_headertext', array($this, 'filter_login_header_text'));
		add_filter('login_errors', array($this, 'filter_login_errors'));
		add_filter('login_display_language_dropdown', '__return_false');
		add_action('vc_before_init', array($this, 'register_wpbakery_element'));
		add_action('elementor/widgets/register', array($this, 'register_elementor_widgets'));

		/* v2.0 — Schema.org JSON-LD */
		add_action('wp_head', array($this, 'render_schema_jsonld'));

		/* v2.0 — Login attempt limiter */
		add_action('wp_login_failed', array($this, 'track_failed_login'));
		add_filter('authenticate', array($this, 'check_login_lockout'), 30, 3);
		add_action('wp_login', array($this, 'clear_login_attempts'), 10, 2);
		add_action('wp_ajax_wtols_unlock_ip', array($this, 'ajax_unlock_ip'));
		add_action('wp_ajax_wtols_clear_security_logs', array($this, 'ajax_clear_security_logs'));
		add_action('wp_ajax_wtols_export_security_logs', array($this, 'ajax_export_security_logs'));
		add_action('wp_ajax_wtols_clear_locked_ips', array($this, 'ajax_clear_locked_ips'));
		add_action('wp_ajax_wtols_save_admin_notes', array($this, 'ajax_save_admin_notes'));
		add_action('wp_ajax_wtols_save_admin_tasks', array($this, 'ajax_save_admin_tasks'));

		/* v3.0 — Security & Performance */
		add_filter('xmlrpc_enabled', array($this, 'filter_xmlrpc_enabled'));
		add_action('login_enqueue_scripts', array($this, 'enqueue_captcha_scripts'));
		add_action('login_form', array($this, 'render_captcha_field'));
		add_filter('authenticate', array($this, 'verify_captcha'), 20, 3);
		add_action('admin_bar_menu', array($this, 'add_admin_bar_clear_cache'), 100);
		add_action('admin_post_wtols_clear_cache', array($this, 'handle_clear_cache'));
		add_action('updated_option', array($this, 'flush_cache_on_save'), 10, 3);
		add_action('admin_notices', array($this, 'render_admin_notices'));

		/* v4.0 — Version Hiding & Hardening */
		add_action('init', array($this, 'handle_version_hiding'));

		/* v3.1 — Styling & Utilities */
		add_action('init', array($this, 'init_utilities'), 1);
		add_action('wp_head', array($this, 'render_styling_css_vars'));
		add_filter('post_row_actions', array($this, 'add_duplicate_post_link'), 10, 2);
		add_filter('page_row_actions', array($this, 'add_duplicate_post_link'), 10, 2);
		add_action('post_submitbox_misc_actions', array($this, 'add_duplicate_post_button_submitbox'));
		add_action('admin_post_wtols_duplicate_post', array($this, 'handle_duplicate_post'));
		add_action('admin_post_wtols_delete_all_comments', array($this, 'handle_delete_all_comments'));
		add_action('admin_post_wtols_export_settings', array($this, 'handle_export_settings'));
		add_action('admin_post_wtols_import_settings', array($this, 'handle_import_settings'));
		add_action('admin_post_wtols_reset_settings', array($this, 'handle_reset_settings'));
		add_action('admin_post_wtols_db_cleanup', array($this, 'handle_db_cleanup'));
		add_action('admin_post_wtols_add_redirect', array($this, 'handle_add_redirect'));
		add_action('admin_post_wtols_delete_redirect', array($this, 'handle_delete_redirect'));
		add_action('admin_post_wtols_export_redirects', array($this, 'handle_export_redirects'));
		add_action('admin_post_wtols_import_redirects', array($this, 'handle_import_redirects'));
		add_action('admin_post_wtols_bulk_delete_redirects', array($this, 'handle_bulk_delete_redirects'));
		add_action('admin_post_wtols_save_custom_css', array($this, 'handle_save_custom_css'));
		add_action('admin_post_wtols_save_custom_scripts', array($this, 'handle_save_custom_scripts'));

		/* v2.1.0 — New Features */
		add_action('template_redirect', array($this, 'handle_maintenance_mode'));
		add_action('wp_footer', array($this, 'render_sticky_whatsapp'), 98);
		add_action('wp_footer', array($this, 'render_rating_widget'), 97);
		add_action('wp_footer', array($this, 'render_back_to_top'), 96);
		add_action('wp_footer', array($this, 'render_mobile_bottom_buttons'), 95);
		add_action('wp_footer', array($this, 'render_sticky_vertical_btn'), 94);
		add_action('wp_login_failed', array($this, 'log_failed_login_attempt'));
		add_action('admin_menu', array($this, 'organize_admin_menu'), 999);

		/* Custom Code */
		add_action('wp_head', array($this, 'render_custom_header_code'), 99);
		add_action('wp_body_open', array($this, 'render_custom_body_code'), 1);
		add_action('wp_head', array($this, 'render_custom_css'), 100);
		add_action('wp_footer', array($this, 'render_custom_footer_code'), 99);

		/* Additional Features */
		add_action('admin_bar_menu', array($this, 'add_admin_bar_maintenance_mode'), 101);
		add_action('admin_bar_menu', array($this, 'add_admin_bar_search_visibility'), 102);
		add_action('admin_bar_menu', array($this, 'capture_admin_bar_nodes'), 99999);
		add_action('admin_bar_menu', array($this, 'clean_up_admin_bar'), 100000);
		add_filter('upload_mimes', array($this, 'allow_svg_upload'));
		add_filter('wp_check_filetype_and_ext', array($this, 'check_svg_filetype'), 10, 4);
		add_filter('wp_handle_upload_prefilter', array($this, 'sanitize_svg_upload'));
		add_action('template_redirect', array($this, 'handle_disable_author_archives'), 1);
		add_action('template_redirect', array($this, 'handle_custom_redirects'), 1);
		add_filter('author_link', array($this, 'filter_author_link'), 10, 3);
		add_filter('the_content', array($this, 'open_external_links_new_tab'));
		add_filter('wp_setup_nav_menu_item', array($this, 'dynamic_login_logout_menu_item'));
		add_filter('login_redirect', array($this, 'handle_custom_login_redirect'), 10, 3);
		add_filter('login_message', array($this, 'filter_login_message'));
		add_action('wp_logout', array($this, 'handle_custom_logout_redirect'), 999);
		add_action('phpmailer_init', array($this, 'configure_smtp'));
		add_filter('wp_mail_from', array($this, 'filter_mail_from'));
		add_filter('wp_mail_from_name', array($this, 'filter_mail_from_name'));
		add_action('wp_ajax_wtols_send_test_email', array($this, 'ajax_send_test_email'));
		add_action('template_redirect', array($this, 'redirect_404_to_home'), 1);
		add_filter('update_footer', array($this, 'custom_admin_footer_right_text'), 99);
		add_action('wp_enqueue_scripts', array($this, 'maybe_enqueue_auto_logout'));
		add_action('admin_enqueue_scripts', array($this, 'maybe_enqueue_auto_logout'));
		add_action('wp_ajax_wtols_keep_alive', array($this, 'ajax_keep_alive'));
		add_action('attachment_submitbox_misc_actions', array($this, 'render_media_replace_sidebar_form'));
		add_filter('media_row_actions',                 array($this, 'add_media_replace_row_action'), 10, 2);
		add_action('wp_ajax_wtols_replace_media',       array($this, 'handle_media_replace_upload'));
		add_filter('attachment_fields_to_edit',         array($this, 'add_media_replace_to_modal'), 10, 2);
		add_action('wp_login', array($this, 'send_login_notification'), 10, 2);
		add_action('init', array($this, 'run_basic_firewall'), 1);
		add_filter('rest_authentication_errors', array($this, 'restrict_rest_api_access'));
		add_action('admin_bar_menu', array($this, 'apply_zen_mode'), 100001);
		add_filter('plugin_row_meta', array($this, 'add_plugin_row_meta_links'), 10, 2);

		/* v2.6.0 — Supercharged Features */
		add_shortcode('wtols_copyright', array($this, 'shortcode_current_year'));
		$options = self::get_options();
		if (!empty($options['remove_query_strings'])) {
			add_filter('script_loader_src', array($this, 'remove_ver_query_string'), 999);
			add_filter('style_loader_src', array($this, 'remove_ver_query_string'), 999);
		}
		if (!empty($options['enable_auto_alt'])) {
			add_filter('wp_get_attachment_image_attributes', array($this, 'auto_alt_text'), 10, 2);
		}
		if (!empty($options['enable_content_protection'])) {
			add_action('wp_footer', array($this, 'render_content_protection_js'));
		}
		if (!empty($options['enable_duplicate_menu'])) {
			add_action('admin_footer-nav-menus.php', array($this, 'render_duplicate_menu_js'));
			add_action('admin_init', array($this, 'handle_menu_duplication'));
		}

		/* v2.7.0 — Heartbeat Control */
		add_action('init', array($this, 'manage_heartbeat_api'), 1);
		add_filter('heartbeat_settings', array($this, 'control_heartbeat_settings'));

		/* v2.7.0 — Email 2FA */
		add_filter('authenticate', array($this, 'handle_2fa_login_intercept'), 99, 3);
		add_action('login_form_wtols_2fa_verify', array($this, 'handle_2fa_verification'));

		// Cache bypass/exclusion integrations for custom login URL
		add_filter('rocket_cache_reject_uri', array($this, 'exclude_from_wp_rocket_cache'));
		add_filter('sgo_bypass_cache', array($this, 'exclude_from_sg_optimizer_cache'));
	}


	public static function get_default_options()
	{
		return array(
			'phone' => '',
			'phone_2' => '',
			'email' => get_option('admin_email'),
			'email_2' => '',
			'fax' => '',
			'address' => '',
			'address_link' => '',
			'logo_light_id' => 0,
			'logo_light_url' => '',
			'logo_dark_id' => 0,
			'logo_dark_url' => '',
			'map' => '',
			'social_links' => self::get_default_social_links(),
			'custom_social_links' => array(),
			'enable_fontawesome' => 1,
			'admin_footer_text' => '',
			'login_logo_id' => 0,
			'login_logo_url' => '',
			'login_background_id' => 0,
			'login_background_url' => '',
			'login_error_message' => 'Incorrect login details, please contact the website administrator or developer',
			'login_slug' => '',
			'login_secret_key' => '',
			'logo_id' => 0,
			'logo_url' => '',
			'business_hours' => self::get_default_business_hours(),
			'business_hours_freeform' => '',
			'business_hours_label' => 'Business Hours',
			'enable_schema' => 0,
			'limiter_enabled' => 0,
			'limiter_max_attempts' => 5,
			'limiter_lockout_duration' => 30,
			'limiter_message' => 'Too many failed login attempts. Please try again later.',
			'disable_xmlrpc' => 0,
			'captcha_type' => 'none',
			'captcha_site_key' => '',
			'captcha_secret_key' => '',
			'show_contact_icons' => 0,
			'icon_placement' => 'before',
			'icon_phone' => 'fa-solid fa-phone',
			'icon_phone_2' => 'fa-solid fa-phone',
			'icon_email' => 'fa-solid fa-envelope',
			'icon_email_2' => 'fa-solid fa-envelope',
			'icon_fax' => 'fa-solid fa-fax',
			'icon_address' => 'fa-solid fa-location-dot',
			'clear_cache_on_save' => 0,
			'admin_bar_clear_cache' => 0,
			'layout_style' => 'simple',
			'color_text' => '',
			'color_background' => '',
			'color_icon' => '',
			'disable_gutenberg' => 0,
			'disable_file_editor' => 0,
			'disable_comments_sitewide' => 0,
			'hidden_plugin_updates' => array(),
			'disabled_plugin_autoupdates' => array(),
			'enable_duplicator' => 0,
			'agency_mode' => 0,
			'agency_menu_name' => 'Dynamic Options',
			'agency_hide_icon' => 0,
			'hide_wp_version' => 0,
			'enable_maintenance' => 0,
			'maintenance_message' => 'Our website is currently undergoing scheduled maintenance. We will be back shortly. Thank you for your patience!',
			'enable_login_designer' => 0,
			'login_designer_layout' => 'default',
			'login_bg_image_id' => 0,
			'login_bg_image' => '',
			'enable_geo_blocking' => 0,
			'geo_block_type' => 'login',
			'geo_blocked_countries' => array(),
			'delete_data_on_uninstall' => 0,
			'hidden_admin_menus' => array(),
			'login_logs' => array(),
			'whatsapp_number' => '',
			'enable_sticky_whatsapp' => 0,
			'sticky_whatsapp_position' => 'right',
			'sticky_whatsapp_display' => 'both',
			'sticky_whatsapp_message' => '',
			'sticky_whatsapp_icon_size' => '32',
			'enable_rating_widget' => 0,
			'rating_widget_provider' => 'google',
			'rating_widget_icon_type' => 'icon',
			'rating_widget_image_url' => '',
			'rating_widget_score' => '5.0',
			'rating_widget_link' => '',
			'rating_widget_display' => 'desktop',
			'enable_back_to_top' => 0,
			'back_to_top_display' => 'both',
			'back_to_top_bg_color' => '#5cb85c',
			'back_to_top_icon_color' => '#ffffff',
			'back_to_top_shape' => 'square',
			'back_to_top_size' => '20',
			'enable_mobile_buttons' => 0,
			'mobile_button_1_text' => 'Call Now',
			'mobile_button_1_text_color' => '#ffffff',
			'mobile_button_1_link' => '',
			'mobile_button_1_color' => '#5cb85c',
			'mobile_button_2_text' => '',
			'mobile_button_2_text_color' => '#ffffff',
			'mobile_button_2_link' => '',
			'mobile_button_2_color' => '#0275d8',
			'enable_sticky_vertical_btn' => 0,
			'sticky_vertical_btn_text' => 'Feedback',
			'sticky_vertical_btn_icon' => 'fa-solid fa-comment-dots',
			'sticky_vertical_btn_id_class' => '',
			'sticky_vertical_btn_text_color' => '#ffffff',
			'sticky_vertical_btn_bg_color' => '#0073aa',
			'sticky_vertical_btn_icon_color' => '#ffffff',
			'sticky_vertical_btn_position' => '50',
			'custom_css' => '',
			'custom_header_code' => '',
			'custom_body_code' => '',
			'custom_footer_code' => '',
			'disable_update_emails' => 0,
			'admin_footer_right_text' => '',
			'disable_author_archives' => 0,
			'open_external_links_new_tab' => 0,
			'enable_login_logout_menu' => 0,
			'menu_login_url' => '',
			'enable_redirect_login' => 0,
			'redirect_after_login' => array(),
			'enable_redirect_logout' => 0,
			'redirect_after_logout' => array(),
			'custom_robots_txt' => '',
			'enable_smtp' => 0,
			'smtp_host' => '',
			'smtp_port' => '587',
			'smtp_secure' => 'tls',
			'smtp_user' => '',
			'smtp_pass' => '',
			'smtp_from_email' => '',
			'smtp_from_name' => '',
			'maintenance_heading' => 'Maintenance Mode',
			'redirect_404_home' => 0,
			'enable_media_replace' => 0,
			'xss_protection' => 0,
			'xss_mode' => 'basic',
			'disable_common_usernames' => 0,
			'enable_login_alerts' => 0,
			'enable_ip_lockout_alerts' => 0,
			'login_alert_email' => get_option('admin_email'),
			'enable_firewall' => 0,
			'restrict_rest_api' => 0,
			'admin_bar_zen_mode' => 0,
			'enable_content_protection' => 0,
			'remove_query_strings' => 0,
			'enable_auto_alt' => 0,
			'enable_duplicate_menu' => 0,
			'hidden_admin_bar_nodes' => array(),
			'enable_heartbeat_control' => 0,
			'heartbeat_interval' => 60,
			'heartbeat_disable_frontend' => 0,
			'heartbeat_disable_dashboard' => 0,
			'heartbeat_disable_editor' => 0,
			'enable_2fa' => 0,
			'2fa_roles' => array('administrator'),
			'enable_prefetch' => 0,
			'maintenance_bypass_key' => '',
			'enable_auto_logout' => 0,
			'auto_logout_idle_time' => 15,
			'auto_logout_roles' => array(),
			'ip_whitelist' => '',
			'ip_blacklist' => '',
			'block_login_page' => 0,
			'login_ip_whitelist' => '',
		);
	}

	public static function get_default_social_links()
	{
		return array(
			'facebook' => array('label' => 'Facebook', 'url' => '', 'icon' => 'fab fa-facebook-f'),
			'instagram' => array('label' => 'Instagram', 'url' => '', 'icon' => 'fab fa-instagram'),
			'x_twitter' => array('label' => 'X / Twitter', 'url' => '', 'icon' => 'fab fa-x-twitter'),
			'linkedin' => array('label' => 'LinkedIn', 'url' => '', 'icon' => 'fab fa-linkedin-in'),
			'youtube' => array('label' => 'YouTube', 'url' => '', 'icon' => 'fab fa-youtube'),
			'whatsapp' => array('label' => 'WhatsApp', 'url' => '', 'icon' => 'fab fa-whatsapp'),
		);
	}

	public static function get_default_business_hours()
	{
		$days = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
		$hours = array();
		foreach ($days as $day) {
			$hours[$day] = array(
				'enabled' => in_array($day, array('saturday', 'sunday'), true) ? 0 : 1,
				'open' => '09:00',
				'close' => '18:00',
			);
		}
		return $hours;
	}

	public static function get_options()
	{
		$options = get_option(self::OPTION_KEY, array());

		if (!is_array($options)) {
			$options = array();
		}

		$options = wp_parse_args($options, self::get_default_options());

		// Ensure safe_mode_secret is stable and unique per site using WP AUTH_KEY
		if (empty($options['safe_mode_secret'])) {
			$seed = defined('AUTH_KEY') ? AUTH_KEY : get_option('admin_email', 'wtols');
			$options['safe_mode_secret'] = 'wtols_' . substr(md5($seed), 0, 10);
		}

		if (empty($options['logo_light_id']) && !empty($options['logo_id'])) {
			$options['logo_light_id'] = absint($options['logo_id']);
			$options['logo_light_url'] = isset($options['logo_url']) ? esc_url_raw($options['logo_url']) : '';
		}

		$options['social_links'] = wp_parse_args(
			is_array($options['social_links']) ? $options['social_links'] : array(),
			self::get_default_social_links()
		);

		return $options;
	}

	public function register_admin_menu()
	{
		$options = self::get_options();
		$menu_label = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			? $options['agency_menu_name']
			: __('Webtaru Site Options', 'webtaru-site-options-login-security');

		// Register top-level parent menu
		add_menu_page(
			$menu_label,
			$menu_label,
			'manage_options',
			'wtols-settings',
			array($this, 'render_settings_page'),
			'dashicons-admin-generic',
			81
		);

		// Register first submenu item (overrides parent link to change its title)
		add_submenu_page(
			'wtols-settings',
			__('General Settings', 'webtaru-site-options-login-security'),
			__('General Settings', 'webtaru-site-options-login-security'),
			'manage_options',
			'wtols-settings',
			array($this, 'render_settings_page')
		);

		// Register redirects manager submenu item
		add_submenu_page(
			'wtols-settings',
			__('301 Redirects', 'webtaru-site-options-login-security'),
			__('301 Redirects', 'webtaru-site-options-login-security'),
			'manage_options',
			'wtols-redirects',
			array($this, 'render_redirects_page')
		);

		// Register custom css submenu item
		add_submenu_page(
			'wtols-settings',
			__('Custom CSS', 'webtaru-site-options-login-security'),
			__('Custom CSS', 'webtaru-site-options-login-security'),
			'manage_options',
			'wtols-custom-css',
			array($this, 'render_custom_css_page')
		);

		// Register custom scripts submenu item
		add_submenu_page(
			'wtols-settings',
			__('Custom Scripts', 'webtaru-site-options-login-security'),
			__('Custom Scripts', 'webtaru-site-options-login-security'),
			'manage_options',
			'wtols-custom-scripts',
			array($this, 'render_custom_scripts_page')
		);
	}

	public function maybe_redirect_after_activation()
	{
		if (!is_admin() || wp_doing_ajax() || !current_user_can('manage_options')) {
			return;
		}

		if (!get_transient(self::TRANSIENT_REDIRECT)) {
			return;
		}

		delete_transient(self::TRANSIENT_REDIRECT);

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['activate-multi'])) {
			return;
		}

		wp_safe_redirect(admin_url('admin.php?page=wtols-settings&wtols_welcome=1'));
		exit;
	}

	public function register_dashboard_widget()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		$options = self::get_options();
		$widget_title = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			/* translators: %s: agency menu name */
			? sprintf(__('%s Details', 'webtaru-site-options-login-security'), $options['agency_menu_name'])
			: __('Dynamic Options Details', 'webtaru-site-options-login-security');

		wp_add_dashboard_widget(
			'wtols_dashboard_settings',
			$widget_title,
			array($this, 'render_dashboard_widget')
		);

		wp_add_dashboard_widget(
			'wtols_notes_todo_dashboard_widget',
			__('Internal Notes & Tasks', 'webtaru-site-options-login-security'),
			array($this, 'render_notes_todo_dashboard_widget')
		);
	}

	public function enqueue_admin_assets($hook_suffix)
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_plugin_page = (isset($_GET['page']) && in_array($_GET['page'], array('wtols-settings', 'wtols-redirects', 'wtols-custom-css', 'wtols-custom-scripts'), true));
		$is_dashboard = 'index.php' === $hook_suffix;

		if (!$is_plugin_page && !$is_dashboard) {
			return;
		}

		wp_enqueue_media();
		wp_enqueue_style('wp-color-picker');
		wp_enqueue_style('wtols-admin', WTOLS_PLUGIN_URL . 'assets/admin-v3.css', array('wp-color-picker'), WTOLS_VERSION);
		wp_enqueue_script('wtols-admin', WTOLS_PLUGIN_URL . 'assets/admin-v3.js', array('jquery', 'wp-color-picker'), WTOLS_VERSION, true);
		wp_localize_script(
			'wtols-admin',
			'wtolsAdmin',
			array(
				'chooseLogo'     => __('Choose Image', 'webtaru-site-options-login-security'),
				'useLogo'        => __('Use this image', 'webtaru-site-options-login-security'),
				'noLogo'         => __('No image selected.', 'webtaru-site-options-login-security'),
				'labelPlaceholder' => __('Label', 'webtaru-site-options-login-security'),
				'urlPlaceholder' => __('Profile URL or #', 'webtaru-site-options-login-security'),
				'unlockNonce'    => wp_create_nonce('wtols_unlock_ip'),
				'testEmailNonce' => wp_create_nonce('wtols_test_email'),
				'unlocking'      => __('Unlocking...', 'webtaru-site-options-login-security'),
			)
		);

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ($is_plugin_page && isset($_GET['page']) && $_GET['page'] === 'wtols-redirects') {
			wp_add_inline_script('wtols-admin', '
				jQuery(document).ready(function($) {
					var selectAll = document.getElementById("wtols-select-all-redirects");
					if (!selectAll) return;
					function updateSelectAll() {
						var all = $(".wtols-redirect-checkbox");
						var done = $(".wtols-redirect-checkbox:checked");
						if (done.length === 0) { selectAll.checked = false; selectAll.indeterminate = false; }
						else if (done.length === all.length) { selectAll.checked = true; selectAll.indeterminate = false; }
						else { selectAll.checked = false; selectAll.indeterminate = true; }
					}
					$(selectAll).on("change", function() {
						$(".wtols-redirect-checkbox").prop("checked", this.checked);
					});
					$(document).on("change", ".wtols-redirect-checkbox", updateSelectAll);
				});
			');
		}
	}


	public function enqueue_media_replace_assets($hook_suffix)
	{
		$options = self::get_options();
		if (empty($options['enable_media_replace'])) {
			return;
		}
		// Only on media library pages
		if (!in_array($hook_suffix, array('upload.php', 'post.php'), true)) {
			return;
		}
		$replace_base = esc_js(admin_url('post.php?action=edit&post='));
		$btn_label    = esc_js(__('Replace Media', 'webtaru-site-options-login-security'));
		
		// Inline JS — adds a "Replace Media" link into the media modal sidebar
		wp_add_inline_script('media-views', '
			(function($){
				$(document).ready(function(){
					if(typeof wp === "undefined" || typeof wp.media === "undefined") return;
					
					// Hook into the media attachment details (Grid Modal)
					if(wp.media.view && wp.media.view.Attachment && wp.media.view.Attachment.Details){
						var oldDetails = wp.media.view.Attachment.Details;
						wp.media.view.Attachment.Details = oldDetails.extend({
							ready: function() {
								oldDetails.prototype.ready.apply(this, arguments);
								var id = this.model && this.model.id;
								if(id) {
									var $sidebar = this.$el.find(".attachment-actions");
									if($sidebar.length && !$sidebar.find(".wtols-replace-btn").length){
										$sidebar.append("<a href=\"" + ' . json_encode($replace_base) . ' + id + "\" class=\"wtols-replace-btn button button-large\" target=\"_blank\" style=\"margin-top:15px; width:100%; text-align:center; display:block; background:#2271b1; color:#fff; border-color:#2271b1;\">' + $btn_label + '</a>");
									}
								}
							}
						});
					}
				});
			})(jQuery);
		');
	}

	public function enqueue_frontend_assets()
	{
		wp_register_style('wtols-frontend', WTOLS_PLUGIN_URL . 'assets/frontend.css', array(), WTOLS_VERSION);
		wp_register_style('wtols-fontawesome', WTOLS_PLUGIN_URL . 'assets/vendor/fontawesome/css/all.min.css', array(), '6.5.2');
		wp_register_script('wtols-frontend', WTOLS_PLUGIN_URL . 'assets/frontend.js', array(), WTOLS_VERSION, true);

		$options = self::get_options();
		
		$needs_frontend_css = false;
		if (!empty($options['enable_sticky_whatsapp']) && !empty($options['whatsapp_number'])) {
			$needs_frontend_css = true;
		}
		if (!empty($options['enable_rating_widget'])) {
			$needs_frontend_css = true;
		}
		if (!empty($options['enable_back_to_top'])) {
			$needs_frontend_css = true;
			wp_enqueue_script('wtols-frontend');
		}
		if (!empty($options['enable_mobile_buttons'])) {
			$needs_frontend_css = true;
		}
		if (!empty($options['enable_smooth_scroll'])) {
			wp_enqueue_script('wtols-smooth-scroll', WTOLS_PLUGIN_URL . 'assets/smooth-scroll.js', array(), WTOLS_VERSION, true);
			wp_localize_script('wtols-smooth-scroll', 'wtolsSmoothScroll', array(
				'stepSize'      => floatval($options['smooth_scroll_speed']) * 200,
				'animationTime' => floatval($options['smooth_scroll_smoothness']) * 400,
			));
		}
		if (!empty($options['enable_sticky_vertical_btn'])) {
			$needs_frontend_css = true;
		}

		if ($needs_frontend_css) {
			wp_enqueue_style('wtols-frontend');
			if (!empty($options['enable_fontawesome'])) {
				wp_enqueue_style('wtols-fontawesome');
			}
		}

		if (!empty($options['enable_prefetch'])) {
			wp_enqueue_script('wtols-frontend');
			wp_localize_script('wtols-frontend', 'wtolsPrefetch', array(
				'enabled' => 1,
			));
		}
	}

	public function maybe_enqueue_auto_logout()
	{
		if (!is_user_logged_in()) {
			return;
		}

		$options = self::get_options();
		if (empty($options['enable_auto_logout'])) {
			return;
		}

		// Check if role matches
		$current_user = wp_get_current_user();
		$user_roles = (array) $current_user->roles;
		$target_roles = isset($options['auto_logout_roles']) ? (array) $options['auto_logout_roles'] : array();

		$apply = false;
		if (empty($target_roles)) {
			$apply = true;
		} else {
			foreach ($user_roles as $role) {
				if (in_array($role, $target_roles, true)) {
					$apply = true;
					break;
				}
			}
		}

		if (!$apply) {
			return;
		}

		// Enqueue auto-logout script and styles
		wp_enqueue_script(
			'wtols-auto-logout',
			WTOLS_PLUGIN_URL . 'assets/auto-logout.js',
			array('jquery'),
			WTOLS_VERSION,
			true
		);

		wp_enqueue_style(
			'wtols-auto-logout',
			WTOLS_PLUGIN_URL . 'assets/auto-logout.css',
			array(),
			WTOLS_VERSION
		);

		$idle_timeout = max(10, absint($options['auto_logout_idle_time']) * 60);
		$warning_time = min(60, floor($idle_timeout / 2));

		wp_localize_script('wtols-auto-logout', 'wtolsAutoLogout', array(
			'logoutUrl'      => wp_logout_url(add_query_arg('wtols_logged_out', '1', home_url())),
			'idleTimeout'    => $idle_timeout,
			'warningTime'    => $warning_time,
			'nonce'          => wp_create_nonce('wtols_keep_alive'),
			'ajaxUrl'        => admin_url('admin-ajax.php'),
			'warningTitle'   => __('Are you still here?', 'webtaru-site-options-login-security'),
			'warningMessage' => __('You have been inactive for a while. For security, you will be logged out in {seconds} seconds.', 'webtaru-site-options-login-security'),
			'btnKeepAlive'   => __('Stay Logged In', 'webtaru-site-options-login-security'),
			'btnLogOut'      => __('Log Out Now', 'webtaru-site-options-login-security'),
		));
	}

	public function ajax_keep_alive()
	{
		check_ajax_referer('wtols_keep_alive', 'nonce');
		wp_send_json_success();
	}

	public function filter_admin_footer_text($text)
	{
		$options = self::get_options();
		$footer_text = isset($options['admin_footer_text']) ? trim((string) $options['admin_footer_text']) : '';

		return '' === $footer_text ? $text : wp_kses_post($footer_text);
	}

	public function render_login_custom_styles()
	{
		$options = self::get_options();
		$login_logo = !empty($options['login_logo_id']) ? wp_get_attachment_image_url(absint($options['login_logo_id']), 'full') : '';
		$login_bg = !empty($options['login_background_id']) ? wp_get_attachment_image_url(absint($options['login_background_id']), 'full') : '';
		
		$custom_css = '
			body.login {
				display: flex !important;
				flex-direction: column !important;
				justify-content: center !important;
				align-items: center !important;
				min-height: 100vh !important;
				margin: 0 !important;
				padding: 20px 0 !important;
				box-sizing: border-box !important;
			}
			.language-switcher, #language-switcher {
				display: none !important;
			}
			body.login #login {
				background: #ffffff !important;
				border-radius: 16px !important;
				box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15) !important;
				box-sizing: border-box !important;
				margin: 0 !important;
				padding: 40px 35px 30px !important;
				width: 380px !important;
				max-width: calc(100% - 32px) !important;
			}
			body.login h1 {
				margin: 0 !important;
				padding: 0 !important;
			}
			body.login h1 a {
				display: block !important;
				background-size: contain !important;
				background-position: center !important;
				background-repeat: no-repeat !important;
				width: 100% !important;
				max-width: 280px !important;
				height: 85px !important;
				margin: 0 auto 25px !important;
			}
			body.login #loginform, body.login #lostpasswordform, body.login #registerform {
				background: transparent !important;
				border: 0 !important;
				box-shadow: none !important;
				margin-top: 0 !important;
				padding: 0 !important;
			}
			body.login .input, body.login input[type="text"], body.login input[type="password"], body.login input[type="email"] {
				background: #f8fafc !important;
				border: 1.5px solid #e2e8f0 !important;
				border-radius: 8px !important;
				box-shadow: none !important;
				font-size: 15px !important;
				padding: 10px 12px !important;
				width: 100% !important;
				box-sizing: border-box !important;
				transition: all 0.3s ease !important;
				color: #1e293b !important;
				height: auto !important;
				margin-top: 5px !important;
			}
			body.login .input:focus, body.login input[type="text"]:focus, body.login input[type="password"]:focus, body.login input[type="email"]:focus {
				border-color: #2563eb !important;
				background: #ffffff !important;
				box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15) !important;
				outline: none !important;
			}
			body.login label {
				color: #475569 !important;
				font-weight: 500 !important;
				font-size: 13px !important;
				margin-bottom: 8px !important;
				display: block !important;
			}
			body.login .forgetmenot {
				float: none !important;
				margin: 15px 0 20px !important;
			}
			body.login .forgetmenot label {
				display: inline-flex !important;
				align-items: center !important;
				justify-content: flex-start !important;
				gap: 8px !important;
				font-size: 14px !important;
				color: #475569 !important;
				cursor: pointer !important;
				margin: 0 !important;
				width: auto !important;
			}
			body.login .forgetmenot input[type="checkbox"] {
				display: inline-block !important;
				width: 16px !important;
				height: 16px !important;
				float: none !important;
				margin: 0 !important;
				vertical-align: middle !important;
				flex-shrink: 0 !important;
			}
			body.login .submit {
				float: none !important;
				padding: 0 !important;
				margin: 0 !important;
			}
			body.login .button-primary {
				background: #2563eb !important;
				border: none !important;
				border-radius: 8px !important;
				box-shadow: 0 4px 6px -1px rgba(37, 99, 235, 0.2), 0 2px 4px -1px rgba(37, 99, 235, 0.1) !important;
				color: #ffffff !important;
				font-size: 15px !important;
				font-weight: 600 !important;
				height: auto !important;
				padding: 12px 20px !important;
				width: 100% !important;
				text-shadow: none !important;
				transition: all 0.2s ease !important;
				cursor: pointer !important;
				display: block !important;
			}
			body.login .button-primary:hover, body.login .button-primary:focus {
				background: #1d4ed8 !important;
				box-shadow: 0 10px 15px -3px rgba(37, 99, 235, 0.3), 0 4px 6px -2px rgba(37, 99, 235, 0.15) !important;
			}
			body.login #nav, body.login #backtoblog {
				margin: 18px 0 0 !important;
				padding: 0 !important;
				text-align: center !important;
				font-size: 13px !important;
			}
			body.login #nav a, body.login #backtoblog a {
				color: #64748b !important;
				text-decoration: none !important;
				transition: color 0.2s ease !important;
				font-weight: 500 !important;
			}
			body.login #nav a:hover, body.login #backtoblog a:hover {
				color: #2563eb !important;
			}
		';

		if ($login_bg) {
			$custom_css .= '
				body.login {
					background-image: url("' . esc_url($login_bg) . '") !important;
					background-size: cover !important;
					background-position: center !important;
					background-repeat: no-repeat !important;
					background-attachment: fixed !important;
				}
			';
		}

		if ($login_logo) {
			$custom_css .= '
				body.login h1 a {
					background-image: url("' . esc_url($login_logo) . '") !important;
				}
			';
		}

		wp_add_inline_style('login', $custom_css);
	}


	public function filter_login_header_url()
	{
		return home_url('/');
	}

	public function filter_login_header_text()
	{
		return get_bloginfo('name');
	}

	public function filter_login_errors($error)
	{
		$options = self::get_options();
		$message = isset($options['login_error_message']) && '' !== trim((string) $options['login_error_message'])
			? $options['login_error_message']
			: self::get_default_options()['login_error_message'];

		return esc_html($message);
	}

	public function filter_login_message($message)
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_logged_out']) && '1' === $_GET['wtols_logged_out']) {
			$message .= '<div class="message login-message" style="border-left-color: #ef4444 !important; color: #1e293b !important; font-weight: 500;">' . esc_html__('You have been logged out due to inactivity.', 'webtaru-site-options-login-security') . '</div>';
		}
		return $message;
	}

	public function maybe_save_settings()
	{
		if (!isset($_POST['wtols_settings_submit']) && !isset($_POST['wtols_reset_admin_bar'])) {
			return;
		}

		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to update these settings.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer(self::NONCE_ACTION_SAVE, 'wtols_nonce');

		// phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$raw = isset($_POST['wtols']) && is_array($_POST['wtols']) ? wp_unslash($_POST['wtols']) : array();
		$old_options = self::get_options();

		$options = array(
			'phone' => isset($raw['phone']) ? sanitize_text_field($raw['phone']) : '',
			'phone_2' => isset($raw['phone_2']) ? sanitize_text_field($raw['phone_2']) : '',
			'email' => isset($raw['email']) ? sanitize_email($raw['email']) : '',
			'email_2' => isset($raw['email_2']) ? sanitize_email($raw['email_2']) : '',
			'fax' => isset($raw['fax']) ? sanitize_text_field($raw['fax']) : '',
			'address' => isset($raw['address']) ? sanitize_textarea_field($raw['address']) : '',
			'address_link' => isset($raw['address_link']) ? $this->sanitize_safe_url($raw['address_link']) : '',
			'logo_light_id' => isset($raw['logo_light_id']) ? absint($raw['logo_light_id']) : 0,
			'logo_dark_id' => isset($raw['logo_dark_id']) ? absint($raw['logo_dark_id']) : 0,
			'map' => isset($raw['map']) ? $this->sanitize_map_value($raw['map']) : '',
			'social_links' => isset($raw['social_links']) && is_array($raw['social_links']) ? $this->sanitize_social_links($raw['social_links']) : self::get_default_social_links(),
			'custom_social_links' => isset($raw['custom_social_links']) && is_array($raw['custom_social_links']) ? $this->sanitize_custom_social_links($raw['custom_social_links']) : array(),
			'enable_fontawesome' => isset($raw['enable_fontawesome']) ? 1 : 0,
			'admin_footer_text' => isset($raw['admin_footer_text']) ? wp_kses_post($raw['admin_footer_text']) : '',
			'login_logo_id' => isset($raw['login_logo_id']) ? absint($raw['login_logo_id']) : 0,
			'login_background_id' => isset($raw['login_background_id']) ? absint($raw['login_background_id']) : 0,
			'login_error_message' => isset($raw['login_error_message']) ? sanitize_text_field($raw['login_error_message']) : '',
			'login_slug' => isset($raw['login_slug']) ? $this->sanitize_login_slug($raw['login_slug']) : '',
			'login_secret_key' => isset($raw['login_secret_key']) ? sanitize_key($raw['login_secret_key']) : '',
			'business_hours' => isset($raw['business_hours']) && is_array($raw['business_hours']) ? $this->sanitize_business_hours($raw['business_hours']) : self::get_default_business_hours(),
			'business_hours_freeform' => isset($raw['business_hours_freeform']) ? sanitize_textarea_field($raw['business_hours_freeform']) : '',
			'business_hours_label' => isset($raw['business_hours_label']) ? sanitize_text_field($raw['business_hours_label']) : 'Business Hours',
			'enable_schema' => isset($raw['enable_schema']) ? 1 : 0,
			'limiter_enabled' => isset($raw['limiter_enabled']) ? 1 : 0,
			'limiter_max_attempts' => isset($raw['limiter_max_attempts']) ? max(1, absint($raw['limiter_max_attempts'])) : 5,
			'limiter_lockout_duration' => isset($raw['limiter_lockout_duration']) ? max(1, absint($raw['limiter_lockout_duration'])) : 30,
			'limiter_message' => isset($raw['limiter_message']) ? sanitize_text_field($raw['limiter_message']) : '',
			'disable_xmlrpc' => isset($raw['disable_xmlrpc']) ? 1 : 0,
			'captcha_type' => isset($raw['captcha_type']) && in_array($raw['captcha_type'], array('none', 'recaptcha_v3', 'turnstile'), true) ? $raw['captcha_type'] : 'none',
		);

		$options['captcha_site_key'] = ('none' === $options['captcha_type']) ? '' : (isset($raw['captcha_site_key']) ? sanitize_text_field($raw['captcha_site_key']) : '');
		$options['captcha_secret_key'] = ('none' === $options['captcha_type']) ? '' : (isset($raw['captcha_secret_key']) ? sanitize_text_field($raw['captcha_secret_key']) : '');

		$options = array_merge($options, array(
			'show_contact_icons' => isset($raw['show_contact_icons']) ? 1 : 0,
			'icon_placement' => isset($raw['icon_placement']) && 'after' === $raw['icon_placement'] ? 'after' : 'before',
			'icon_phone' => isset($raw['icon_phone']) ? sanitize_text_field($raw['icon_phone']) : 'fa-solid fa-phone',
			'icon_phone_2' => isset($raw['icon_phone_2']) ? sanitize_text_field($raw['icon_phone_2']) : 'fa-solid fa-phone',
			'icon_email' => isset($raw['icon_email']) ? sanitize_text_field($raw['icon_email']) : 'fa-solid fa-envelope',
			'icon_email_2' => isset($raw['icon_email_2']) ? sanitize_text_field($raw['icon_email_2']) : 'fa-solid fa-envelope',
			'icon_fax' => isset($raw['icon_fax']) ? sanitize_text_field($raw['icon_fax']) : 'fa-solid fa-fax',
			'icon_address' => isset($raw['icon_address']) ? sanitize_text_field($raw['icon_address']) : 'fa-solid fa-location-dot',
			'clear_cache_on_save' => isset($raw['clear_cache_on_save']) ? 1 : 0,
			'admin_bar_clear_cache' => isset($raw['admin_bar_clear_cache']) ? 1 : 0,
			'layout_style' => isset($raw['layout_style']) && in_array($raw['layout_style'], array('simple', 'pill'), true) ? $raw['layout_style'] : 'simple',
			'color_text' => isset($raw['color_text']) ? sanitize_hex_color($raw['color_text']) : '',
			'color_background' => isset($raw['color_background']) ? sanitize_hex_color($raw['color_background']) : '',
			'color_icon' => isset($raw['color_icon']) ? sanitize_hex_color($raw['color_icon']) : '',
			'disable_gutenberg' => isset($raw['disable_gutenberg']) ? 1 : 0,
			'disable_file_editor' => isset($raw['disable_file_editor']) ? 1 : 0,
			'disable_comments_sitewide' => isset($raw['disable_comments_sitewide']) ? 1 : 0,
			'hidden_plugin_updates' => isset($raw['hidden_plugin_updates']) && is_array($raw['hidden_plugin_updates']) ? array_map('sanitize_text_field', $raw['hidden_plugin_updates']) : array(),
			'disabled_plugin_autoupdates' => isset($raw['disabled_plugin_autoupdates']) && is_array($raw['disabled_plugin_autoupdates']) ? array_map('sanitize_text_field', $raw['disabled_plugin_autoupdates']) : array(),
			'enable_duplicator' => isset($raw['enable_duplicator']) ? 1 : 0,
			'agency_mode' => isset($raw['agency_mode']) ? 1 : 0,
			'agency_menu_name' => isset($raw['agency_menu_name']) ? sanitize_text_field($raw['agency_menu_name']) : 'Dynamic Options',
			'agency_hide_icon' => isset($raw['agency_hide_icon']) ? 1 : 0,
			'delete_data_on_uninstall' => isset($raw['delete_data_on_uninstall']) ? 1 : 0,
			'hide_wp_version' => isset($raw['hide_wp_version']) ? 1 : 0,
			'enable_maintenance' => isset($raw['enable_maintenance']) ? 1 : 0,
			'maintenance_message' => isset($raw['maintenance_message']) ? wp_kses_post($raw['maintenance_message']) : '',
			'maintenance_heading' => isset($raw['maintenance_heading']) ? sanitize_text_field($raw['maintenance_heading']) : 'Maintenance Mode',
			'enable_login_designer' => isset($raw['enable_login_designer']) ? 1 : 0,
			'login_designer_layout' => isset($raw['login_designer_layout']) ? sanitize_text_field($raw['login_designer_layout']) : 'default',
			'login_bg_image_id' => isset($raw['login_bg_image_id']) ? absint($raw['login_bg_image_id']) : 0,
			'login_bg_image' => isset($raw['login_bg_image']) ? sanitize_text_field($raw['login_bg_image']) : '',
			'enable_geo_blocking' => isset($raw['enable_geo_blocking']) ? 1 : 0,
			'geo_block_type' => isset($raw['geo_block_type']) ? sanitize_text_field($raw['geo_block_type']) : 'login',
			'geo_blocked_countries' => isset($raw['geo_blocked_countries']) ? array_map('trim', explode(',', sanitize_text_field($raw['geo_blocked_countries']))) : array(),
			'hidden_admin_menus' => isset($raw['hidden_admin_menus']) && is_array($raw['hidden_admin_menus']) ? array_map('sanitize_text_field', $raw['hidden_admin_menus']) : array(),
			'disable_update_emails' => isset($raw['disable_update_emails']) ? 1 : 0,

			'admin_footer_right_text' => isset($raw['admin_footer_right_text']) ? wp_kses_post($raw['admin_footer_right_text']) : '',
			'disable_author_archives' => isset($raw['disable_author_archives']) ? 1 : 0,
			'open_external_links_new_tab' => isset($raw['open_external_links_new_tab']) ? 1 : 0,
			'enable_login_logout_menu' => isset($raw['enable_login_logout_menu']) ? 1 : 0,
			'menu_login_url' => isset($raw['menu_login_url']) ? esc_url_raw($raw['menu_login_url']) : '',
			'enable_redirect_login' => isset($raw['enable_redirect_login']) ? 1 : 0,
			'redirect_after_login' => self::sanitize_redirect_array(isset($raw['redirect_after_login']) ? $raw['redirect_after_login'] : array()),
			'enable_redirect_logout' => isset($raw['enable_redirect_logout']) ? 1 : 0,
			'redirect_after_logout' => self::sanitize_redirect_array(isset($raw['redirect_after_logout']) ? $raw['redirect_after_logout'] : array()),
			'custom_robots_txt' => isset($raw['custom_robots_txt']) ? sanitize_textarea_field($raw['custom_robots_txt']) : '',
			'enable_smtp' => isset($raw['enable_smtp']) ? 1 : 0,
			'smtp_host' => isset($raw['smtp_host']) ? sanitize_text_field($raw['smtp_host']) : '',
			'smtp_port' => isset($raw['smtp_port']) ? sanitize_text_field($raw['smtp_port']) : '587',
			'smtp_secure' => isset($raw['smtp_secure']) ? sanitize_text_field($raw['smtp_secure']) : 'tls',
			'smtp_user' => isset($raw['smtp_user']) ? sanitize_text_field($raw['smtp_user']) : '',
			'smtp_pass' => isset($raw['smtp_pass']) ? sanitize_text_field($raw['smtp_pass']) : '',
			'smtp_from_email' => isset($raw['smtp_from_email']) ? sanitize_email($raw['smtp_from_email']) : '',
			'smtp_from_name' => isset($raw['smtp_from_name']) ? sanitize_text_field($raw['smtp_from_name']) : '',
			'redirect_404_home' => isset($raw['redirect_404_home']) ? 1 : 0,
			'enable_media_replace' => isset($raw['enable_media_replace']) ? 1 : 0,
			'hidden_admin_bar_nodes' => isset($raw['hidden_admin_bar_nodes']) && is_array($raw['hidden_admin_bar_nodes']) ? array_map('sanitize_text_field', $raw['hidden_admin_bar_nodes']) : array(),

			'whatsapp_number' => isset($raw['whatsapp_number']) ? sanitize_text_field($raw['whatsapp_number']) : '',
			'enable_sticky_whatsapp' => isset($raw['enable_sticky_whatsapp']) ? 1 : 0,
			'sticky_whatsapp_position' => isset($raw['sticky_whatsapp_position']) && in_array($raw['sticky_whatsapp_position'], array('left', 'right'), true) ? $raw['sticky_whatsapp_position'] : 'right',
			'sticky_whatsapp_display' => isset($raw['sticky_whatsapp_display']) && in_array($raw['sticky_whatsapp_display'], array('both', 'mobile', 'desktop'), true) ? $raw['sticky_whatsapp_display'] : 'both',
			'sticky_whatsapp_message' => isset($raw['sticky_whatsapp_message']) ? sanitize_text_field($raw['sticky_whatsapp_message']) : '',
			'sticky_whatsapp_icon_size' => isset($raw['sticky_whatsapp_icon_size']) ? sanitize_text_field($raw['sticky_whatsapp_icon_size']) : '32',
			'enable_rating_widget' => isset($raw['enable_rating_widget']) ? 1 : 0,
			'rating_widget_provider' => isset($raw['rating_widget_provider']) && in_array($raw['rating_widget_provider'], array('google', 'trustpilot'), true) ? $raw['rating_widget_provider'] : 'google',
			'rating_widget_icon_type' => isset($raw['rating_widget_icon_type']) && in_array($raw['rating_widget_icon_type'], array('icon', 'image'), true) ? $raw['rating_widget_icon_type'] : 'icon',
			'rating_widget_image_url' => isset($raw['rating_widget_image_url']) ? esc_url_raw($raw['rating_widget_image_url']) : '',
			'rating_widget_score' => isset($raw['rating_widget_score']) ? sanitize_text_field($raw['rating_widget_score']) : '5.0',
			'rating_widget_link' => isset($raw['rating_widget_link']) ? esc_url_raw($raw['rating_widget_link']) : '',
			'rating_widget_display' => isset($raw['rating_widget_display']) && in_array($raw['rating_widget_display'], array('both', 'mobile', 'desktop'), true) ? $raw['rating_widget_display'] : 'desktop',
			'enable_back_to_top' => isset($raw['enable_back_to_top']) ? 1 : 0,
			'back_to_top_display' => isset($raw['back_to_top_display']) && in_array($raw['back_to_top_display'], array('both', 'mobile', 'desktop'), true) ? $raw['back_to_top_display'] : 'both',
			'back_to_top_bg_color' => isset($raw['back_to_top_bg_color']) ? sanitize_hex_color($raw['back_to_top_bg_color']) : '#5cb85c',
			'back_to_top_icon_color' => isset($raw['back_to_top_icon_color']) ? sanitize_hex_color($raw['back_to_top_icon_color']) : '#ffffff',
			'back_to_top_shape' => isset($raw['back_to_top_shape']) && in_array($raw['back_to_top_shape'], array('square', 'circle'), true) ? $raw['back_to_top_shape'] : 'square',
			'back_to_top_size' => isset($raw['back_to_top_size']) ? sanitize_text_field($raw['back_to_top_size']) : '20',
			'enable_mobile_buttons' => isset($raw['enable_mobile_buttons']) ? 1 : 0,
			'mobile_button_1_text' => isset($raw['mobile_button_1_text']) ? sanitize_text_field($raw['mobile_button_1_text']) : 'Call Now',
			'mobile_button_1_text_color' => isset($raw['mobile_button_1_text_color']) ? sanitize_hex_color($raw['mobile_button_1_text_color']) : '#ffffff',
			'mobile_button_1_link' => isset($raw['mobile_button_1_link']) ? esc_url_raw($raw['mobile_button_1_link']) : '',
			'mobile_button_1_color' => isset($raw['mobile_button_1_color']) ? sanitize_hex_color($raw['mobile_button_1_color']) : '#5cb85c',
			'mobile_button_2_text' => isset($raw['mobile_button_2_text']) ? sanitize_text_field($raw['mobile_button_2_text']) : '',
			'mobile_button_2_text_color' => isset($raw['mobile_button_2_text_color']) ? sanitize_hex_color($raw['mobile_button_2_text_color']) : '#ffffff',
			'mobile_button_2_link' => isset($raw['mobile_button_2_link']) ? esc_url_raw($raw['mobile_button_2_link']) : '',
			'mobile_button_2_color' => isset($raw['mobile_button_2_color']) ? sanitize_hex_color($raw['mobile_button_2_color']) : '#0275d8',
			'enable_sticky_vertical_btn' => isset($raw['enable_sticky_vertical_btn']) ? 1 : 0,
			'sticky_vertical_btn_text' => isset($raw['sticky_vertical_btn_text']) ? sanitize_text_field($raw['sticky_vertical_btn_text']) : '',
			'sticky_vertical_btn_icon' => isset($raw['sticky_vertical_btn_icon']) ? sanitize_text_field($raw['sticky_vertical_btn_icon']) : '',
			'sticky_vertical_btn_id_class' => isset($raw['sticky_vertical_btn_id_class']) ? sanitize_text_field($raw['sticky_vertical_btn_id_class']) : '',
			'sticky_vertical_btn_bg_color' => isset($raw['sticky_vertical_btn_bg_color']) ? sanitize_hex_color($raw['sticky_vertical_btn_bg_color']) : '',
			'sticky_vertical_btn_text_color' => isset($raw['sticky_vertical_btn_text_color']) ? sanitize_hex_color($raw['sticky_vertical_btn_text_color']) : '',
			'sticky_vertical_btn_icon_color' => isset($raw['sticky_vertical_btn_icon_color']) ? sanitize_hex_color($raw['sticky_vertical_btn_icon_color']) : '',
			'sticky_vertical_btn_position' => isset($raw['sticky_vertical_btn_position']) ? sanitize_text_field((string)$raw['sticky_vertical_btn_position']) : '50',
			'xss_protection' => isset($raw['xss_protection']) ? 1 : 0,
			'xss_mode' => isset($raw['xss_mode']) && in_array($raw['xss_mode'], array('basic', 'advanced'), true) ? $raw['xss_mode'] : 'basic',
			'disable_common_usernames' => isset($raw['disable_common_usernames']) ? 1 : 0,
			'enable_smooth_scroll' => isset($raw['enable_smooth_scroll']) ? 1 : 0,
			'smooth_scroll_speed' => isset($raw['smooth_scroll_speed']) ? sanitize_text_field($raw['smooth_scroll_speed']) : '0.5',
			'smooth_scroll_smoothness' => isset($raw['smooth_scroll_smoothness']) ? sanitize_text_field($raw['smooth_scroll_smoothness']) : '1.2',
			'enable_login_alerts' => isset($raw['enable_login_alerts']) ? 1 : 0,
			'enable_ip_lockout_alerts' => isset($raw['enable_ip_lockout_alerts']) ? 1 : 0,
			'login_alert_email' => isset($raw['login_alert_email']) ? sanitize_email($raw['login_alert_email']) : get_option('admin_email'),
			'enable_firewall' => isset($raw['enable_firewall']) ? 1 : 0,
			'restrict_rest_api' => isset($raw['restrict_rest_api']) ? 1 : 0,
			'admin_bar_zen_mode' => isset($raw['admin_bar_zen_mode']) ? 1 : 0,
			'enable_content_protection' => isset($raw['enable_content_protection']) ? 1 : 0,
			'remove_query_strings' => isset($raw['remove_query_strings']) ? 1 : 0,
			'enable_auto_alt' => isset($raw['enable_auto_alt']) ? 1 : 0,
			'enable_duplicate_menu' => isset($raw['enable_duplicate_menu']) ? 1 : 0,
			'enable_heartbeat_control' => isset($raw['enable_heartbeat_control']) ? 1 : 0,
			'heartbeat_interval' => isset($raw['heartbeat_interval']) ? min(120, max(15, absint($raw['heartbeat_interval']))) : 60,
			'heartbeat_disable_frontend' => isset($raw['heartbeat_disable_frontend']) ? 1 : 0,
			'heartbeat_disable_dashboard' => isset($raw['heartbeat_disable_dashboard']) ? 1 : 0,
			'heartbeat_disable_editor' => isset($raw['heartbeat_disable_editor']) ? 1 : 0,
			'enable_2fa' => isset($raw['enable_2fa']) ? 1 : 0,
			'2fa_roles' => isset($raw['2fa_roles']) && is_array($raw['2fa_roles']) ? array_map('sanitize_key', $raw['2fa_roles']) : array('administrator'),
			'enable_prefetch' => isset($raw['enable_prefetch']) ? 1 : 0,
			'maintenance_bypass_key' => isset($raw['maintenance_bypass_key']) ? sanitize_key($raw['maintenance_bypass_key']) : '',
			'enable_auto_logout' => isset($raw['enable_auto_logout']) ? 1 : 0,
			'auto_logout_idle_time' => isset($raw['auto_logout_idle_time']) ? max(1, absint($raw['auto_logout_idle_time'])) : 15,
			'auto_logout_roles' => isset($raw['auto_logout_roles']) && is_array($raw['auto_logout_roles']) ? array_map('sanitize_key', $raw['auto_logout_roles']) : array(),
			'ip_whitelist' => isset($raw['ip_whitelist']) ? sanitize_textarea_field($raw['ip_whitelist']) : '',
			'ip_blacklist' => isset($raw['ip_blacklist']) ? sanitize_textarea_field($raw['ip_blacklist']) : '',
			'block_login_page' => isset($raw['block_login_page']) ? 1 : 0,
			'login_ip_whitelist' => isset($raw['login_ip_whitelist']) ? sanitize_textarea_field($raw['login_ip_whitelist']) : '',
		));

		$options['custom_css'] = isset($raw['custom_css']) ? wp_strip_all_tags(wp_unslash($raw['custom_css'])) : '';
		if (current_user_can('unfiltered_html')) {
			$options['custom_header_code'] = isset($raw['custom_header_code']) ? wp_unslash($raw['custom_header_code']) : '';
			$options['custom_footer_code'] = isset($raw['custom_footer_code']) ? wp_unslash($raw['custom_footer_code']) : '';
		} else {
			$options['custom_header_code'] = isset($raw['custom_header_code']) ? wp_kses_post(wp_unslash($raw['custom_header_code'])) : '';
			$options['custom_footer_code'] = isset($raw['custom_footer_code']) ? wp_kses_post(wp_unslash($raw['custom_footer_code'])) : '';
		}

		// Preserve logs during save
		$existing_options = self::get_options();
		$options['login_logs'] = $existing_options['login_logs'];

		$options['logo_light_url'] = $this->get_attachment_url($options['logo_light_id']);
		$options['logo_dark_url'] = $this->get_attachment_url($options['logo_dark_id']);
		$options['login_logo_url'] = $this->get_attachment_url($options['login_logo_id']);
		$options['login_background_url'] = $this->get_attachment_url($options['login_background_id']);
		$options['login_bg_image'] = $this->get_attachment_url($options['login_bg_image_id']);
		$options['logo_id'] = $options['logo_light_id'];
		$options['logo_url'] = $options['logo_light_url'];

		if ('' === $options['login_error_message']) {
			$options['login_error_message'] = self::get_default_options()['login_error_message'];
		}

		if (!is_email($options['email'])) {
			$options['email'] = '';
		}

		if ('' !== $options['email_2'] && !is_email($options['email_2'])) {
			$options['email_2'] = '';
		}

		update_option(self::OPTION_KEY, wp_parse_args($options, self::get_default_options()));
		if (isset($old_options['login_slug']) && $old_options['login_slug'] !== $options['login_slug']) {
			delete_option('wtols_dismiss_cache_notice');
		}

		if (isset($_POST['wtols_reset_admin_bar'])) {
			delete_option('wtols_captured_nodes');
		}

		$active_tab = isset($_POST['wtols_active_tab']) ? sanitize_text_field(wp_unslash($_POST['wtols_active_tab'])) : 'contact';
		$redirect = admin_url('admin.php?page=wtols-settings&wtols_saved=1&wtols_active_tab=' . $active_tab);

		wp_safe_redirect($redirect);
		exit;
	}

	private function get_attachment_url($attachment_id)
	{
		if (!$attachment_id) {
			return '';
		}

		$url = wp_get_attachment_image_url(absint($attachment_id), 'full');
		return $url ? esc_url_raw($url) : '';
	}

	private function sanitize_map_value($value)
	{
		$value = trim((string) $value);

		if ('' === $value) {
			return '';
		}

		if (false !== stripos($value, '<iframe')) {
			return wp_kses($value, $this->get_allowed_iframe_html());
		}

		return esc_url_raw($value);
	}

	private function sanitize_social_links($social_links)
	{
		$defaults = self::get_default_social_links();
		$clean = array();

		foreach ($defaults as $key => $default) {
			$item = isset($social_links[$key]) && is_array($social_links[$key]) ? $social_links[$key] : array();

			$clean[$key] = array(
				'label' => $default['label'],
				'url' => isset($item['url']) ? $this->sanitize_safe_url($item['url']) : '',
				'icon' => isset($item['icon']) ? $this->sanitize_class_list($item['icon']) : $default['icon'],
			);

			if ('' === $clean[$key]['icon']) {
				$clean[$key]['icon'] = $default['icon'];
			}
		}

		return $clean;
	}

	private function sanitize_login_slug($value)
	{
		$value = trim((string) $value);

		if ('' === $value) {
			return '';
		}

		if (false !== strpos($value, '://')) {
			$path = wp_parse_url($value, PHP_URL_PATH);
			$value = $path ? basename(trim($path, '/')) : '';
		}

		$slug = sanitize_title(trim($value, '/'));

		if ('' === $slug) {
			return '';
		}

		$reserved = array('admin', 'admin-ajax', 'admin-post', 'wp-admin', 'wp-content', 'wp-includes', 'wp-json', 'wp-login', 'wp-login-php', 'xmlrpc', 'xmlrpc-php');

		return in_array($slug, $reserved, true) ? '' : $slug;
	}

	private function sanitize_safe_url($value)
	{
		$value = trim((string) $value);

		if ('' === $value) {
			return '';
		}

		if ('#' === $value) {
			return '#';
		}

		if (0 === strpos($value, '#')) {
			return '#' . sanitize_title(substr($value, 1));
		}

		return esc_url_raw($value);
	}

	private function esc_safe_url($value)
	{
		if ($this->is_hash_url($value)) {
			return esc_attr($value);
		}

		return esc_url($value);
	}

	private function is_hash_url($value)
	{
		return '#' === $value || 0 === strpos((string) $value, '#');
	}

	private function get_login_slug()
	{
		$options = self::get_options();
		return isset($options['login_slug']) ? $this->sanitize_login_slug($options['login_slug']) : '';
	}

	private function get_custom_login_url($action = '', $args = array())
	{
		$slug = $this->get_login_slug();

		if ('' === $slug) {
			return wp_login_url();
		}

		$url = home_url(user_trailingslashit($slug));

		if ('' !== $action) {
			$args['action'] = $action;
		}

		$args = array_filter(
			$args,
			static function ($value) {
				return '' !== $value && null !== $value;
			}
		);

		return empty($args) ? $url : add_query_arg($args, $url);
	}

	private function get_login_action_url($action = '', $args = array())
	{
		$slug = $this->get_login_slug();
		$options = self::get_options();
		$secret_key = isset($options['login_secret_key']) ? $options['login_secret_key'] : '';

		if ('' !== $slug) {
			return $this->get_custom_login_url($action, $args);
		}

		if ('' !== $secret_key) {
			if ('' !== $action) {
				$args['action'] = $action;
			}
			$args['secret'] = $secret_key;
			$args = array_filter(
				$args,
				static function ($value) {
					return '' !== $value && null !== $value;
				}
			);
			return add_query_arg($args, site_url('wp-login.php'));
		}

		return wp_login_url();
	}

	public function maybe_load_custom_login()
	{
		$slug = $this->get_login_slug();

		if ('' === $slug || $slug !== $this->get_current_request_slug()) {
			return;
		}

		// Prevent caching of the custom login URL
		if (!defined('DONOTCACHEPAGE')) {
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
			define('DONOTCACHEPAGE', true);
		}
		nocache_headers();

		// LiteSpeed Cache bypass
		if (!defined('LSCWP_CTRL')) {
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
			define('LSCWP_CTRL', 'disable');
		}
		if (class_exists('LiteSpeed_Cache_API')) {
			\LiteSpeed_Cache_API::set_nocache('Webtaru Site Options custom login bypass');
		}

		// WP Engine bypass caching for this page
		if (class_exists('WpeCommon')) {
			if (method_exists('WpeCommon', 'purge_memcached')) {
				\WpeCommon::purge_memcached();
			}
			if (method_exists('WpeCommon', 'clear_varnish_cache')) {
				\WpeCommon::clear_varnish_cache();
			}
		}

		$this->custom_login_request = true;
		global $pagenow;
		$pagenow = 'wp-login.php';

		require_once ABSPATH . 'wp-login.php';
		exit;
	}

	public function maybe_block_wp_admin_direct_access()
	{
		if (is_user_logged_in() || '' === $this->get_login_slug()) {
			return;
		}

		$request_path = $this->get_current_request_path();

		if ('' === $request_path || 0 !== strpos($request_path, 'wp-admin')) {
			return;
		}

		if (0 === strpos($request_path, 'wp-admin/admin-ajax.php')) {
			return;
		}

		wp_safe_redirect(home_url('/'));
		exit;
	}

	public function maybe_block_default_login()
	{
		if ($this->custom_login_request) {
			return;
		}

		$options = self::get_options();
		$slug = isset($options['login_slug']) ? $options['login_slug'] : '';
		$secret_key = isset($options['login_secret_key']) ? $options['login_secret_key'] : '';

		if ('' === $slug && '' === $secret_key) {
			return;
		}

		// Allow access if query parameter 'secret' matches our secret key (case-insensitive)
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ('' !== $secret_key && isset($_GET['secret']) && sanitize_key(wp_unslash($_GET['secret'])) === sanitize_key($secret_key)) {
			return;
		}

		$method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper(sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD']))) : 'GET';
		if ('POST' === $method) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$action = isset($_REQUEST['action']) ? sanitize_key(wp_unslash($_REQUEST['action'])) : 'login';
		$allowed_actions = array('logout', 'lostpassword', 'retrievepassword', 'postpass', 'rp', 'resetpass', 'confirm_admin_email', 'wtols_2fa_verify');

		if (in_array($action, $allowed_actions, true)) {
			return;
		}

		wp_safe_redirect(home_url('/'));
		exit;
	}

	public function maybe_block_login_by_ip()
	{
		$options = self::get_options();

		// If toggle is off, do nothing
		if (empty($options['block_login_page'])) {
			return;
		}

		// Prevent lockout for logged-in administrators in wp-admin
		if (is_admin() && current_user_can('manage_options')) {
			return;
		}

		// Determine if the request is for the login page or admin dashboard
		$is_login_page = false;
		global $pagenow;

		// Check if it's wp-login.php
		if ('wp-login.php' === $pagenow) {
			$is_login_page = true;
		}

		$request_path = $this->get_current_request_path();
		$slug = $this->get_login_slug();

		// Check if it's the custom login slug
		if ('' !== $slug && $slug === $this->get_current_request_slug()) {
			$is_login_page = true;
		}

		// Check if it's wp-admin (except admin-ajax.php and admin-post.php)
		$is_wp_admin = false;
		if ('' !== $request_path && 0 === strpos($request_path, 'wp-admin')) {
			if (0 !== strpos($request_path, 'wp-admin/admin-ajax.php') && 0 !== strpos($request_path, 'wp-admin/admin-post.php')) {
				$is_wp_admin = true;
			}
		}

		if (!$is_login_page && !$is_wp_admin) {
			return;
		}

		// Allow access if query parameter 'secret' matches our secret key (case-insensitive) - Lockout prevention
		$secret_key = isset($options['login_secret_key']) ? $options['login_secret_key'] : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ('' !== $secret_key && isset($_GET['secret']) && sanitize_key(wp_unslash($_GET['secret'])) === sanitize_key($secret_key)) {
			return;
		}

		// Get current IP and parse whitelisted IPs
		$ip = $this->get_client_ip();
		$whitelist_raw = !empty($options['login_ip_whitelist']) ? $options['login_ip_whitelist'] : '';
		$whitelist = array_filter(array_map('trim', explode("\n", $whitelist_raw)));

		// If whitelist is not empty and the current IP is in the whitelist, allow access
		if (!empty($whitelist) && in_array($ip, $whitelist, true)) {
			return;
		}

		// If IP is not whitelisted, block access
		header('HTTP/1.1 403 Forbidden');
		header('Status: 403 Forbidden');
		wp_die(
			esc_html__('Access Denied: The login page and backend are restricted to authorized IP addresses.', 'webtaru-site-options-login-security'),
			'Forbidden',
			array('response' => 403)
		);
	}



	private function get_current_request_slug()
	{
		return sanitize_title(trim(rawurldecode($this->get_current_request_path()), '/'));
	}

	private function get_current_request_path()
	{
		$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
		$request_path = trim((string) wp_parse_url($request_uri, PHP_URL_PATH), '/');
		$home_path = trim((string) wp_parse_url(home_url('/'), PHP_URL_PATH), '/');

		if ('' !== $home_path && 0 === strpos($request_path, $home_path . '/')) {
			$request_path = substr($request_path, strlen($home_path) + 1);
		}

		return trim(rawurldecode($request_path), '/');
	}

	public function render_settings_page()
	{
		if (!current_user_can("manage_options")) {
			return;
		}

		$options = self::get_options();
		$header_title = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			? $options['agency_menu_name']
			: __('Webtaru Site Options and Login Security', 'webtaru-site-options-login-security');

		$wrap_class = 'wrap wtols-wrap';
		if (!empty($options['agency_hide_icon'])) {
			$wrap_class .= ' wtols-hide-header-icon';
		}
		?>
				<div class="<?php echo esc_attr($wrap_class); ?>">
					<div class="wtols-page-header">
						<h1>
							<img src="<?php echo esc_url( WTOLS_PLUGIN_URL . 'assets/webtaru-logo.png' ); ?>" class="wtols-header-logo" alt="" />
							<?php echo esc_html($header_title); ?>
						</h1>
						<button type="submit" name="wtols_settings_submit" form="wtols-main-form" class="button button-primary wtols-save-top"><?php esc_html_e("Save Settings", "webtaru-site-options-login-security"); ?></button>
					</div>
				<div class="wtols-page-header-spacer"></div>
				<hr class="wp-header-end" style="display:none;">
					<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
					<?php if (isset($_GET["wtols_welcome"])): ?>
							<div class="notice notice-info is-dismissible"><p><?php esc_html_e("Plugin activated. Add your contact details below, then use the generated shortcodes anywhere.", "webtaru-site-options-login-security"); ?></p></div>
					<?php endif; ?>
					<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
					<?php if (isset($_GET["wtols_comments_deleted"])): ?>
							<div class="notice notice-success is-dismissible"><p><?php esc_html_e("All comments have been successfully deleted.", "webtaru-site-options-login-security"); ?></p></div>
					<?php endif; ?>
					<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
					<?php if (isset($_GET["wtols_cleaned"])): ?>
							<div class="notice notice-success is-dismissible"><p><?php esc_html_e("Database cleanup successful! Revisions, auto-drafts, and expired transients removed.", "webtaru-site-options-login-security"); ?></p></div>
					<?php endif; ?>

					<div class="wtols-admin-layout">
						<nav class="wtols-sidebar-nav">
							<a class="wtols-tab" data-tab="contact"><span class="dashicons dashicons-phone"></span><span class="wtols-tab-label"><?php esc_html_e("Contact &amp; Info", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="floating-widgets"><span class="dashicons dashicons-admin-links"></span><span class="wtols-tab-label"><?php esc_html_e("Floating Widgets", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="brand"><span class="dashicons dashicons-format-image"></span><span class="wtols-tab-label"><?php esc_html_e("Visual Branding", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="login"><span class="dashicons dashicons-lock"></span><span class="wtols-tab-label"><?php esc_html_e("Login &amp; Security", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="premium-scanners"><span class="dashicons dashicons-shield"></span><span class="wtols-tab-label"><?php esc_html_e("Premium Scanners", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="utilities"><span class="dashicons dashicons-admin-tools"></span><span class="wtols-tab-label"><?php esc_html_e("Workflow Utilities", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="system"><span class="dashicons dashicons-admin-settings"></span><span class="wtols-tab-label"><?php esc_html_e("System &amp; Backup", "webtaru-site-options-login-security"); ?></span></a>
							<a class="wtols-tab" data-tab="shortcodes"><span class="dashicons dashicons-editor-code"></span><span class="wtols-tab-label"><?php esc_html_e("Shortcodes", "webtaru-site-options-login-security"); ?></span></a>
					
							<div class="wtols-sidebar-footer" style="padding-bottom: 15px;">
								<div class="wtols-sidebar-links" style="font-size:12px; text-align: left; padding: 0 10px;">
									<a href="https://wordpress.org/support/plugin/webtaru-site-options-login-security/reviews/#new-post" target="_blank" style="display:block; margin-bottom:6px; color:#2271b1; text-decoration:none;"><span class="dashicons dashicons-star-filled" style="font-size:14px; width:14px; height:14px; vertical-align:middle; margin-right:4px; color:#f59e0b;"></span><?php esc_html_e("Review Us", "webtaru-site-options-login-security"); ?></a>
									<a href="<?php echo esc_url('mailto:hello@aaditya.me?subject=Bug%20Report%20-%20Webtaru%20Site%20Options%20and%20Login%20Security'); ?>" style="display:block; margin-bottom:6px; color:#d93025; text-decoration:none;"><span class="dashicons dashicons-warning" style="font-size:14px; width:14px; height:14px; vertical-align:middle; margin-right:4px;"></span><?php esc_html_e("Report Bug", "webtaru-site-options-login-security"); ?></a>
									<a href="<?php echo esc_url('mailto:hello@aaditya.me?subject=Feature%20Request%20-%20Webtaru%20Site%20Options%20and%20Login%20Security'); ?>" style="display:block; color:#137333; text-decoration:none;"><span class="dashicons dashicons-lightbulb" style="font-size:14px; width:14px; height:14px; vertical-align:middle; margin-right:4px;"></span><?php esc_html_e("Request Feature", "webtaru-site-options-login-security"); ?></a>
								</div>
							</div>
						</nav>
						<div class="wtols-content-area">
							<?php $this->render_settings_form($options); ?>
						</div>
					</div>
				</div>
				<?php
	}

	public function render_dashboard_widget()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_saved'])) {
			echo '<div class="notice notice-success inline"><p>' . esc_html__('Settings saved.', 'webtaru-site-options-login-security') . '</p></div>';
		}

		$this->render_settings_form(self::get_options(), true);
	}

	public function render_notes_todo_dashboard_widget()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		$notes = get_option('wtols_admin_notes', '');
		$tasks = get_option('wtols_admin_tasks', array());
		if (!is_array($tasks)) {
			$tasks = array();
		}

		$nonce = wp_create_nonce('wtols_notes_todo_nonce');
		?>
		<div class="wtols-dashboard-widget-wrap">
			<!-- Tabs -->
			<div class="wtols-widget-tabs" style="display:flex; border-bottom:1px solid #ddd; margin-bottom:12px;">
				<a href="#" class="wtols-widget-tab wtols-widget-tab-active" data-tab="notes" style="padding:8px 16px; text-decoration:none; font-weight:600; color:#2271b1; border-bottom: 2px solid #2271b1; margin-bottom: -1px;"><?php esc_html_e('Notes', 'webtaru-site-options-login-security'); ?></a>
				<a href="#" class="wtols-widget-tab" data-tab="tasks" style="padding:8px 16px; text-decoration:none; font-weight:600; color:#64748b; margin-bottom: -1px;"><?php esc_html_e('Task List', 'webtaru-site-options-login-security'); ?></a>
			</div>

			<!-- Tab 1: Notes -->
			<div class="wtols-widget-panel wtols-widget-panel-active" id="wtols-widget-panel-notes">
				<textarea id="wtols-widget-notes-area" style="width:100%; height:150px; resize:vertical; padding:8px; border:1px solid #ccc; border-radius:4px; font-family:inherit;" placeholder="<?php esc_attr_e('Write your internal notes here...', 'webtaru-site-options-login-security'); ?>"><?php echo esc_textarea($notes); ?></textarea>
				<p class="description" style="margin-top:6px; display:flex; justify-content:space-between; align-items:center;">
					<span><?php esc_html_e('Auto-saves as you type.', 'webtaru-site-options-login-security'); ?></span>
					<span id="wtols-notes-status" style="color:green; font-weight:600;"></span>
				</p>
			</div>

			<!-- Tab 2: Tasks -->
			<div class="wtols-widget-panel" id="wtols-widget-panel-tasks" style="display:none;">
				<div style="display:flex; gap:8px; margin-bottom:12px;">
					<input type="text" id="wtols-widget-new-task" placeholder="<?php esc_attr_e('Add new task...', 'webtaru-site-options-login-security'); ?>" style="flex:1; padding:6px 10px; border:1px solid #ccc; border-radius:4px;" />
					<button type="button" id="wtols-widget-add-task-btn" class="button button-primary"><?php esc_html_e('Add', 'webtaru-site-options-login-security'); ?></button>
				</div>
				<ul id="wtols-widget-task-list" style="margin:0; padding:0; list-style:none; max-height:200px; overflow-y:auto;">
					<?php if (empty($tasks)): ?>
						<li class="wtols-no-tasks-item" style="color:#64748b; padding:8px 0; font-style:italic;"><?php esc_html_e('No tasks added yet.', 'webtaru-site-options-login-security'); ?></li>
					<?php else: ?>
						<?php foreach ($tasks as $id => $task): ?>
							<?php $checked = !empty($task['done']) ? 'checked' : ''; ?>
							<?php $text_style = !empty($task['done']) ? 'text-decoration:line-through; color:#a7aaad;' : ''; ?>
							<li class="wtols-widget-task-item" data-id="<?php echo esc_attr($id); ?>" style="display:flex; align-items:center; justify-content:space-between; padding:8px 0; border-bottom:1px solid #f0f0f0;">
								<label style="display:flex; align-items:center; gap:8px; cursor:pointer;">
									<input type="checkbox" class="wtols-task-checkbox" <?php echo esc_attr($checked); ?> style="margin:0;" />
									<span class="wtols-task-text" style="<?php echo esc_attr($text_style); ?>"><?php echo esc_html($task['text']); ?></span>
								</label>
								<a href="#" class="wtols-delete-task-btn" style="color:#d63638; text-decoration:none; font-size:16px;">&times;</a>
							</li>
						<?php endforeach; ?>
					<?php endif; ?>
				</ul>
			</div>
		</div>

		<script type="text/javascript">
		jQuery(document).ready(function($) {
			// Tab switching
			$('.wtols-widget-tab').on('click', function(e) {
				e.preventDefault();
				$('.wtols-widget-tab').removeClass('wtols-widget-tab-active').css({'color': '#64748b', 'border-bottom': 'none'});
				$(this).addClass('wtols-widget-tab-active').css({'color': '#2271b1', 'border-bottom': '2px solid #2271b1'});
				
				var tab = $(this).data('tab');
				$('.wtols-widget-panel').hide();
				$('#wtols-widget-panel-' + tab).show();
			});

			// Notes autosave logic (debounce)
			var notesTimeout = null;
			$('#wtols-widget-notes-area').on('input', function() {
				var notes = $(this).val();
				$('#wtols-notes-status').text('Typing...').css('color', '#64748b');
				clearTimeout(notesTimeout);
				notesTimeout = setTimeout(function() {
					$.ajax({
						url: ajaxurl,
						type: 'POST',
						data: {
							action: 'wtols_save_admin_notes',
							notes: notes,
							nonce: '<?php echo esc_js($nonce); ?>'
						},
						success: function(response) {
							if (response.success) {
								$('#wtols-notes-status').text('Saved').css('color', 'green');
								setTimeout(function() {
									$('#wtols-notes-status').text('');
								}, 1500);
							}
						}
					});
				}, 1000);
			});

			// Tasks list logic
			function saveTasks() {
				var tasks = {};
				$('#wtols-widget-task-list .wtols-widget-task-item').each(function() {
					var id = $(this).data('id');
					var text = $(this).find('.wtols-task-text').text();
					var done = $(this).find('.wtols-task-checkbox').is(':checked') ? 1 : 0;
					tasks[id] = { text: text, done: done };
				});
				$.ajax({
					url: ajaxurl,
					type: 'POST',
					data: {
						action: 'wtols_save_admin_tasks',
						tasks: JSON.stringify(tasks),
						nonce: '<?php echo esc_js($nonce); ?>'
					}
				});
			}

			// Add task
			function addTask() {
				var text = $('#wtols-widget-new-task').val().trim();
				if (!text) return;
				
				var id = 'task_' + Date.now();
				$('.wtols-no-tasks-item').remove();

				var itemHtml = '<li class="wtols-widget-task-item" data-id="' + id + '" style="display:flex; align-items:center; justify-content:space-between; padding:8px 0; border-bottom:1px solid #f0f0f0;">' +
					'<label style="display:flex; align-items:center; gap:8px; cursor:pointer;">' +
						'<input type="checkbox" class="wtols-task-checkbox" style="margin:0;" />' +
						'<span class="wtols-task-text">' + $('<div/>').text(text).html() + '</span>' +
					'</label>' +
					'<a href="#" class="wtols-delete-task-btn" style="color:#d63638; text-decoration:none; font-size:16px;">&times;</a>' +
				'</li>';

				$('#wtols-widget-task-list').append(itemHtml);
				$('#wtols-widget-new-task').val('');
				saveTasks();
			}

			$('#wtols-widget-add-task-btn').on('click', addTask);
			$('#wtols-widget-new-task').on('keypress', function(e) {
				if (e.which === 13) {
					addTask();
				}
			});

			// Toggle task
			$(document).on('change', '.wtols-task-checkbox', function() {
				var $text = $(this).siblings('.wtols-task-text');
				if ($(this).is(':checked')) {
					$text.css({'text-decoration': 'line-through', 'color': '#a7aaad'});
				} else {
					$text.css({'text-decoration': 'none', 'color': 'inherit'});
				}
				saveTasks();
			});

			// Delete task
			$(document).on('click', '.wtols-delete-task-btn', function(e) {
				e.preventDefault();
				$(this).closest('.wtols-widget-task-item').remove();
				if ($('#wtols-widget-task-list .wtols-widget-task-item').length === 0) {
					$('#wtols-widget-task-list').append('<li class="wtols-no-tasks-item" style="color:#64748b; padding:8px 0; font-style:italic;">No tasks added yet.</li>');
				}
				saveTasks();
			});
		});
		</script>
		<?php
	}

	public function ajax_save_admin_notes()
	{
		if (!current_user_can('manage_options')) {
			wp_send_json_error('Permission denied');
		}

		check_ajax_referer('wtols_notes_todo_nonce', 'nonce');

		$notes = isset($_POST['notes']) ? sanitize_textarea_field(wp_unslash($_POST['notes'])) : '';
		update_option('wtols_admin_notes', $notes);
		wp_send_json_success();
	}

	public function ajax_save_admin_tasks()
	{
		if (!current_user_can('manage_options')) {
			wp_send_json_error('Permission denied');
		}

		check_ajax_referer('wtols_notes_todo_nonce', 'nonce');

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$tasks_json = isset($_POST['tasks']) ? wp_unslash($_POST['tasks']) : '';
		$tasks_raw = json_decode($tasks_json, true);
		
		$tasks = array();
		if (is_array($tasks_raw)) {
			foreach ($tasks_raw as $id => $task) {
				$clean_id = sanitize_key($id);
				$tasks[$clean_id] = array(
					'text' => sanitize_text_field($task['text']),
					'done' => !empty($task['done']) ? 1 : 0
				);
			}
		}

		update_option('wtols_admin_tasks', $tasks);
		wp_send_json_success();
	}
	private function render_settings_form($options, $compact = false)
	{
		$action_url = esc_url(admin_url('admin.php'));
		$form_class = $compact ? 'wtols-settings-form wtols-compact-form' : 'wtols-settings-form';
		echo '<form method="post" id="wtols-main-form" action="' . esc_url($action_url) . '" class="' . esc_attr($form_class) . '">';
		wp_nonce_field(self::NONCE_ACTION_SAVE, 'wtols_nonce');
		echo '<input type="hidden" name="page" value="wtols-settings" />';
		$active_tab = 'contact';
		// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
		if (isset($_GET['wtols_active_tab'])) {
			$active_tab = sanitize_text_field(wp_unslash($_GET['wtols_active_tab']));
		} elseif (isset($_POST['wtols_active_tab'])) {
			$active_tab = sanitize_text_field(wp_unslash($_POST['wtols_active_tab']));
		}
		// phpcs:enable
		echo '<input type="hidden" id="wtols_active_tab" name="wtols_active_tab" value="' . esc_attr($active_tab) . '" />';

		/* ── Tab 1: Contact ── */
		echo '<div class="wtols-tab-panel" data-panel="contact"><table class="form-table" role="presentation"><tbody>';
		$this->render_section_heading(__('Contact Details', 'webtaru-site-options-login-security'));
		$this->render_text_row('wtols-phone', 'wtols[phone]', __('Phone 1', 'webtaru-site-options-login-security'), $options['phone'], 'tel');
		$this->render_text_row('wtols-phone-2', 'wtols[phone_2]', __('Phone 2', 'webtaru-site-options-login-security'), $options['phone_2'], 'tel');
		$this->render_text_row('wtols-email', 'wtols[email]', __('Email 1', 'webtaru-site-options-login-security'), $options['email'], 'email', 'email');
		$this->render_text_row('wtols-email-2', 'wtols[email_2]', __('Email 2', 'webtaru-site-options-login-security'), $options['email_2'], 'email', 'email');
		$this->render_text_row('wtols-fax', 'wtols[fax]', __('Fax Number', 'webtaru-site-options-login-security'), $options['fax']);

		$this->render_section_heading(__('Address & Map', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-address">' . esc_html__('Address', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-address" name="wtols[address]" rows="4" class="large-text">' . esc_textarea($options['address']) . '</textarea></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-address-link">' . esc_html__('Address Link', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-address-link" name="wtols[address_link]" value="' . esc_attr($options['address_link']) . '" class="regular-text" placeholder="https://maps.google.com/..." />';
		echo '<p class="description">' . esc_html__('Optional. Google Maps URL, page URL, or # placeholder.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-map">' . esc_html__('Map URL or Iframe', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-map" name="wtols[map]" rows="4" class="large-text code">' . esc_textarea($options['map']) . '</textarea></td></tr>';

		$this->render_section_heading(__('Contact Icons', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Icons', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[show_contact_icons]" value="1" ' . checked(!empty($options['show_contact_icons']), true, false) . ' /> ';
		echo esc_html__('Show Font Awesome icons next to contact details.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-icon-placement">' . esc_html__('Icon Placement', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-icon-placement" name="wtols[icon_placement]">';
		echo '<option value="before" ' . selected($options['icon_placement'], 'before', false) . '>' . esc_html__('Before Text', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="after" ' . selected($options['icon_placement'], 'after', false) . '>' . esc_html__('After Text', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		$this->render_text_row('wtols-icon-phone', 'wtols[icon_phone]', __('Phone Icon', 'webtaru-site-options-login-security'), $options['icon_phone']);
		$this->render_text_row('wtols-icon-phone-2', 'wtols[icon_phone_2]', __('Phone 2 Icon', 'webtaru-site-options-login-security'), $options['icon_phone_2']);
		$this->render_text_row('wtols-icon-email', 'wtols[icon_email]', __('Email Icon', 'webtaru-site-options-login-security'), $options['icon_email']);
		$this->render_text_row('wtols-icon-email-2', 'wtols[icon_email_2]', __('Email 2 Icon', 'webtaru-site-options-login-security'), $options['icon_email_2']);
		$this->render_text_row('wtols-icon-fax', 'wtols[icon_fax]', __('Fax Icon', 'webtaru-site-options-login-security'), $options['icon_fax']);
		$this->render_text_row('wtols-icon-address', 'wtols[icon_address]', __('Address Icon', 'webtaru-site-options-login-security'), $options['icon_address']);
		$this->render_text_row('wtols-icon-hours', 'wtols[icon_hours]', __('Hours Icon', 'webtaru-site-options-login-security'), isset($options['icon_hours']) ? $options['icon_hours'] : 'far fa-clock');

		$this->render_section_heading(__('Styling & Layout', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-layout-style">' . esc_html__('Contact Style', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-layout-style" name="wtols[layout_style]">';
		echo '<option value="simple" ' . selected($options['layout_style'], 'simple', false) . '>' . esc_html__('Simple Text', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="pill" ' . selected($options['layout_style'], 'pill', false) . '>' . esc_html__('Pill/Badge Style', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-color-text">' . esc_html__('Text Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-color-text" name="wtols[color_text]" value="' . esc_attr($options['color_text']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-color-background">' . esc_html__('Background Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-color-background" name="wtols[color_background]" value="' . esc_attr($options['color_background']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-color-icon">' . esc_html__('Icon Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-color-icon" name="wtols[color_icon]" value="' . esc_attr($options['color_icon']) . '" class="wtols-color-picker" /></td></tr>';

		$this->render_section_heading(__('Business Hours', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Hours', 'webtaru-site-options-login-security') . '</th><td>';
		$this->render_business_hours_fields($options);
		echo '</td></tr>';
		echo '<tr><th scope="row"><label for="wtols-hours-freeform">' . esc_html__('Custom Text', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-hours-freeform" name="wtols[business_hours_freeform]" rows="5" class="large-text" placeholder="' . esc_attr__("Mon - Fri: 9am - 6pm\nSat - Sun: Closed", 'webtaru-site-options-login-security') . '">' . esc_textarea($options['business_hours_freeform']) . '</textarea>';
		echo '<p class="description">' . esc_html__('If filled, [wtols_hours] shows this text instead of the schedule above. Write anything — e.g. "Mon - Sun: 10am - 8pm".', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-hours-label">' . esc_html__('Section Label', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-hours-label" name="wtols[business_hours_label]" value="' . esc_attr($options['business_hours_label']) . '" class="regular-text" /></td></tr>';

		$this->render_section_heading(__('Social Media', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Social Links', 'webtaru-site-options-login-security') . '</th><td>';
		$this->render_social_fields($options);
		echo '</td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Custom Links', 'webtaru-site-options-login-security') . '</th><td>';
		$this->render_custom_social_fields($options);
		echo '</td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Font Awesome', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_fontawesome]" value="1" ' . checked(!empty($options['enable_fontawesome']), true, false) . ' /> ';
		echo esc_html__('Load Font Awesome icons for social and contact details.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '</tbody></table></div>';

		/* ── Tab: Floating Widgets ── */
		echo '<div class="wtols-tab-panel" data-panel="floating-widgets"><table class="form-table" role="presentation"><tbody>';
		
		$this->render_section_heading(__('WhatsApp Widget', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-whatsapp-number">' . esc_html__('WhatsApp Number', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-whatsapp-number" name="wtols[whatsapp_number]" value="' . esc_attr($options['whatsapp_number']) . '" class="regular-text" placeholder="e.g. +1234567890" /></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Enable Sticky Widget', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_sticky_whatsapp]" value="1" ' . checked(!empty($options['enable_sticky_whatsapp']), true, false) . ' /> ';
		echo esc_html__('Display a floating WhatsApp icon at the bottom corner.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-whatsapp-display">' . esc_html__('Display On', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-sticky-whatsapp-display" name="wtols[sticky_whatsapp_display]">';
		echo '<option value="both" ' . selected($options['sticky_whatsapp_display'], 'both', false) . '>' . esc_html__('Desktop & Mobile', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="desktop" ' . selected($options['sticky_whatsapp_display'], 'desktop', false) . '>' . esc_html__('Desktop Only', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="mobile" ' . selected($options['sticky_whatsapp_display'], 'mobile', false) . '>' . esc_html__('Mobile Only', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-whatsapp-position">' . esc_html__('Widget Position', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-sticky-whatsapp-position" name="wtols[sticky_whatsapp_position]">';
		echo '<option value="left" ' . selected($options['sticky_whatsapp_position'], 'left', false) . '>' . esc_html__('Bottom Left', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="right" ' . selected($options['sticky_whatsapp_position'], 'right', false) . '>' . esc_html__('Bottom Right', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-whatsapp-message">' . esc_html__('Pre-filled Message', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-sticky-whatsapp-message" name="wtols[sticky_whatsapp_message]" rows="3" class="large-text" placeholder="' . esc_attr__('e.g. Hello, I have an inquiry...', 'webtaru-site-options-login-security') . '">' . esc_textarea($options['sticky_whatsapp_message']) . '</textarea>';
		echo '<p class="description">' . esc_html__('Optional. Default message to send when user clicks the widget.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-whatsapp-icon-size">' . esc_html__('Icon Size (px)', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="number" id="wtols-sticky-whatsapp-icon-size" name="wtols[sticky_whatsapp_icon_size]" value="' . esc_attr($options['sticky_whatsapp_icon_size']) . '" class="small-text" /></td></tr>';

		$this->render_section_heading(__('Rating Widget', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Rating Widget', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_rating_widget]" value="1" ' . checked(!empty($options['enable_rating_widget']), true, false) . ' /> ';
		echo esc_html__('Display a floating rating badge in the footer.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-rating-widget-provider">' . esc_html__('Provider', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-rating-widget-provider" name="wtols[rating_widget_provider]">';
		echo '<option value="google" ' . selected($options['rating_widget_provider'], 'google', false) . '>' . esc_html__('Google', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="trustpilot" ' . selected($options['rating_widget_provider'], 'trustpilot', false) . '>' . esc_html__('Trustpilot', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-rating-widget-icon-type">' . esc_html__('Icon Type', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-rating-widget-icon-type" name="wtols[rating_widget_icon_type]">';
		echo '<option value="icon" ' . selected($options['rating_widget_icon_type'], 'icon', false) . '>' . esc_html__('Built-in Icon', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="image" ' . selected($options['rating_widget_icon_type'], 'image', false) . '>' . esc_html__('Custom Image URL', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr class="wtols-rating-image-url-row"><th scope="row"><label for="wtols-rating-widget-image-url">' . esc_html__('Custom Image URL', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="url" id="wtols-rating-widget-image-url" name="wtols[rating_widget_image_url]" value="' . esc_attr($options['rating_widget_image_url']) . '" class="regular-text" placeholder="https://" />';
		echo '<p class="description">' . esc_html__('Used if Icon Type is set to Custom Image URL.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-rating-widget-score">' . esc_html__('Rating Score', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-rating-widget-score" name="wtols[rating_widget_score]" value="' . esc_attr($options['rating_widget_score']) . '" class="small-text" placeholder="5.0" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-rating-widget-link">' . esc_html__('Review Link', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="url" id="wtols-rating-widget-link" name="wtols[rating_widget_link]" value="' . esc_attr($options['rating_widget_link']) . '" class="regular-text" placeholder="https://" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-rating-widget-display">' . esc_html__('Display On', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-rating-widget-display" name="wtols[rating_widget_display]">';
		echo '<option value="both" ' . selected($options['rating_widget_display'], 'both', false) . '>' . esc_html__('Desktop & Mobile', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="desktop" ' . selected($options['rating_widget_display'], 'desktop', false) . '>' . esc_html__('Desktop Only', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="mobile" ' . selected($options['rating_widget_display'], 'mobile', false) . '>' . esc_html__('Mobile Only', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';

		$this->render_section_heading(__('Back to Top Button', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Back to Top', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_back_to_top]" value="1" ' . checked(!empty($options['enable_back_to_top']), true, false) . ' /> ';
		echo esc_html__('Display a back to top arrow on scroll.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-back-to-top-display">' . esc_html__('Display On', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-back-to-top-display" name="wtols[back_to_top_display]">';
		echo '<option value="both" ' . selected($options['back_to_top_display'], 'both', false) . '>' . esc_html__('Desktop & Mobile', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="desktop" ' . selected($options['back_to_top_display'], 'desktop', false) . '>' . esc_html__('Desktop Only', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="mobile" ' . selected($options['back_to_top_display'], 'mobile', false) . '>' . esc_html__('Mobile Only', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-back-to-top-bg-color">' . esc_html__('Background Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-back-to-top-bg-color" name="wtols[back_to_top_bg_color]" value="' . esc_attr($options['back_to_top_bg_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-back-to-top-icon-color">' . esc_html__('Icon Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-back-to-top-icon-color" name="wtols[back_to_top_icon_color]" value="' . esc_attr($options['back_to_top_icon_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-back-to-top-shape">' . esc_html__('Shape', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-back-to-top-shape" name="wtols[back_to_top_shape]">';
		echo '<option value="square" ' . selected($options['back_to_top_shape'], 'square', false) . '>' . esc_html__('Square', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="circle" ' . selected($options['back_to_top_shape'], 'circle', false) . '>' . esc_html__('Circle', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-back-to-top-size">' . esc_html__('Arrow Size (px)', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="number" id="wtols-back-to-top-size" name="wtols[back_to_top_size]" value="' . esc_attr($options['back_to_top_size']) . '" class="small-text" /></td></tr>';

		$this->render_section_heading(__('Smooth Scrolling', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Smooth Scroll', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label style="display:inline-flex; align-items:center; gap:10px; margin-bottom:10px; font-weight:600;">';
		echo '<input type="checkbox" name="wtols[enable_smooth_scroll]" value="1" ' . checked(!empty($options['enable_smooth_scroll']), true, false) . ' onchange="document.getElementById(\'wtols-smooth-scroll-wrapper\').style.display=this.checked?\'block\':\'none\';" /> ';
		echo esc_html__('Enable Site-wide Smooth Scroll', 'webtaru-site-options-login-security') . '</label>';
		
		$smooth_display = !empty($options['enable_smooth_scroll']) ? 'block' : 'none';
		echo '<div id="wtols-smooth-scroll-wrapper" style="display:' . esc_attr($smooth_display) . '; margin-top:10px; padding:12px; background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px;">';
		
		echo '<div style="margin-bottom:15px;">';
		echo '<p style="margin:0 0 5px 0; font-weight:600;">' . esc_html__('Scroll Speed', 'webtaru-site-options-login-security') . ' (<span id="wtols-speed-val">' . esc_html($options['smooth_scroll_speed']) . '</span>)</p>';
		echo '<input type="range" name="wtols[smooth_scroll_speed]" min="0.1" max="1" step="0.1" value="' . esc_attr($options['smooth_scroll_speed']) . '" style="width:100%; max-width:300px;" oninput="document.getElementById(\'wtols-speed-val\').textContent=this.value;" />';
		echo '</div>';

		echo '<div>';
		echo '<p style="margin:0 0 5px 0; font-weight:600;">' . esc_html__('Smoothness', 'webtaru-site-options-login-security') . ' (<span id="wtols-smooth-val">' . esc_html($options['smooth_scroll_smoothness']) . '</span>)</p>';
		echo '<input type="range" name="wtols[smooth_scroll_smoothness]" min="1" max="2" step="0.1" value="' . esc_attr($options['smooth_scroll_smoothness']) . '" style="width:100%; max-width:300px;" oninput="document.getElementById(\'wtols-smooth-val\').textContent=this.value;" />';
		echo '</div>';

		echo '<p class="description" style="margin-top:10px;">' . esc_html__('Adjust the speed and smoothness of the mousewheel scrolling effect.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div></td></tr>';

		$this->render_section_heading(__('Sticky Vertical Button', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Vertical Button', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_sticky_vertical_btn]" value="1" ' . checked(!empty($options['enable_sticky_vertical_btn']), true, false) . ' /> ';
		echo esc_html__('Display a fixed vertical button on the right side.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-text">' . esc_html__('Button Text', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-text" name="wtols[sticky_vertical_btn_text]" value="' . esc_attr($options['sticky_vertical_btn_text']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-icon">' . esc_html__('Icon Class', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-icon" name="wtols[sticky_vertical_btn_icon]" value="' . esc_attr($options['sticky_vertical_btn_icon']) . '" class="regular-text" placeholder="fa-solid fa-comment-dots" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-id-class">' . esc_html__('Custom ID / Class', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-id-class" name="wtols[sticky_vertical_btn_id_class]" value="' . esc_attr($options['sticky_vertical_btn_id_class']) . '" class="regular-text" placeholder="e.g. #my-popup or .trigger-modal" />';
		echo '<p class="description">' . esc_html__('Add an ID starting with # or a class starting with . to trigger Elementor popups.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-bg-color">' . esc_html__('Background Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-bg-color" name="wtols[sticky_vertical_btn_bg_color]" value="' . esc_attr($options['sticky_vertical_btn_bg_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-text-color">' . esc_html__('Text Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-text-color" name="wtols[sticky_vertical_btn_text_color]" value="' . esc_attr($options['sticky_vertical_btn_text_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-icon-color">' . esc_html__('Icon Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-sticky-vertical-btn-icon-color" name="wtols[sticky_vertical_btn_icon_color]" value="' . esc_attr($options['sticky_vertical_btn_icon_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-sticky-vertical-btn-position">' . esc_html__('Vertical Position (%)', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="number" id="wtols-sticky-vertical-btn-position" name="wtols[sticky_vertical_btn_position]" value="' . esc_attr($options['sticky_vertical_btn_position']) . '" class="small-text" min="0" max="100" /></td></tr>';

		$this->render_section_heading(__('Mobile Bottom Buttons', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Mobile Buttons', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_mobile_buttons]" value="1" ' . checked(!empty($options['enable_mobile_buttons']), true, false) . ' /> ';
		echo esc_html__('Display a fixed button bar at the bottom of mobile screens.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-1-text">' . esc_html__('Button 1 Text', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-1-text" name="wtols[mobile_button_1_text]" value="' . esc_attr($options['mobile_button_1_text']) . '" class="regular-text" placeholder="e.g. Call Now" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-1-link">' . esc_html__('Button 1 Link', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-1-link" name="wtols[mobile_button_1_link]" value="' . esc_attr($options['mobile_button_1_link']) . '" class="regular-text" placeholder="e.g. tel:+1234567890" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-1-color">' . esc_html__('Button 1 Background', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-1-color" name="wtols[mobile_button_1_color]" value="' . esc_attr($options['mobile_button_1_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-1-text-color">' . esc_html__('Button 1 Text Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-1-text-color" name="wtols[mobile_button_1_text_color]" value="' . esc_attr($options['mobile_button_1_text_color']) . '" class="wtols-color-picker" /></td></tr>';

		echo '<tr><th scope="row"><label for="wtols-mobile-btn-2-text">' . esc_html__('Button 2 Text', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-2-text" name="wtols[mobile_button_2_text]" value="' . esc_attr($options['mobile_button_2_text']) . '" class="regular-text" placeholder="Optional" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-2-link">' . esc_html__('Button 2 Link', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-2-link" name="wtols[mobile_button_2_link]" value="' . esc_attr($options['mobile_button_2_link']) . '" class="regular-text" placeholder="Optional" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-2-color">' . esc_html__('Button 2 Background', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-2-color" name="wtols[mobile_button_2_color]" value="' . esc_attr($options['mobile_button_2_color']) . '" class="wtols-color-picker" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-mobile-btn-2-text-color">' . esc_html__('Button 2 Text Color', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-mobile-btn-2-text-color" name="wtols[mobile_button_2_text_color]" value="' . esc_attr($options['mobile_button_2_text_color']) . '" class="wtols-color-picker" /></td></tr>';

		echo '</tbody></table></div>';

		/* ── Tab 2: Visual Branding ── */
		echo '<div class="wtols-tab-panel" data-panel="brand"><table class="form-table" role="presentation"><tbody>';
		$this->render_section_heading(__('Brand Logos', 'webtaru-site-options-login-security'));
		$this->render_logo_field('light', __('Light Logo', 'webtaru-site-options-login-security'), $options);
		$this->render_logo_field('dark', __('Dark Logo', 'webtaru-site-options-login-security'), $options);
		$this->render_section_heading(__('Dashboard Branding', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-admin-footer-text">' . esc_html__('Admin Footer Text', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-admin-footer-text" name="wtols[admin_footer_text]" value="' . esc_attr($options['admin_footer_text']) . '" class="large-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-admin-footer-right-text">' . esc_html__('Right Admin Footer', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-admin-footer-right-text" name="wtols[admin_footer_right_text]" value="' . esc_attr($options['admin_footer_right_text']) . '" class="regular-text" />';
		echo '<p class="description">' . esc_html__('Overrides the WordPress version text in the bottom right corner.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '</tbody></table></div>';

		/* ── Tab 3: Login & Security ── */
		echo '<div class="wtols-tab-panel" data-panel="login"><table class="form-table" role="presentation"><tbody>';
		$this->render_section_heading(__('Custom Login URL', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-login-slug">' . esc_html__('Login Slug', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><div class="wtols-inline-url"><span>' . esc_html(trailingslashit(home_url())) . '</span>';
		echo '<input type="text" id="wtols-login-slug" name="wtols[login_slug]" value="' . esc_attr($options['login_slug']) . '" class="regular-text" placeholder="secure-login" /></div>';
		if (!empty($options['login_slug'])) {
			echo '<p><strong>' . esc_html__('Active:', 'webtaru-site-options-login-security') . '</strong> <code>' . esc_html($this->get_custom_login_url()) . '</code></p>';
		}
		echo '</td></tr>';

		// Cache exclusion warning
		echo '<tr><th scope="row">' . esc_html__('Caching Notice', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><div class="notice notice-warning inline" style="margin: 0 0 10px 0; border-left-color: #f59e0b; padding: 12px; background: #fffbeb; max-width: 600px;">';
		echo '<p style="margin:0 0 8px 0; font-weight:600; color:#b45309;"><span class="dashicons dashicons-warning" style="color:#d97706; vertical-align:middle; margin-right:4px;"></span>' . esc_html__('Important Caching Notice:', 'webtaru-site-options-login-security') . '</p>';
		$caching_notice = sprintf(
			/* translators: 1: opening strong tag, 2: closing strong tag */
			__('If you are using a caching plugin (like WP Rocket, LiteSpeed Cache, SG Optimizer, W3 Total Cache) or a CDN service (like Cloudflare), you %1$sMUST exclude the Login Slug%2$s from caching in their settings. Otherwise, the custom login URL may redirect to the home page or fail to load. (Alternative: Use the Query Parameter method below which is immune to caching).', 'webtaru-site-options-login-security'),
			'<strong>',
			'</strong>'
		);
		echo '<p style="margin:0; font-size:13px; line-height:1.5; color:#4b5563;">' . wp_kses($caching_notice, array('strong' => array())) . '</p></div></td></tr>';

		// Secret query parameter key
		$secret_key = isset($options['login_secret_key']) ? $options['login_secret_key'] : '';
		echo '<tr><th scope="row"><label for="wtols-login-secret-key">' . esc_html__('Login Secret Key (Cache-Proof)', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td>';
		echo '<input type="text" id="wtols-login-secret-key" name="wtols[login_secret_key]" value="' . esc_attr($secret_key) . '" class="regular-text" placeholder="e.g. mysecretlogin" />';
		echo '<p class="description">' . esc_html__('Optional. A secret key for query-parameter based logins (e.g. wp-login.php?secret=yourkey). This method is 100% immune to caching and does not require cache configuration.', 'webtaru-site-options-login-security') . '</p>';
		if (!empty($secret_key)) {
			echo '<p style="margin-top:8px;"><strong>' . esc_html__('Active:', 'webtaru-site-options-login-security') . '</strong> <code>' . esc_html(site_url('wp-login.php?secret=' . $secret_key)) . '</code></p>';
		}
		echo '</td></tr>';
		$this->render_image_field('login_logo_id', __('Login Logo', 'webtaru-site-options-login-security'), $options);
		$this->render_image_field('login_background_id', __('Login Background', 'webtaru-site-options-login-security'), $options);
		echo '<tr><th scope="row"><label for="wtols-login-error-message">' . esc_html__('Error Message', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-login-error-message" name="wtols[login_error_message]" value="' . esc_attr($options['login_error_message']) . '" class="large-text" /></td></tr>';

		// Restrict Login by IP
		$this->render_section_heading(__('Restrict Login Page by IP', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Block Login Page', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[block_login_page]" value="1" ' . checked(!empty($options['block_login_page']), true, false) . ' /> ';
		echo esc_html__('Block access to the login page and admin dashboard for unauthorized IPs', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row"><label for="wtols-login-ip-whitelist">' . esc_html__('Authorized IPs', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-login-ip-whitelist" name="wtols[login_ip_whitelist]" rows="5" class="large-text" placeholder="e.g. 192.168.1.1">' . esc_textarea($options['login_ip_whitelist']) . '</textarea>';
		$current_ip = $this->get_client_ip();
		// translators: %s: Current IP address.
		echo '<p class="description">' . sprintf(esc_html__('Enter the IP addresses authorized to access the login page and wp-admin, one per line. Your current IP address is %s. If left empty while blocked, the login page will be inaccessible globally (you can bypass using the Custom Secret Key query parameter, e.g. wp-login.php?secret=yourkey, to prevent lockout).', 'webtaru-site-options-login-security'), '<code>' . esc_html($current_ip) . '</code>') . '</p>';
		echo '</td></tr>';
		
		// Advanced Login Designer
		$this->render_section_heading(__('Advanced Login Designer (Premium)', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Designer', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_login_designer]" value="1" ' . checked(!empty($options['enable_login_designer']), true, false) . ' /> ' . esc_html__('Enable Advanced Login Layouts', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-login-designer-layout">' . esc_html__('Layout Style', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-login-designer-layout" name="wtols[login_designer_layout]">';
		$current_layout = isset($options['login_designer_layout']) ? $options['login_designer_layout'] : 'default';
		echo '<option value="default" ' . selected($current_layout, 'default', false) . '>' . esc_html__('Default Minimal', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="split-left" ' . selected($current_layout, 'split-left', false) . '>' . esc_html__('Split Screen (Left Form)', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="split-right" ' . selected($current_layout, 'split-right', false) . '>' . esc_html__('Split Screen (Right Form)', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="glassmorphism" ' . selected($current_layout, 'glassmorphism', false) . '>' . esc_html__('Centered Glassmorphism', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		$this->render_image_field('login_bg_image_id', __('Designer Background Image', 'webtaru-site-options-login-security'), $options);

		// Geo Blocking
		$this->render_section_heading(__('Geo-Blocking (Premium)', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Geo-Blocking', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_geo_blocking]" value="1" ' . checked(!empty($options['enable_geo_blocking']), true, false) . ' /> ' . esc_html__('Block access from specific countries', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-geo-block-type">' . esc_html__('Block Target', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-geo-block-type" name="wtols[geo_block_type]">';
		$geo_type = isset($options['geo_block_type']) ? $options['geo_block_type'] : 'login';
		echo '<option value="login" ' . selected($geo_type, 'login', false) . '>' . esc_html__('Login & Admin Only (Recommended)', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="all" ' . selected($geo_type, 'all', false) . '>' . esc_html__('Entire Website', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		
		echo '<tr><th scope="row"><label for="wtols-geo-blocked-countries">' . esc_html__('Blocked Country Codes', 'webtaru-site-options-login-security') . '</label></th>';
		
		// Handle array to string conversion safely for display
		$geo_countries = isset($options['geo_blocked_countries']) ? $options['geo_blocked_countries'] : '';
		if (is_array($geo_countries)) {
			$geo_countries = implode(',', $geo_countries);
		}
		
		echo '<td><input type="text" id="wtols-geo-blocked-countries" name="wtols[geo_blocked_countries]" value="' . esc_attr($geo_countries) . '" class="regular-text" placeholder="CN, RU, BR" />';
		echo '<p class="description">' . esc_html__('Comma-separated 2-letter ISO country codes (e.g. CN, RU).', 'webtaru-site-options-login-security') . '</p></td></tr>';

		$this->render_section_heading(__('Login Redirects & Menu', 'webtaru-site-options-login-security'));

		// Log In/Out Menu toggle
		$login_logout_enabled = !empty($options['enable_login_logout_menu']);
		echo '<tr><th scope="row">' . esc_html__('Log In/Out Menu', 'webtaru-site-options-login-security') . '</th><td>';
		echo '<label style="display:inline-flex; align-items:center; gap:10px; margin-bottom:10px; font-weight:600; font-size:13px;">';
		echo '<input type="checkbox" name="wtols[enable_login_logout_menu]" id="wtols-enable-login-logout-menu" value="1" ' . checked($login_logout_enabled, true, false) . ' style="width:40px !important;" onchange="document.getElementById(\'wtols-login-logout-menu-info\').style.display=this.checked?\'block\':\'none\';" />';
		echo esc_html__('Enable Dynamic Login / Logout Menu Item', 'webtaru-site-options-login-security') . '</label>';
		echo '<div id="wtols-login-logout-menu-info" style="' . ($login_logout_enabled ? '' : 'display:none;') . '">';
		echo '<p class="description">' . esc_html__('In Appearance > Menus, add a Custom Link with URL:', 'webtaru-site-options-login-security') . ' <code>#wtols-login-logout#</code><br>';
		echo '<em>' . esc_html__('The label will automatically switch between "Log In" and "Log Out" based on the visitor\'s session.', 'webtaru-site-options-login-security') . '</em></p>';

		// Custom URL for public login link
		$menu_login_url = isset($options['menu_login_url']) ? $options['menu_login_url'] : '';
		echo '<p style="margin-top:12px; margin-bottom:0;"><label for="wtols-menu-login-url" style="font-weight:600; display:block; margin-bottom:4px;">' . esc_html__('Custom Login Link URL', 'webtaru-site-options-login-security') . '</label>';
		echo '<input type="url" id="wtols-menu-login-url" name="wtols[menu_login_url]" value="' . esc_attr($menu_login_url) . '" class="regular-text" placeholder="https://example.com/my-account/" style="width:100%; max-width:400px;" />';
		echo '<br><span class="description">' . esc_html__('Optional. If you want the menu login link to point to a front-end login page (like WooCommerce /my-account/) so that public users do not see your secret admin login URL. If left empty, it will auto-detect WooCommerce or fallback to your custom admin login URL.', 'webtaru-site-options-login-security') . '</span></p>';
		echo '</div>';
		echo '</td></tr>';

		// ── Redirect After Login ──
		$login_redirects = is_array($options['redirect_after_login']) ? $options['redirect_after_login'] : array();
		$login_master    = !empty($options['enable_redirect_login']);
		echo '<tr><th scope="row">' . esc_html__('Redirect After Login', 'webtaru-site-options-login-security') . '</th><td>';

		// Master toggle
		echo '<label style="display:inline-flex; align-items:center; gap:10px; margin-bottom:14px; font-weight:600; font-size:13px;">';
		echo '<input type="checkbox" name="wtols[enable_redirect_login]" value="1" id="wtols-enable-redirect-login" ' . checked($login_master, true, false) . ' style="width:40px !important;" onchange="document.getElementById(\'wtols-login-redirect-roles\').style.display=this.checked?\'block\':\'none\';" />';
		echo esc_html__('Enable Login Redirect', 'webtaru-site-options-login-security') . '</label>';

		// Per-role cards
		echo '<div id="wtols-login-redirect-roles" style="' . ($login_master ? '' : 'display:none;') . '">';
		echo '<div style="background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px; overflow:hidden;">';
		$roles      = wp_roles()->get_names();
		$role_count = count($roles);
		$i          = 0;
		foreach ($roles as $role => $name) {
			$i++;
			$enabled = !empty($login_redirects['enable_' . $role]);
			$val     = isset($login_redirects[$role]) ? $login_redirects[$role] : '';
			$border  = ($i < $role_count) ? 'border-bottom:1px solid #e2e4e7;' : '';
			echo '<div style="display:grid; grid-template-columns:46px 150px 1fr; align-items:center; padding:10px 14px; ' . esc_attr($border) . '">';
			echo '<input type="checkbox" name="wtols[redirect_after_login][enable_' . esc_attr($role) . ']" value="1" ' . checked($enabled, true, false) . ' style="width:40px !important;" />';
			echo '<span style="font-weight:500; font-size:13px; color:#1d2327;">' . esc_html(translate_user_role($name)) . '</span>';
			echo '<input type="url" name="wtols[redirect_after_login][' . esc_attr($role) . ']" value="' . esc_attr($val) . '" class="regular-text" placeholder="https://example.com/dashboard" style="width:100%; max-width:360px;" />';
			echo '</div>';
		}
		echo '</div>';
		echo '<p class="description" style="margin-top:8px;">' . esc_html__('Toggle each role ON and enter its redirect URL. New roles (e.g. WooCommerce Customer) appear automatically.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div>';
		echo '</td></tr>';

		// ── Redirect After Logout ──
		$logout_redirects = is_array($options['redirect_after_logout']) ? $options['redirect_after_logout'] : array();
		$logout_master    = !empty($options['enable_redirect_logout']);
		echo '<tr><th scope="row">' . esc_html__('Redirect After Logout', 'webtaru-site-options-login-security') . '</th><td>';

		// Master toggle
		echo '<label style="display:inline-flex; align-items:center; gap:10px; margin-bottom:14px; font-weight:600; font-size:13px;">';
		echo '<input type="checkbox" name="wtols[enable_redirect_logout]" value="1" id="wtols-enable-redirect-logout" ' . checked($logout_master, true, false) . ' style="width:40px !important;" onchange="document.getElementById(\'wtols-logout-redirect-roles\').style.display=this.checked?\'block\':\'none\';" />';
		echo esc_html__('Enable Logout Redirect', 'webtaru-site-options-login-security') . '</label>';

		// Per-role cards
		echo '<div id="wtols-logout-redirect-roles" style="' . ($logout_master ? '' : 'display:none;') . '">';
		echo '<div style="background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px; overflow:hidden;">';
		$i = 0;
		foreach ($roles as $role => $name) {
			$i++;
			$enabled = !empty($logout_redirects['enable_' . $role]);
			$val     = isset($logout_redirects[$role]) ? $logout_redirects[$role] : '';
			$border  = ($i < $role_count) ? 'border-bottom:1px solid #e2e4e7;' : '';
			echo '<div style="display:grid; grid-template-columns:46px 150px 1fr; align-items:center; padding:10px 14px; ' . esc_attr($border) . '">';
			echo '<input type="checkbox" name="wtols[redirect_after_logout][enable_' . esc_attr($role) . ']" value="1" ' . checked($enabled, true, false) . ' style="width:40px !important;" />';
			echo '<span style="font-weight:500; font-size:13px; color:#1d2327;">' . esc_html(translate_user_role($name)) . '</span>';
			echo '<input type="url" name="wtols[redirect_after_logout][' . esc_attr($role) . ']" value="' . esc_attr($val) . '" class="regular-text" placeholder="https://example.com/" style="width:100%; max-width:360px;" />';
			echo '</div>';
		}
		echo '</div>';
		echo '<p class="description" style="margin-top:8px;">' . esc_html__('Toggle each role ON and enter its redirect URL. New roles (e.g. WooCommerce Customer) appear automatically.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div>';
		echo '</td></tr>';

		$this->render_section_heading(__('Login CAPTCHA', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-captcha-type">' . esc_html__('CAPTCHA Service', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-captcha-type" name="wtols[captcha_type]">';
		echo '<option value="none" ' . selected($options['captcha_type'], 'none', false) . '>' . esc_html__('None', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="recaptcha_v3" ' . selected($options['captcha_type'], 'recaptcha_v3', false) . '>' . esc_html__('Google reCAPTCHA v3', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="turnstile" ' . selected($options['captcha_type'], 'turnstile', false) . '>' . esc_html__('Cloudflare Turnstile', 'webtaru-site-options-login-security') . '</option>';
		echo '</select></td></tr>';
		echo '<tr class="wtols-captcha-row"><th scope="row"><label for="wtols-captcha-site-key">' . esc_html__('Site Key', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-captcha-site-key" name="wtols[captcha_site_key]" value="' . esc_attr($options['captcha_site_key']) . '" class="regular-text" /></td></tr>';
		echo '<tr class="wtols-captcha-row"><th scope="row"><label for="wtols-captcha-secret-key">' . esc_html__('Secret Key', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td>';
		echo '<div style="position: relative; display: inline-block; max-width: 25em; width: 100%;">';
		echo '<input type="password" id="wtols-captcha-secret-key" name="wtols[captcha_secret_key]" value="' . esc_attr($options['captcha_secret_key']) . '" class="regular-text" style="padding-right: 40px; width: 100%; box-sizing: border-box;" autocomplete="new-password" />';
		echo '<span class="dashicons dashicons-visibility" id="wtols-toggle-captcha-secret" style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; color: #787c82;"></span>';
		echo '</div>';
		echo '</td></tr>';
		$this->render_section_heading(__('Login Attempt Limiter', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[limiter_enabled]" value="1" ' . checked(!empty($options['limiter_enabled']), true, false) . ' /> ';
		echo esc_html__('Block IPs after too many failed attempts.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Max Attempts', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><input type="number" name="wtols[limiter_max_attempts]" value="' . esc_attr($options['limiter_max_attempts']) . '" min="1" max="20" class="small-text" /></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Lockout (min)', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><input type="number" name="wtols[limiter_lockout_duration]" value="' . esc_attr($options['limiter_lockout_duration']) . '" min="1" max="1440" class="small-text" /></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Lockout Message', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><input type="text" name="wtols[limiter_message]" value="' . esc_attr($options['limiter_message']) . '" class="large-text" /></td></tr>';
		$this->render_section_heading(__('XML-RPC Security', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Disable XML-RPC', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_xmlrpc]" value="1" ' . checked(!empty($options['disable_xmlrpc']), true, false) . ' /> ';
		echo esc_html__('Disable XML-RPC to prevent pingback and brute-force attacks.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('System Hardening', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Hide WP Version', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[hide_wp_version]" value="1" ' . checked(!empty($options['hide_wp_version']), true, false) . ' /> ';
		echo esc_html__('Remove WordPress version from frontend (Header, Scripts, and Styles) for better security.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Disable File Editor', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_file_editor]" value="1" ' . checked(!empty($options['disable_file_editor']), true, false) . ' /> ';
		echo esc_html__('Disable built-in theme and plugin file editors.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Advanced XSS Protection', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label style="display:inline-flex; align-items:center; gap:10px; margin-bottom:10px; font-weight:600;">';
		echo '<input type="checkbox" name="wtols[xss_protection]" value="1" ' . checked(!empty($options['xss_protection']), true, false) . ' onchange="document.getElementById(\'wtols-xss-mode-wrapper\').style.display=this.checked?\'block\':\'none\';" /> ';
		echo esc_html__('Enable Protection Headers', 'webtaru-site-options-login-security') . '</label>';

		$xss_display = !empty($options['xss_protection']) ? 'block' : 'none';
		echo '<div id="wtols-xss-mode-wrapper" style="display:' . esc_attr($xss_display) . '; margin-top:10px; padding:12px; background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px;">';
		echo '<p style="margin:0 0 8px 0; font-weight:600;">' . esc_html__('Protection Mode', 'webtaru-site-options-login-security') . '</p>';
		echo '<select name="wtols[xss_mode]" style="width:100%; max-width:300px;">';
		echo '<option value="basic" ' . selected($options['xss_mode'], 'basic', false) . '>' . esc_html__('Basic (Recommended)', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="advanced" ' . selected($options['xss_mode'], 'advanced', false) . '>' . esc_html__('Advanced (CSP Header)', 'webtaru-site-options-login-security') . '</option>';
		echo '</select>';
		echo '<p class="description" style="margin-top:8px;">' . esc_html__('Advanced mode enables Content Security Policy. Use with caution as it might block some external resources.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Disable Common Usernames', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_common_usernames]" value="1" ' . checked(!empty($options['disable_common_usernames']), true, false) . ' /> ';
		echo esc_html__('Prevent registration of common usernames like "admin" or "root".', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('Security & Login Email Alerts', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Successful Login Alerts', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" id="wtols-enable-login-alerts" name="wtols[enable_login_alerts]" value="1" ' . checked(!empty($options['enable_login_alerts']), true, false) . ' onchange="wtols_toggle_alert_email_row();" /> ';
		echo esc_html__('Send email notification on successful login.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Enable IP Lockout Alerts', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" id="wtols-enable-ip-lockout-alerts" name="wtols[enable_ip_lockout_alerts]" value="1" ' . checked(!empty($options['enable_ip_lockout_alerts']), true, false) . ' onchange="wtols_toggle_alert_email_row();" /> ';
		echo esc_html__('Send email notification when an IP is blocked/locked out.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Disable Update Emails', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_update_emails]" value="1" ' . checked(!empty($options['disable_update_emails']), true, false) . ' /> ';
		echo esc_html__('Disable auto-update email notifications for core, themes, and plugins.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$alert_email_display = (!empty($options['enable_login_alerts']) || !empty($options['enable_ip_lockout_alerts'])) ? '' : 'display:none;';
		echo '<tr id="wtols-login-alert-email-row" style="' . esc_attr($alert_email_display) . '"><th scope="row"><label for="wtols-login-alert-email">' . esc_html__('Notification Email', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="email" id="wtols-login-alert-email" name="wtols[login_alert_email]" value="' . esc_attr($options['login_alert_email']) . '" class="regular-text" placeholder="' . esc_attr(get_option('admin_email')) . '" />';
		echo '<p class="description">' . esc_html__('Email address where security and login alerts will be sent.', 'webtaru-site-options-login-security') . '</p></td></tr>';

		$this->render_section_heading(__('Security Firewall', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Basic Firewall', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_firewall]" value="1" ' . checked(!empty($options['enable_firewall']), true, false) . ' /> ';
		echo esc_html__('Block common malicious query strings like eval() and SQL injection attempts.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Restrict REST API', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[restrict_rest_api]" value="1" ' . checked(!empty($options['restrict_rest_api']), true, false) . ' /> ';
		echo esc_html__('Block access to REST API for non-logged-in users.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('Email Two-Factor Authentication', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Email 2FA', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_2fa]" value="1" ' . checked(!empty($options['enable_2fa']), true, false) . ' onchange="document.getElementById(\'wtols-2fa-roles-wrapper\').style.display=this.checked?\'block\':\'none\';" /> ';
		echo esc_html__('Enable email-based 2FA to protect user accounts on login.', 'webtaru-site-options-login-security') . '</label>';
		
		$tfa_display = !empty($options['enable_2fa']) ? 'block' : 'none';
		$tfa_roles = is_array($options['2fa_roles']) ? $options['2fa_roles'] : array('administrator');
		echo '<div id="wtols-2fa-roles-wrapper" style="display:' . esc_attr($tfa_display) . '; margin-top:10px; padding:12px; background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px;">';
		echo '<p style="margin:0 0 8px 0; font-weight:600;">' . esc_html__('Select Roles that Require 2FA', 'webtaru-site-options-login-security') . '</p>';
		$roles = wp_roles()->get_names();
		foreach ($roles as $role => $name) {
			$checked = in_array($role, $tfa_roles, true);
			echo '<label style="display:inline-block; margin-right:15px; margin-bottom:5px; font-weight:normal;"><input type="checkbox" name="wtols[2fa_roles][]" value="' . esc_attr($role) . '" ' . checked($checked, true, false) . ' /> ' . esc_html(translate_user_role($name)) . '</label>';
		}
		echo '<p class="description" style="margin-top:8px;">' . esc_html__('Only selected user roles will trigger 2FA upon login.', 'webtaru-site-options-login-security') . '</p>';
		$this->render_section_heading(__('Inactivity Auto Logout', 'webtaru-site-options-login-security'));
		$enable_auto_logout = !empty($options['enable_auto_logout']);
		echo '<tr><th scope="row">' . esc_html__('Enable Auto Logout', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_auto_logout]" id="wtols-enable-auto-logout" value="1" ' . checked($enable_auto_logout, true, false) . ' onchange="document.getElementById(\'wtols-auto-logout-wrapper\').style.display=this.checked?\'block\':\'none\';" /> ';
		echo esc_html__('Automatically log out inactive users.', 'webtaru-site-options-login-security') . '</label>';

		$logout_display = $enable_auto_logout ? 'block' : 'none';
		$auto_logout_idle_time = isset($options['auto_logout_idle_time']) ? absint($options['auto_logout_idle_time']) : 15;
		$auto_logout_roles = is_array($options['auto_logout_roles']) ? $options['auto_logout_roles'] : array();

		echo '<div id="wtols-auto-logout-wrapper" style="display:' . esc_attr($logout_display) . '; margin-top:10px; padding:12px; background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px;">';
		echo '<p style="margin:0 0 8px 0; font-weight:600;"><label for="wtols-auto-logout-idle-time">' . esc_html__('Inactivity Timeout (Minutes)', 'webtaru-site-options-login-security') . '</label></p>';
		echo '<input type="number" id="wtols-auto-logout-idle-time" name="wtols[auto_logout_idle_time]" value="' . esc_attr($auto_logout_idle_time) . '" min="1" max="1440" class="small-text" style="margin-bottom:12px;" /> ' . esc_html__('minutes', 'webtaru-site-options-login-security');

		echo '<p style="margin:8px 0 8px 0; font-weight:600;">' . esc_html__('Select Roles to Auto Logout', 'webtaru-site-options-login-security') . '</p>';
		$roles_list = wp_roles()->get_names();
		foreach ($roles_list as $role => $name) {
			$checked = in_array($role, $auto_logout_roles, true);
			echo '<label style="display:inline-block; margin-right:15px; margin-bottom:5px; font-weight:normal;"><input type="checkbox" name="wtols[auto_logout_roles][]" value="' . esc_attr($role) . '" ' . checked($checked, true, false) . ' /> ' . esc_html(translate_user_role($name)) . '</label>';
		}
		echo '<p class="description" style="margin-top:8px;">' . esc_html__('If no roles are selected, auto logout will apply to all logged-in users.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div></td></tr>';

		$this->render_section_heading(__('Security Logs', 'webtaru-site-options-login-security'));
		echo '<tr><td colspan="2">';
		if (empty($options['login_logs'])) {
			echo '<p class="description" id="wtols-no-logs-msg">' . esc_html__('No failed login attempts logged yet.', 'webtaru-site-options-login-security') . '</p>';
		} else {
			echo '<div style="margin-bottom: 10px; display: flex; gap: 8px; align-items: center;">';
			echo '<button type="button" class="button wtols-clear-logs" style="color: #b32d2e; border-color: #b32d2e;">' . esc_html__('Clear List', 'webtaru-site-options-login-security') . '</button>';
			$export_url = wp_nonce_url(admin_url('admin-ajax.php?action=wtols_export_security_logs'), 'wtols_export_logs_action');
			echo '<a href="' . esc_url($export_url) . '" class="button button-secondary"><span class="dashicons dashicons-download" style="vertical-align: middle; font-size: 16px; width: 16px; height: 16px; margin-right: 4px; margin-top: 2px;"></span>' . esc_html__('Export to CSV', 'webtaru-site-options-login-security') . '</a>';
			echo '</div>';

			echo '<table class="wp-list-table widefat fixed striped" id="wtols-security-logs-table" style="margin-top: 10px;">';
			echo '<thead><tr><th style="width: 45%;">' . esc_html__('IP Address', 'webtaru-site-options-login-security') . '</th><th style="width: 25%;">' . esc_html__('Username', 'webtaru-site-options-login-security') . '</th><th style="width: 30%;">' . esc_html__('Time', 'webtaru-site-options-login-security') . '</th></tr></thead>';
			echo '<tbody id="wtols-security-logs-body">';
			foreach ($options['login_logs'] as $log) {
				$ip_link = 'https://ipinfo.io/' . urlencode($log['ip']);
				echo '<tr>';
				echo '<td style="word-break: break-all;"><a href="' . esc_url($ip_link) . '" target="_blank" rel="noopener noreferrer" title="View IP Location">' . esc_html($log['ip']) . '</a></td>';
				echo '<td>' . esc_html($log['user']) . '</td>';
				echo '<td>' . esc_html($log['time']) . '</td>';
				echo '</tr>';
			}
			echo '</tbody></table>';
			
			if (count($options['login_logs']) > 20) {
				echo '<div id="wtols-security-logs-pagination" style="margin-top: 10px; display: flex; gap: 5px; align-items: center;"></div>';
			}
			
			echo '<p class="description">' . esc_html__('Only the last 100 failed attempts are logged.', 'webtaru-site-options-login-security') . '</p>';
		}
		echo '</td></tr>';

		$this->render_section_heading(__('Locked IPs', 'webtaru-site-options-login-security'));
		echo '<tr><td colspan="2">';
		$this->render_locked_ips_table();
		echo '</td></tr>';

		$this->render_section_heading(__('IP Access Control (Whitelist / Blacklist)', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row"><label for="wtols-ip-whitelist">' . esc_html__('IP Whitelist', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-ip-whitelist" name="wtols[ip_whitelist]" rows="5" class="large-text code" style="width:100%; max-width:500px;" placeholder="e.g. 192.168.1.1">' . esc_textarea($options['ip_whitelist']) . '</textarea>';
		echo '<p class="description">' . esc_html__('Allowed IP addresses, one per line. Whitelisted IPs bypass lockout limits.', 'webtaru-site-options-login-security') . '</p></td></tr>';

		echo '<tr><th scope="row"><label for="wtols-ip-blacklist">' . esc_html__('IP Blacklist', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-ip-blacklist" name="wtols[ip_blacklist]" rows="5" class="large-text code" style="width:100%; max-width:500px;" placeholder="e.g. 203.0.113.5">' . esc_textarea($options['ip_blacklist']) . '</textarea>';
		echo '<p class="description">' . esc_html__('Blocked IP addresses, one per line. Access from blacklisted IPs will be blocked immediately.', 'webtaru-site-options-login-security') . '</p></td></tr>';

		echo '</tbody></table></div>';

		echo '<script type="text/javascript">
		function wtols_toggle_alert_email_row() {
			var loginAlerts = document.getElementById("wtols-enable-login-alerts");
			var lockoutAlerts = document.getElementById("wtols-enable-ip-lockout-alerts");
			var emailRow = document.getElementById("wtols-login-alert-email-row");
			if (loginAlerts && lockoutAlerts && emailRow) {
				emailRow.style.display = (loginAlerts.checked || lockoutAlerts.checked) ? "table-row" : "none";
			}
		}
		</script>';
		
		// Inline Script for Pagination and AJAX clear handlers
		echo '<script>
			jQuery(document).ready(function($) {
				// Pagination logic
				function setupPagination(tableBodyId, paginationId, itemsPerPage) {
					var $tableBody = $("#" + tableBodyId);
					var $rows = $tableBody.find("tr");
					var totalRows = $rows.length;
					var totalPages = Math.ceil(totalRows / itemsPerPage);
					var $pagination = $("#" + paginationId);
					
					if (totalPages <= 1) {
						$pagination.hide();
						return;
					}
					
					function showPage(page) {
						$rows.hide();
						$rows.slice((page - 1) * itemsPerPage, page * itemsPerPage).show();
						$pagination.find("button").removeClass("button-primary");
						$pagination.find("button[data-page=\'" + page + "\']").addClass("button-primary");
					}
					
					$pagination.empty();
					for (var i = 1; i <= totalPages; i++) {
						var $btn = $("<button type=\'button\' class=\'button\' data-page=\'" + i + "\'>" + i + "</button>");
						$btn.on("click", function() {
							showPage($(this).data("page"));
						});
						$pagination.append($btn);
					}
					showPage(1);
				}
				
				setupPagination("wtols-security-logs-body", "wtols-security-logs-pagination", 20);
				setupPagination("wtols-locked-ips-body", "wtols-locked-ips-pagination", 20);
				
				// AJAX Clear Security Logs
				$(".wtols-clear-logs").on("click", function() {
					if (confirm("' . esc_js(__('Are you sure you want to clear all security logs?', 'webtaru-site-options-login-security')) . '")) {
						var $btn = $(this);
						$btn.prop("disabled", true).text("' . esc_js(__('Clearing...', 'webtaru-site-options-login-security')) . '");
						$.post(ajaxurl, {
							action: "wtols_clear_security_logs",
							_wpnonce: wtolsAdmin.clearLogsNonce || "' . esc_js(wp_create_nonce('wtols_clear_logs')) . '"
						}, function(response) {
							if (response.success) {
								$("#wtols-security-logs-table, #wtols-security-logs-pagination").remove();
								$btn.parent().after("<p class=\'description\'>" + "' . esc_js(__('No failed login attempts logged yet.', 'webtaru-site-options-login-security')) . '" + "</p>");
								$btn.parent().remove();
							} else {
								alert("' . esc_js(__('Failed to clear logs.', 'webtaru-site-options-login-security')) . '");
								$btn.prop("disabled", false).text("' . esc_js(__('Clear List', 'webtaru-site-options-login-security')) . '");
							}
						});
					}
				});
				
				// AJAX Clear Locked IPs
				$(".wtols-clear-locked-ips").on("click", function() {
					if (confirm("' . esc_js(__('Are you sure you want to unlock all IPs and clear the list?', 'webtaru-site-options-login-security')) . '")) {
						var $btn = $(this);
						$btn.prop("disabled", true).text("' . esc_js(__('Clearing...', 'webtaru-site-options-login-security')) . '");
						$.post(ajaxurl, {
							action: "wtols_clear_locked_ips",
							_wpnonce: wtolsAdmin.clearLockedIpsNonce || "' . esc_js(wp_create_nonce('wtols_clear_locked_ips')) . '"
						}, function(response) {
							if (response.success) {
								$("#wtols-locked-ips-table, #wtols-locked-ips-pagination").remove();
								$btn.parent().after("<p class=\'wtols-no-lockouts\'>" + "' . esc_js(__('No IPs are currently locked out.', 'webtaru-site-options-login-security')) . '" + "</p>");
								$btn.parent().remove();
							} else {
								alert("' . esc_js(__('Failed to clear locked IPs.', 'webtaru-site-options-login-security')) . '");
								$btn.prop("disabled", false).text("' . esc_js(__('Clear List', 'webtaru-site-options-login-security')) . '");
							}
						});
					}
				});
			});
		</script>';


		/* ── Tab 4: Premium Scanners ── */
		echo '<div class="wtols-tab-panel" data-panel="premium-scanners"><table class="form-table" role="presentation"><tbody>';
		$this->render_section_heading(__('File & Malware Scanner', 'webtaru-site-options-login-security'));
		echo '<tr><td colspan="2">';
		echo '<div class="notice notice-warning inline" style="margin: 0 0 15px 0; max-width: 600px;">';
		echo '<p><strong style="color:#d97706;">' . esc_html__('Warning:', 'webtaru-site-options-login-security') . '</strong> ' . esc_html__('Before using the auto-clean feature, please backup your database and files. Deleting files or cleaning database options can break your site if it is heavily infected or if there is a false positive.', 'webtaru-site-options-login-security') . '</p></div>';
		echo '<p>' . esc_html__('Scan your active plugins and themes for known malware signatures and suspicious code like eval(), base64 injections, and iframes.', 'webtaru-site-options-login-security') . '</p>';
		echo '<button type="button" id="wtols-run-scanner" class="button button-primary">' . esc_html__('Run File & DB Scan Now', 'webtaru-site-options-login-security') . '</button>';
		echo '<div id="wtols-scanner-results" style="margin-top: 20px; display: none;">';
		echo '<h4>' . esc_html__('Scan Results:', 'webtaru-site-options-login-security') . '</h4>';
		echo '<div class="wtols-scanner-log" style="background: #f8fafc; border: 1px solid #cbd5e1; padding: 15px; border-radius: 8px; max-height: 400px; overflow-y: auto; font-family: monospace;"></div>';
		echo '</div>';
		echo '<script>
			jQuery(document).ready(function($) {
				$("#wtols-run-scanner").on("click", function() {
					var btn = $(this);
					var resDiv = $("#wtols-scanner-results");
					var logDiv = resDiv.find(".wtols-scanner-log");
					
					btn.prop("disabled", true).text("' . esc_html__('Scanning...', 'webtaru-site-options-login-security') . '");
					logDiv.html("Initializing scan...<br>");
					resDiv.show();
					
					$.post(ajaxurl, {
						action: "wtols_run_scanner",
						nonce: "' . esc_js(wp_create_nonce('wtols_scanner_nonce')) . '",
						scan_type: "full"
					}, function(response) {
						btn.prop("disabled", false).text("' . esc_html__('Run File & DB Scan Now', 'webtaru-site-options-login-security') . '");
						if(response.success) {
							logDiv.append("<span style=\'color: green;\'>Scan completed successfully.</span><br><br>");
							
							if(response.data.files.length > 0) {
								logDiv.append("<strong style=\'color: #d63638;\'>File Issues Found:</strong><br>");
								$.each(response.data.files, function(i, file) {
									logDiv.append("<div style=\'margin-bottom: 5px; padding-bottom: 5px; border-bottom: 1px dashed #ccc;\'>- " + file.path + " : " + file.issue + " <button type=\'button\' class=\'button button-small wtols-clean-btn\' data-type=\'" + file.action_type + "\' data-target=\'" + file.action_data + "\' style=\'color: #d63638; border-color: #d63638;\'>Delete File</button></div>");
								});
							} else {
								logDiv.append("No suspicious files found.<br>");
							}
							
							logDiv.append("<br>");
							
							if(response.data.db.length > 0) {
								logDiv.append("<strong style=\'color: #d63638;\'>Database Issues Found:</strong><br>");
								$.each(response.data.db, function(i, item) {
									var btnLabel = item.action_type === "user" ? "Delete User" : "Clean Option";
									logDiv.append("<div style=\'margin-bottom: 5px; padding-bottom: 5px; border-bottom: 1px dashed #ccc;\'>- " + item.location + " : " + item.issue + " <button type=\'button\' class=\'button button-small wtols-clean-btn\' data-type=\'" + item.action_type + "\' data-target=\'" + item.action_data + "\' style=\'color: #d63638; border-color: #d63638;\'>" + btnLabel + "</button></div>");
								});
							} else {
								logDiv.append("No suspicious database entries found.<br>");
							}
						} else {
							logDiv.append("<span style=\'color: red;\'>Error: " + response.data + "</span>");
						}
					});
				});

				$(document).on("click", ".wtols-clean-btn", function() {
					if(!confirm("' . esc_js(__('Are you sure you want to clean/delete this? Make sure you have a backup!', 'webtaru-site-options-login-security')) . '")) return;
					
					var btn = $(this);
					var type = btn.data("type");
					var target = btn.data("target");
					btn.prop("disabled", true).text("Cleaning...");
					
					$.post(ajaxurl, {
						action: "wtols_clean_issue",
						nonce: "' . esc_js(wp_create_nonce('wtols_scanner_nonce')) . '",
						issue_type: type,
						issue_data: target
					}, function(response) {
						if(response.success) {
							btn.parent().html("<span style=\'color: green;\'>&#10004; Cleaned: " + response.data + "</span>");
						} else {
							btn.prop("disabled", false).text("Failed");
							alert("Error: " + response.data);
						}
					});
				});
			});
		</script>';
		echo '</td></tr>';
		echo '</tbody></table></div>';

		/* ── Tab 5: Workflow Utilities ── */
		echo '<div class="wtols-tab-panel" data-panel="utilities"><table class="form-table" role="presentation"><tbody>';
		$this->render_section_heading(__('Admin Workflow', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Classic Editor', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_gutenberg]" value="1" ' . checked(!empty($options['disable_gutenberg']), true, false) . ' /> ';
		echo esc_html__('Disable Gutenberg block editor globally (revert to Classic Editor).', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Content Duplicator', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_duplicator]" value="1" ' . checked(!empty($options['enable_duplicator']), true, false) . ' /> ';
		echo esc_html__('Enable "Duplicate" link for Posts, Pages, and Custom Post Types.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Enable Media Replace', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_media_replace]" value="1" ' . checked(!empty($options['enable_media_replace']), true, false) . ' /> ';
		echo esc_html__('Allow administrators to replace existing media files with new ones without changing the URL.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Duplicate Navigation Menus', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_duplicate_menu]" value="1" ' . checked(!empty($options['enable_duplicate_menu']), true, false) . ' /> ';
		echo esc_html__('Add a "Duplicate" link to your navigation menus for easy cloning.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Redirect 404 to Homepage', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[redirect_404_home]" value="1" ' . checked(!empty($options['redirect_404_home']), true, false) . ' /> ';
		echo esc_html__('Automatically redirect all 404 Not Found errors to the homepage.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Open External Links in New Tab', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[open_external_links_new_tab]" value="1" ' . checked(!empty($options['open_external_links_new_tab']), true, false) . ' /> ';
		echo esc_html__('Force all external links in post content to open in a new tab with noopener/noreferrer.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Content Protection', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_content_protection]" value="1" ' . checked(!empty($options['enable_content_protection']), true, false) . ' /> ';
		echo esc_html__('Disable Right-Click, Text Selection, and Copy-Paste on your website.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('Maintenance Mode', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Maintenance', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_maintenance]" value="1" ' . checked(!empty($options['enable_maintenance']), true, false) . ' /> ';
		echo esc_html__('Block visitors with a maintenance message. Administrators can still access the site.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-maintenance-heading">' . esc_html__('Maintenance Heading', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-maintenance-heading" name="wtols[maintenance_heading]" value="' . esc_attr($options['maintenance_heading']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-maintenance-message">' . esc_html__('Maintenance Message', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><textarea id="wtols-maintenance-message" name="wtols[maintenance_message]" rows="4" class="large-text">' . esc_textarea($options['maintenance_message']) . '</textarea></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-maintenance-bypass-key">' . esc_html__('Bypass Key', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-maintenance-bypass-key" name="wtols[maintenance_bypass_key]" value="' . esc_attr($options['maintenance_bypass_key']) . '" class="regular-text" placeholder="e.g. mysecretkey" />';
		// translators: 1: bypass URL with query param wtols_bypass, 2: bypass URL with query param bypass.
		echo '<p class="description">' . sprintf(esc_html__('Optional. Visit %1$s or %2$s to bypass the maintenance page.', 'webtaru-site-options-login-security'), '<code>' . esc_html(home_url('/?wtols_bypass=YOUR_KEY')) . '</code>', '<code>' . esc_html(home_url('/?bypass=YOUR_KEY')) . '</code>') . '</p></td></tr>';


		$this->render_section_heading(__('Sitewide Comments', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Disable Comments', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_comments_sitewide]" value="1" ' . checked(!empty($options['disable_comments_sitewide']), true, false) . ' /> ';
		echo esc_html__('Disable all comments across the entire website.', 'webtaru-site-options-login-security') . '</label><br><br>';
		echo '<a href="' . esc_url(wp_nonce_url(admin_url('admin-post.php?action=wtols_delete_all_comments'), 'wtols_delete_all_comments')) . '" class="button" onclick="return confirm(\'' . esc_js(__('Are you sure you want to permanently delete all comments? This cannot be undone.', 'webtaru-site-options-login-security')) . '\');">' . esc_html__('Delete All Comments Now', 'webtaru-site-options-login-security') . '</a></td></tr>';
		echo '</tbody></table></div>';

		/* ── Tab 6: System & Backup ── */
		echo '<div class="wtols-tab-panel" data-panel="system"><table class="form-table" role="presentation"><tbody>';

		$this->render_section_heading(__('Agency Mode (White Label)', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Agency Mode', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[agency_mode]" value="1" ' . checked(!empty($options['agency_mode']), true, false) . ' /> ';
		echo esc_html__('Hide plugin branding and enable custom menu naming.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-agency-menu-name">' . esc_html__('Custom Menu Name', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-agency-menu-name" name="wtols[agency_menu_name]" value="' . esc_attr($options['agency_menu_name']) . '" class="regular-text" placeholder="' . esc_attr__('e.g. Client Settings', 'webtaru-site-options-login-security') . '" />';
		echo '<p class="description">' . esc_html__('This will replace "Dynamic Options" in the WordPress menu.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Hide Header Icon', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[agency_hide_icon]" value="1" ' . checked(!empty($options['agency_hide_icon']), true, false) . ' /> ';
		echo esc_html__('Hide the plugin icon in the settings page header.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Hide Dashboard Menus', 'webtaru-site-options-login-security') . '</th>';
		echo '<td>';
		$menus_to_hide = array(
			'edit.php?post_type=page' => __('Pages', 'webtaru-site-options-login-security'),
			'edit-comments.php' => __('Comments', 'webtaru-site-options-login-security'),
			'themes.php' => __('Appearance', 'webtaru-site-options-login-security'),
			'plugins.php' => __('Plugins', 'webtaru-site-options-login-security'),
			'tools.php' => __('Tools', 'webtaru-site-options-login-security'),
			'options-general.php' => __('Settings', 'webtaru-site-options-login-security'),
		);
		foreach ($menus_to_hide as $slug => $label) {
			echo '<label style="display:inline-block; width:120px;"><input type="checkbox" name="wtols[hidden_admin_menus][]" value="' . esc_attr($slug) . '" ' . checked(in_array($slug, $options['hidden_admin_menus'], true), true, false) . ' /> ' . esc_html($label) . '</label>';
		}
		echo '<p class="description">' . esc_html__('Hide these menus for non-administrator users to simplify their dashboard.', 'webtaru-site-options-login-security') . '</p></td></tr>';
		$this->render_section_heading(__('Performance & SEO', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Schema.org SEO', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_schema]" value="1" ' . checked(!empty($options['enable_schema']), true, false) . ' /> ';
		echo esc_html__('Output LocalBusiness JSON-LD structured data for SEO.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Auto-Alt Text', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_auto_alt]" value="1" ' . checked(!empty($options['enable_auto_alt']), true, false) . ' /> ';
		echo esc_html__('Automatically use the image title as Alt text if it is missing.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Remove Query Strings', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[remove_query_strings]" value="1" ' . checked(!empty($options['remove_query_strings']), true, false) . ' /> ';
		echo esc_html__('Remove "?ver=" query strings from static CSS/JS files to improve caching scores.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Cache Management', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[clear_cache_on_save]" value="1" ' . checked(!empty($options['clear_cache_on_save']), true, false) . ' /> ';
		echo esc_html__('Clear sitewide cache on save (supports WP Rocket, LSCache, W3TC, SG, Super Cache).', 'webtaru-site-options-login-security') . '</label><br>';
		echo '<label><input type="checkbox" name="wtols[admin_bar_clear_cache]" value="1" ' . checked(!empty($options['admin_bar_clear_cache']), true, false) . ' /> ';
		echo esc_html__('Add "Clear Cache" shortcut to admin bar.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Disable Author Archives', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[disable_author_archives]" value="1" ' . checked(!empty($options['disable_author_archives']), true, false) . ' /> ';
		echo esc_html__('Return 404 (Not Found) error when trying to load author archives.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('Heartbeat Control', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Heartbeat Control', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_heartbeat_control]" value="1" ' . checked(!empty($options['enable_heartbeat_control']), true, false) . ' onchange="document.getElementById(\'wtols-heartbeat-wrapper\').style.display=this.checked?\'block\':\'none\';" /> ';
		echo esc_html__('Optimize and reduce WordPress Heartbeat frequency to lower server load.', 'webtaru-site-options-login-security') . '</label>';
		
		$hb_display = !empty($options['enable_heartbeat_control']) ? 'block' : 'none';
		echo '<div id="wtols-heartbeat-wrapper" style="display:' . esc_attr($hb_display) . '; margin-top:10px; padding:12px; background:#f8f9fa; border:1px solid #e2e4e7; border-radius:6px;">';
		echo '<p style="margin:0 0 8px 0; font-weight:600;"><label for="wtols-heartbeat-interval">' . esc_html__('Heartbeat Interval', 'webtaru-site-options-login-security') . '</label></p>';
		echo '<select id="wtols-heartbeat-interval" name="wtols[heartbeat_interval]" style="width:100%; max-width:200px; margin-bottom:12px;">';
		echo '<option value="15" ' . selected($options['heartbeat_interval'], 15, false) . '>15 ' . esc_html__('Seconds', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="30" ' . selected($options['heartbeat_interval'], 30, false) . '>30 ' . esc_html__('Seconds', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="60" ' . selected($options['heartbeat_interval'], 60, false) . '>60 ' . esc_html__('Seconds (Default)', 'webtaru-site-options-login-security') . '</option>';
		echo '<option value="120" ' . selected($options['heartbeat_interval'], 120, false) . '>120 ' . esc_html__('Seconds', 'webtaru-site-options-login-security') . '</option>';
		echo '</select>';
		
		echo '<p style="margin:0 0 8px 0; font-weight:600;">' . esc_html__('Disable Heartbeat API', 'webtaru-site-options-login-security') . '</p>';
		echo '<label style="display:block; margin-bottom:5px; font-weight:normal;"><input type="checkbox" name="wtols[heartbeat_disable_frontend]" value="1" ' . checked(!empty($options['heartbeat_disable_frontend']), true, false) . ' /> ' . esc_html__('Disable on Frontend', 'webtaru-site-options-login-security') . '</label>';
		echo '<label style="display:block; margin-bottom:5px; font-weight:normal;"><input type="checkbox" name="wtols[heartbeat_disable_dashboard]" value="1" ' . checked(!empty($options['heartbeat_disable_dashboard']), true, false) . ' /> ' . esc_html__('Disable on Dashboard', 'webtaru-site-options-login-security') . '</label>';
		echo '<label style="display:block; margin-bottom:5px; font-weight:normal;"><input type="checkbox" name="wtols[heartbeat_disable_editor]" value="1" ' . checked(!empty($options['heartbeat_disable_editor']), true, false) . ' /> ' . esc_html__('Disable on Post/Page Editor', 'webtaru-site-options-login-security') . '</label>';
		echo '</div></td></tr>';

		$this->render_section_heading(__('Instant Page Prefetching', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable Page Prefetching', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_prefetch]" value="1" ' . checked(!empty($options['enable_prefetch']), true, false) . ' /> ';
		echo esc_html__('Prefetch internal links in the background when hovered, making page transitions feel instant.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		$this->render_section_heading(__('Admin Bar Cleanup', 'webtaru-site-options-login-security'));

		echo '<tr><th scope="row">' . esc_html__('Zen Mode', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[admin_bar_zen_mode]" value="1" ' . checked(!empty($options['admin_bar_zen_mode']), true, false) . ' /> ';
		echo esc_html__('Instantly clean up the admin bar for a distraction-free experience.', 'webtaru-site-options-login-security') . '</label></td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Hide Elements', 'webtaru-site-options-login-security') . '</th><td>';
		$captured_nodes = get_option('wtols_captured_nodes', array());
		if (empty($captured_nodes)) {
			echo '<p class="description">' . esc_html__('No elements captured yet. Please refresh any admin page first.', 'webtaru-site-options-login-security') . '</p>';
		} else {
			echo '<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; background: #f6f7f7; padding: 15px; border-radius: 6px; border: 1px solid #dcdcde;">';
			ksort($captured_nodes);
			foreach ($captured_nodes as $node_id => $title) {
				$is_hidden = in_array($node_id, $options['hidden_admin_bar_nodes'], true);
				echo '<label style="display: flex; align-items: center; gap: 8px; font-size: 13px;">';
				echo '<input type="checkbox" class="wtols-tick-checkbox" name="wtols[hidden_admin_bar_nodes][]" value="' . esc_attr($node_id) . '" ' . checked($is_hidden, true, false) . ' />';
				echo '<span>' . esc_html($title) . ' <small style="color: #a7aaad;">(' . esc_html($node_id) . ')</small></span>';
				echo '</label>';
			}
			echo '</div>';
			echo '<div style="margin-top: 10px; display: flex; align-items: center; gap: 15px;">';
			echo '<p class="description">' . esc_html__('Select elements to remove from the admin bar. Note: Some elements only appear on specific pages or for certain plugins.', 'webtaru-site-options-login-security') . '</p>';
			echo '<button type="submit" name="wtols_reset_admin_bar" class="button button-small" style="background: #f0f0f1; border-color: #dcdcde; color: #d63638;" onclick="return confirm(\'' . esc_js(__('Clear captured list and start fresh?', 'webtaru-site-options-login-security')) . '\');">' . esc_html__('Reset List', 'webtaru-site-options-login-security') . '</button>';
			echo '</div>';
		}
		echo '</td></tr>';

		$this->render_section_heading(__('Email Delivery (SMTP)', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Enable SMTP', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><label><input type="checkbox" name="wtols[enable_smtp]" value="1" ' . checked(!empty($options['enable_smtp']), true, false) . ' /> ';
		echo esc_html__('Use external SMTP service to ensure emails are delivered.', 'webtaru-site-options-login-security') . '</label></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-host">' . esc_html__('SMTP Host', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-smtp-host" name="wtols[smtp_host]" value="' . esc_attr($options['smtp_host']) . '" class="regular-text" placeholder="smtp.example.com" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-port">' . esc_html__('SMTP Port', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-smtp-port" name="wtols[smtp_port]" value="' . esc_attr($options['smtp_port']) . '" class="small-text" placeholder="587" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-secure">' . esc_html__('SMTP Security', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><select id="wtols-smtp-secure" name="wtols[smtp_secure]">';
		echo '<option value="tls" ' . selected($options['smtp_secure'], 'tls', false) . '>TLS</option>';
		echo '<option value="ssl" ' . selected($options['smtp_secure'], 'ssl', false) . '>SSL</option>';
		echo '<option value="none" ' . selected($options['smtp_secure'], 'none', false) . '>None</option>';
		echo '</select></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-user">' . esc_html__('SMTP Username', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-smtp-user" name="wtols[smtp_user]" value="' . esc_attr($options['smtp_user']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-pass">' . esc_html__('SMTP Password', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="password" id="wtols-smtp-pass" name="wtols[smtp_pass]" value="' . esc_attr($options['smtp_pass']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-from-name">' . esc_html__('From Name', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="text" id="wtols-smtp-from-name" name="wtols[smtp_from_name]" value="' . esc_attr($options['smtp_from_name']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row"><label for="wtols-smtp-from-email">' . esc_html__('From Email', 'webtaru-site-options-login-security') . '</label></th>';
		echo '<td><input type="email" id="wtols-smtp-from-email" name="wtols[smtp_from_email]" value="' . esc_attr($options['smtp_from_email']) . '" class="regular-text" /></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Test Email', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><input type="email" id="wtols-test-email-address" class="regular-text" placeholder="Send to email..." /> <button type="button" class="button" id="wtols-send-test-email">' . esc_html__('Send Test', 'webtaru-site-options-login-security') . '</button><span id="wtols-test-email-result" style="margin-left: 10px;"></span></td></tr>';

		$this->render_section_heading(__('Safe Database Cleanup', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Optimization', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><a href="' . esc_url(wp_nonce_url(admin_url('admin-post.php?action=wtols_db_cleanup'), 'wtols_db_cleanup')) . '" class="button" onclick="return confirm(\'' . esc_js(__('This will delete all post revisions, auto-drafts, and expired transients. Proceed?', 'webtaru-site-options-login-security')) . '\');">' . esc_html__('Run Clean Up Now', 'webtaru-site-options-login-security') . '</a>';
		echo '<p class="description">' . esc_html__('Helps reduce database size and improve performance.', 'webtaru-site-options-login-security') . '</p></td></tr>';


		$this->render_section_heading(__('Import & Export Settings', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Export', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><a href="' . esc_url(wp_nonce_url(admin_url('admin-post.php?action=wtols_export_settings'), 'wtols_export_settings')) . '" class="button button-secondary">' . esc_html__('Download Configuration (JSON)', 'webtaru-site-options-login-security') . '</a></td></tr>';
		echo '<tr><th scope="row">' . esc_html__('Import', 'webtaru-site-options-login-security') . '</th>';
		echo '<td>';
		echo '<input type="file" id="wtols-import-file" name="wtols_import_file" accept=".json" style="display:none;" onchange="if(this.files.length) { document.getElementById(\'wtols-import-submit\').style.display = \'inline-block\'; }" />';
		echo '<button type="button" class="button" onclick="document.getElementById(\'wtols-import-file\').click();">' . esc_html__('Choose JSON File', 'webtaru-site-options-login-security') . '</button> ';
		echo '<button type="submit" id="wtols-import-submit" name="wtols_import_settings_submit" class="button button-primary" style="display:none;" formaction="' . esc_url(wp_nonce_url(admin_url('admin-post.php?action=wtols_import_settings'), 'wtols_import_settings')) . '" formenctype="multipart/form-data">' . esc_html__('Import Now', 'webtaru-site-options-login-security') . '</button>';
		echo '</td></tr>';

		$this->render_section_heading(__('Danger Zone', 'webtaru-site-options-login-security'));
		echo '<tr><th scope="row">' . esc_html__('Uninstall Policy', 'webtaru-site-options-login-security') . '</th>';
		echo '<td>';
		echo '<label style="color: #d63638; font-weight: 600;"><input type="checkbox" name="wtols[delete_data_on_uninstall]" value="1" ' . checked(!empty($options['delete_data_on_uninstall']), true, false) . ' /> ';
		echo esc_html__('Delete all settings and logs on uninstall?', 'webtaru-site-options-login-security') . '</label>';
		echo '<p class="description">' . esc_html__('If checked, deleting the plugin will permanently remove all configuration from the database.', 'webtaru-site-options-login-security') . '</p>';
		echo '</td></tr>';

		echo '<tr><th scope="row">' . esc_html__('Reset All Settings', 'webtaru-site-options-login-security') . '</th>';
		echo '<td>';
		echo '<a href="' . esc_url(wp_nonce_url(admin_url('admin-post.php?action=wtols_reset_settings'), 'wtols_reset_settings')) . '" class="button wtols-button-danger" onclick="return confirm(\'' . esc_js(__('WARNING: Are you sure you want to delete all settings and return to default? This action cannot be undone.', 'webtaru-site-options-login-security')) . '\');">' . esc_html__('Reset to Factory Defaults', 'webtaru-site-options-login-security') . '</a>';
		echo '<p class="description">' . esc_html__('This will wipe all contact details, social links, and security settings.', 'webtaru-site-options-login-security') . '</p>';
		echo '</td></tr>';

		echo '</tbody></table></div>';

		/* ── Tab 8: Shortcodes ── */
		echo '<div class="wtols-tab-panel" data-panel="shortcodes">';
		echo '<h2>' . esc_html__('Integration Shortcodes', 'webtaru-site-options-login-security') . '</h2>';
		echo '<p>' . esc_html__('Click any shortcode to copy it. Use in editor, Elementor, WPBakery, or do_shortcode().', 'webtaru-site-options-login-security') . '</p>';
		echo '<table class="form-table" role="presentation"><tbody>';

		$shortcodes = array(
			'[wtols_phone]' => __('Primary Phone', 'webtaru-site-options-login-security'),
			'[wtols_phone number="2"]' => __('Secondary Phone', 'webtaru-site-options-login-security'),
			'[wtols_email]' => __('Primary Email', 'webtaru-site-options-login-security'),
			'[wtols_email number="2"]' => __('Secondary Email', 'webtaru-site-options-login-security'),
			'[wtols_fax]' => __('Fax Number', 'webtaru-site-options-login-security'),
			'[wtols_address]' => __('Physical Address', 'webtaru-site-options-login-security'),
			'[wtols_logo type="light"]' => __('Light Logo', 'webtaru-site-options-login-security'),
			'[wtols_logo type="dark"]' => __('Dark Logo', 'webtaru-site-options-login-security'),
			'[wtols_map]' => __('Google Map', 'webtaru-site-options-login-security'),
			'[wtols_social_links]' => __('Social Icons List', 'webtaru-site-options-login-security'),
			'[wtols_contact_card]' => __('Full Contact Card', 'webtaru-site-options-login-security'),
			'[wtols_hours]' => __('Business Hours Table', 'webtaru-site-options-login-security'),
			'[wtols_hours format="status"]' => __('Open/Closed Status', 'webtaru-site-options-login-security'),
			'[wtols_copyright]' => __('Copyright Year (© 2026)', 'webtaru-site-options-login-security'),
		);

		foreach ($shortcodes as $code => $desc) {
			echo '<tr><th scope="row">' . esc_html($desc) . '</th>';
			echo '<td><ul class="wtols-shortcode-list"><li><code>' . esc_html($code) . '</code></li></ul></td></tr>';
		}

		echo '<tr><th scope="row">' . esc_html__('PHP Example', 'webtaru-site-options-login-security') . '</th>';
		echo '<td><code>&lt;?php echo do_shortcode(\'[wtols_contact_card]\'); ?&gt;</code></td></tr>';

		echo '</tbody></table></div>';

		echo '<p class="submit"><button type="submit" name="wtols_settings_submit" class="button button-primary">' . esc_html__('Save Settings', 'webtaru-site-options-login-security') . '</button>';
		if ($compact) {
			echo ' <a class="button" href="' . esc_url(admin_url('admin.php?page=wtols-settings')) . '">' . esc_html__('Open Full Settings', 'webtaru-site-options-login-security') . '</a>';
		}
		echo '</p></form>';
	}

	private function render_text_row($id, $name, $label, $value, $autocomplete = 'off', $type = 'text')
	{
		echo '<tr><th scope="row"><label for="' . esc_attr($id) . '">' . esc_html($label) . '</label></th>';
		echo '<td><input type="' . esc_attr($type) . '" id="' . esc_attr($id) . '" name="' . esc_attr($name) . '" value="' . esc_attr($value) . '" class="regular-text" autocomplete="' . esc_attr($autocomplete) . '" /></td></tr>';
	}

	private function render_section_heading($title)
	{
		?>
				<tr class="wtols-section-row">
					<th colspan="2">
						<h2>
							<?php echo esc_html($title); ?>
							<span class="dashicons dashicons-arrow-down-alt2 wtols-accordion-toggle"></span>
						</h2>
					</th>
				</tr>
				<?php
	}

	private function render_logo_field($type, $label, $options)
	{
		$field_key = 'logo_' . $type . '_id';
		$preview_id = 'wtols-logo-preview-' . $type;
		$field_id = 'wtols-logo-' . $type . '-id';
		$logo_preview = '';

		if (!empty($options[$field_key])) {
			$logo_preview = wp_get_attachment_image(absint($options[$field_key]), 'medium', false, array('class' => 'wtols-logo-preview-image'));
		}
		?>
				<tr>
					<th scope="row"><label for="<?php echo esc_attr($field_id); ?>"><?php echo esc_html($label); ?></label></th>
					<td>
						<input type="hidden" id="<?php echo esc_attr($field_id); ?>" name="wtols[<?php echo esc_attr($field_key); ?>]" value="<?php echo esc_attr(absint($options[$field_key])); ?>" />
						<div id="<?php echo esc_attr($preview_id); ?>" class="wtols-logo-preview"><?php echo $logo_preview ? wp_kses_post($logo_preview) : esc_html__('No logo selected.', 'webtaru-site-options-login-security'); ?></div>
						<p>
							<button type="button" class="button wtols-upload-logo" data-target="<?php echo esc_attr($field_id); ?>" data-preview="<?php echo esc_attr($preview_id); ?>"><?php esc_html_e('Choose Logo', 'webtaru-site-options-login-security'); ?></button>
							<button type="button" class="button wtols-remove-logo" data-target="<?php echo esc_attr($field_id); ?>" data-preview="<?php echo esc_attr($preview_id); ?>"><?php esc_html_e('Remove', 'webtaru-site-options-login-security'); ?></button>
						</p>
					</td>
				</tr>
				<?php
	}

	private function render_image_field($field_key, $label, $options)
	{
		$preview_id = 'wtols-preview-' . sanitize_html_class($field_key);
		$field_id = 'wtols-' . sanitize_html_class(str_replace('_', '-', $field_key));
		$image_preview = '';

		if (!empty($options[$field_key])) {
			$image_preview = wp_get_attachment_image(absint($options[$field_key]), 'medium', false, array('class' => 'wtols-logo-preview-image'));
		}
		?>
				<tr>
					<th scope="row"><label for="<?php echo esc_attr($field_id); ?>"><?php echo esc_html($label); ?></label></th>
					<td>
						<input type="hidden" id="<?php echo esc_attr($field_id); ?>" name="wtols[<?php echo esc_attr($field_key); ?>]" value="<?php echo esc_attr(absint($options[$field_key])); ?>" />
						<div id="<?php echo esc_attr($preview_id); ?>" class="wtols-logo-preview"><?php echo $image_preview ? wp_kses_post($image_preview) : esc_html__('No image selected.', 'webtaru-site-options-login-security'); ?></div>
						<p>
							<button type="button" class="button wtols-upload-logo" data-target="<?php echo esc_attr($field_id); ?>" data-preview="<?php echo esc_attr($preview_id); ?>"><?php esc_html_e('Choose Image', 'webtaru-site-options-login-security'); ?></button>
							<button type="button" class="button wtols-remove-logo" data-target="<?php echo esc_attr($field_id); ?>" data-preview="<?php echo esc_attr($preview_id); ?>"><?php esc_html_e('Remove', 'webtaru-site-options-login-security'); ?></button>
						</p>
					</td>
				</tr>
				<?php
	}

	private function render_social_fields($options)
	{
		$social_links = isset($options['social_links']) && is_array($options['social_links']) ? $options['social_links'] : self::get_default_social_links();
		?>
				<div class="wtols-social-admin">
					<?php foreach (self::get_default_social_links() as $key => $default): ?>
							<?php $item = isset($social_links[$key]) && is_array($social_links[$key]) ? wp_parse_args($social_links[$key], $default) : $default; ?>
							<div class="wtols-social-row">
								<strong><?php echo esc_html($default['label']); ?></strong>
								<input type="text" name="wtols[social_links][<?php echo esc_attr($key); ?>][url]" value="<?php echo esc_attr($item['url']); ?>" placeholder="<?php esc_attr_e('Profile URL or #', 'webtaru-site-options-login-security'); ?>" />
								<input type="text" name="wtols[social_links][<?php echo esc_attr($key); ?>][icon]" value="<?php echo esc_attr($item['icon']); ?>" placeholder="<?php echo esc_attr($default['icon']); ?>" />
							</div>
					<?php endforeach; ?>
					<p class="description"><?php esc_html_e('Icon fields accept Font Awesome classes, for example: fab fa-instagram.', 'webtaru-site-options-login-security'); ?></p>
				</div>
				<?php
	}

	public function register_shortcodes()
	{
		add_shortcode('wtols_field', array($this, 'shortcode_field'));
		add_shortcode('wtols_phone', array($this, 'shortcode_phone'));
		add_shortcode('wtols_phone_1', array($this, 'shortcode_phone'));
		add_shortcode('wtols_phone_2', array($this, 'shortcode_phone_2'));
		add_shortcode('wtols_email', array($this, 'shortcode_email'));
		add_shortcode('wtols_email_1', array($this, 'shortcode_email'));
		add_shortcode('wtols_email_2', array($this, 'shortcode_email_2'));
		add_shortcode('wtols_fax', array($this, 'shortcode_fax'));
		add_shortcode('wtols_address', array($this, 'shortcode_address'));
		add_shortcode('wtols_logo', array($this, 'shortcode_logo'));
		add_shortcode('wtols_logo_light', array($this, 'shortcode_logo_light'));
		add_shortcode('wtols_logo_dark', array($this, 'shortcode_logo_dark'));
		add_shortcode('wtols_map', array($this, 'shortcode_map'));
		add_shortcode('wtols_social_links', array($this, 'shortcode_social_links'));
		add_shortcode('wtols_contact_card', array($this, 'shortcode_contact_card'));
		add_shortcode('wtols_hours', array($this, 'shortcode_hours'));
	}

	public function shortcode_field($atts)
	{
		$atts = shortcode_atts(
			array(
				'key' => 'phone',
				'link' => 'no',
				'class' => '',
			),
			$atts,
			'wtols_field'
		);

		$key = sanitize_key($atts['key']);
		$class = $this->sanitize_class_list($atts['class']);

		if (in_array($key, array('logo', 'logo_light'), true)) {
			return $this->shortcode_logo(array('type' => 'light', 'class' => $class));
		}

		if ('logo_dark' === $key) {
			return $this->shortcode_logo(array('type' => 'dark', 'class' => $class));
		}

		if ('map' === $key) {
			return $this->shortcode_map(array('class' => $class));
		}

		if (in_array($key, array('social', 'social_links'), true)) {
			return $this->shortcode_social_links(array('class' => $class));
		}

		return $this->render_field($key, 'yes' === strtolower($atts['link']), $class);
	}

	public function shortcode_phone($atts)
	{
		$atts = shortcode_atts(array('number' => '1', 'link' => 'yes', 'class' => ''), $atts, 'wtols_phone');
		$field = '2' === (string) $atts['number'] ? 'phone_2' : 'phone';

		return $this->render_field($field, 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_phone_2($atts)
	{
		$atts = shortcode_atts(array('link' => 'yes', 'class' => ''), $atts, 'wtols_phone_2');
		return $this->render_field('phone_2', 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_email($atts)
	{
		$atts = shortcode_atts(array('number' => '1', 'link' => 'yes', 'class' => ''), $atts, 'wtols_email');
		$field = '2' === (string) $atts['number'] ? 'email_2' : 'email';

		return $this->render_field($field, 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_email_2($atts)
	{
		$atts = shortcode_atts(array('link' => 'yes', 'class' => ''), $atts, 'wtols_email_2');
		return $this->render_field('email_2', 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_fax($atts)
	{
		$atts = shortcode_atts(array('link' => 'no', 'class' => ''), $atts, 'wtols_fax');
		return $this->render_field('fax', 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_address($atts)
	{
		$atts = shortcode_atts(array('link' => 'yes', 'class' => ''), $atts, 'wtols_address');
		return $this->render_field('address', 'yes' === strtolower($atts['link']), $this->sanitize_class_list($atts['class']));
	}

	public function shortcode_logo_light($atts)
	{
		$atts = shortcode_atts(array('size' => 'full', 'class' => '', 'alt' => get_bloginfo('name')), $atts, 'wtols_logo_light');
		$atts['type'] = 'light';
		return $this->shortcode_logo($atts);
	}

	public function shortcode_logo_dark($atts)
	{
		$atts = shortcode_atts(array('size' => 'full', 'class' => '', 'alt' => get_bloginfo('name')), $atts, 'wtols_logo_dark');
		$atts['type'] = 'dark';
		return $this->shortcode_logo($atts);
	}

	public function shortcode_logo($atts)
	{
		$atts = shortcode_atts(
			array(
				'type' => 'light',
				'size' => 'full',
				'class' => '',
				'alt' => get_bloginfo('name'),
				'link' => 'yes',
			),
			$atts,
			'wtols_logo'
		);

		$type = 'dark' === sanitize_key($atts['type']) ? 'dark' : 'light';
		$options = self::get_options();
		$key = 'logo_' . $type . '_id';

		if (empty($options[$key])) {
			return '';
		}

		$class = trim('wtols-logo wtols-logo--' . $type . ' ' . $this->sanitize_class_list($atts['class']));

		$image = wp_get_attachment_image(
			absint($options[$key]),
			sanitize_key($atts['size']),
			false,
			array(
				'class' => $class,
				'alt' => sanitize_text_field($atts['alt']),
			)
		);

		if ('no' === strtolower($atts['link'])) {
			return $image;
		}

		return '<a class="wtols-logo-link wtols-logo-link--' . esc_attr($type) . '" href="' . esc_url(home_url('/')) . '">' . $image . '</a>';
	}

	public function shortcode_map($atts)
	{
		$atts = shortcode_atts(
			array(
				'height' => '320',
				'class' => '',
			),
			$atts,
			'wtols_map'
		);

		$options = self::get_options();
		$map = trim($options['map']);

		if ('' === $map) {
			return '';
		}

		wp_enqueue_style('wtols-frontend');

		$class = trim('wtols-map ' . $this->sanitize_class_list($atts['class']));
		$height = max(160, absint($atts['height']));

		if (false !== stripos($map, '<iframe')) {
			$map = preg_replace('/\s(width|height)=["\'][^"\']*["\']/i', '', $map);
			return '<div class="' . esc_attr($class) . '" style="height:' . esc_attr($height) . 'px">' . wp_kses($map, $this->get_allowed_iframe_html()) . '</div>';
		}

		return sprintf(
			'<div class="%1$s" style="height:%2$dpx"><iframe src="%3$s" loading="lazy" referrerpolicy="no-referrer-when-downgrade" title="%4$s"></iframe></div>',
			esc_attr($class),
			absint($height),
			esc_url($map),
			esc_attr__('Location map', 'webtaru-site-options-login-security')
		);
	}

	public function shortcode_social_links($atts)
	{
		$atts = shortcode_atts(array('class' => '', 'target' => '_blank'), $atts, 'wtols_social_links');

		$options = self::get_options();
		$links = isset($options['social_links']) && is_array($options['social_links']) ? $options['social_links'] : array();

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

		wp_enqueue_style('wtols-frontend');

		if (!empty($options['enable_fontawesome'])) {
			wp_enqueue_style('wtols-fontawesome');
		}

		$class = trim('wtols-social-links ' . $this->sanitize_class_list($atts['class']));
		$target = '_self' === $atts['target'] ? '_self' : '_blank';
		$output = '';

		foreach (self::get_default_social_links() as $key => $default) {
			$item = isset($links[$key]) && is_array($links[$key]) ? wp_parse_args($links[$key], $default) : $default;

			if (empty($item['url'])) {
				continue;
			}

			$icon = $this->sanitize_class_list($item['icon']);
			$item_target = $this->is_hash_url($item['url']) ? '_self' : $target;
			$rel = '_blank' === $item_target ? ' rel="noopener noreferrer"' : '';

			$output .= sprintf(
				'<a href="%1$s" target="%2$s"%3$s aria-label="%4$s"><i class="%5$s" aria-hidden="true"></i></a>',
				$this->esc_safe_url($item['url']),
				esc_attr($item_target),
				$rel,
				esc_attr($item['label']),
				esc_attr($icon)
			);
		}

		/* Custom social links */
		$custom = isset($options['custom_social_links']) && is_array($options['custom_social_links']) ? $options['custom_social_links'] : array();
		foreach ($custom as $citem) {
			if (empty($citem['url']) || empty($citem['label'])) {
				continue;
			}
			$icon = !empty($citem['icon']) ? $this->sanitize_class_list($citem['icon']) : 'fas fa-globe';
			$item_target = $this->is_hash_url($citem['url']) ? '_self' : $target;
			$rel = '_blank' === $item_target ? ' rel="noopener noreferrer"' : '';
			$output .= sprintf(
				'<a href="%1$s" target="%2$s"%3$s aria-label="%4$s"><i class="%5$s" aria-hidden="true"></i></a>',
				$this->esc_safe_url($citem['url']),
				esc_attr($item_target),
				$rel,
				esc_attr(sanitize_text_field($citem['label'])),
				esc_attr($icon)
			);
		}

		return '' === $output ? '' : '<div class="' . esc_attr($class) . '">' . $output . '</div>';
	}

	public function shortcode_contact_card($atts)
	{
		$atts = shortcode_atts(array('class' => ''), $atts, 'wtols_contact_card');

		wp_enqueue_style('wtols-frontend');

		$options = self::get_options();
		$style_class = isset($options['layout_style']) && 'pill' === $options['layout_style'] ? 'wtols-style-pill' : '';

		$class = trim('wtols-contact-card ' . $style_class . ' ' . $this->sanitize_class_list($atts['class']));

		ob_start();
		?>
				<div class="<?php echo esc_attr($class); ?>">
					<?php echo wp_kses_post($this->shortcode_logo(array('type' => 'light', 'size' => 'medium'))); ?>
					<?php echo wp_kses_post($this->render_field('phone', true, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->render_field('phone_2', true, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->render_field('email', true, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->render_field('email_2', true, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->render_field('fax', false, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->render_field('address', true, 'wtols-contact-card__item')); ?>
					<?php echo wp_kses_post($this->shortcode_social_links(array())); ?>
				</div>
				<?php
				return ob_get_clean();
	}

	private function render_field($key, $link = false, $class = '')
	{
		$key = 'phone_1' === $key ? 'phone' : $key;
		$key = 'email_1' === $key ? 'email' : $key;

		if (!in_array($key, $this->field_keys, true)) {
			return '';
		}

		$options = self::get_options();
		$value = isset($options[$key]) ? trim((string) $options[$key]) : '';

		if ('' === $value) {
			return '';
		}

		$class_attr = '' !== $class ? ' class="' . esc_attr($class) . '"' : '';

		$icon_html = '';
		if (!empty($options['show_contact_icons']) && !empty($options['icon_' . $key])) {
			wp_enqueue_style('wtols-fontawesome');
			$icon_class = $this->sanitize_class_list($options['icon_' . $key]);
			$icon_html = '<i class="' . esc_attr($icon_class) . '" aria-hidden="true"></i>';
		}

		$placement = isset($options['icon_placement']) && 'after' === $options['icon_placement'] ? 'after' : 'before';

		if ('address' === $key) {
			$address = nl2br(esc_html($value));
			$inner_content = 'before' === $placement && $icon_html ? $icon_html . ' ' . $address : ('after' === $placement && $icon_html ? $address . ' ' . $icon_html : $address);
			$url = isset($options['address_link']) ? trim((string) $options['address_link']) : '';

			if ($link && '' !== $url) {
				$target = $this->is_hash_url($url) ? '_self' : '_blank';
				$rel = '_blank' === $target ? ' rel="noopener noreferrer"' : '';

				return '<a' . $class_attr . ' href="' . $this->esc_safe_url($url) . '" target="' . esc_attr($target) . '"' . $rel . '>' . $inner_content . '</a>';
			}

			return '<span' . $class_attr . '>' . $inner_content . '</span>';
		}

		$display_val = in_array($key, array('email', 'email_2'), true) ? esc_html(antispambot($value)) : esc_html($value);
		$inner_content = 'before' === $placement && $icon_html ? $icon_html . ' ' . $display_val : ('after' === $placement && $icon_html ? $display_val . ' ' . $icon_html : $display_val);

		if ($link && in_array($key, array('phone', 'phone_2', 'fax'), true)) {
			$href = preg_replace('/[^0-9+]/', '', $value);
			return '<a' . $class_attr . ' href="tel:' . esc_attr($href) . '">' . $inner_content . '</a>';
		}

		if ($link && in_array($key, array('email', 'email_2'), true)) {
			return '<a' . $class_attr . ' href="mailto:' . esc_attr(antispambot($value)) . '">' . $inner_content . '</a>';
		}

		return '<span' . $class_attr . '>' . $inner_content . '</span>';
	}

	private function sanitize_class_list($class_list)
	{
		$classes = preg_split('/\s+/', (string) $class_list);
		$classes = array_filter(array_map('sanitize_html_class', $classes));

		return implode(' ', $classes);
	}

	private function get_allowed_iframe_html()
	{
		return array(
			'iframe' => array(
				'src' => true,
				'width' => true,
				'height' => true,
				'style' => true,
				'allowfullscreen' => true,
				'loading' => true,
				'referrerpolicy' => true,
				'title' => true,
			),
		);
	}

	public function register_wpbakery_element()
	{
		if (!function_exists('vc_map')) {
			return;
		}

		vc_map(
			array(
				'name' => __('Dynamic Options Field', 'webtaru-site-options-login-security'),
				'base' => 'wtols_field',
				'category' => __('Content', 'webtaru-site-options-login-security'),
				'description' => __('Show dynamic phone, email, fax, address, logo, map, or social links.', 'webtaru-site-options-login-security'),
				'params' => array(
					array(
						'type' => 'dropdown',
						'heading' => __('Field', 'webtaru-site-options-login-security'),
						'param_name' => 'key',
						'value' => array(
							__('Phone 1', 'webtaru-site-options-login-security') => 'phone',
							__('Phone 2', 'webtaru-site-options-login-security') => 'phone_2',
							__('Email 1', 'webtaru-site-options-login-security') => 'email',
							__('Email 2', 'webtaru-site-options-login-security') => 'email_2',
							__('Fax', 'webtaru-site-options-login-security') => 'fax',
							__('Address', 'webtaru-site-options-login-security') => 'address',
							__('Light Logo', 'webtaru-site-options-login-security') => 'logo_light',
							__('Dark Logo', 'webtaru-site-options-login-security') => 'logo_dark',
							__('Map', 'webtaru-site-options-login-security') => 'map',
							__('Social Links', 'webtaru-site-options-login-security') => 'social_links',
						),
						'std' => 'phone',
					),
					array(
						'type' => 'checkbox',
						'heading' => __('Make clickable', 'webtaru-site-options-login-security'),
						'param_name' => 'link',
						'value' => array(__('Yes', 'webtaru-site-options-login-security') => 'yes'),
					),
					array(
						'type' => 'textfield',
						'heading' => __('CSS Class', 'webtaru-site-options-login-security'),
						'param_name' => 'class',
					),
				),
			)
		);

		vc_map(
			array(
				'name' => __('Dynamic Social Links', 'webtaru-site-options-login-security'),
				'base' => 'wtols_social_links',
				'category' => __('Content', 'webtaru-site-options-login-security'),
				'description' => __('Show configured social media links with Font Awesome icons.', 'webtaru-site-options-login-security'),
				'params' => array(
					array(
						'type' => 'textfield',
						'heading' => __('CSS Class', 'webtaru-site-options-login-security'),
						'param_name' => 'class',
					),
				),
			)
		);
	}

	public function register_elementor_widgets($widgets_manager)
	{
		if (!did_action('elementor/loaded') || !class_exists('\Elementor\Widget_Base')) {
			return;
		}

		require_once WTOLS_PLUGIN_DIR . 'includes/class-wtols-elementor-widget.php';
		$widgets_manager->register(new WTOLS_Elementor_Widget());
	}

	/* ──────────────────────────────────────────────
	 * v2.0 — Custom Social Links admin fields
	 * ────────────────────────────────────────────── */

	private function render_custom_social_fields($options)
	{
		$custom = isset($options['custom_social_links']) && is_array($options['custom_social_links']) ? $options['custom_social_links'] : array();
		echo '<div class="wtols-social-admin"><div class="wtols-custom-social-list">';
		foreach ($custom as $i => $item) {
			$item = wp_parse_args($item, array('label' => '', 'url' => '', 'icon' => ''));
			echo '<div class="wtols-custom-social-row wtols-social-row">';
			echo '<input type="text" name="wtols[custom_social_links][' . (int) $i . '][label]" value="' . esc_attr($item['label']) . '" placeholder="' . esc_attr__('Label', 'webtaru-site-options-login-security') . '" />';
			echo '<input type="text" name="wtols[custom_social_links][' . (int) $i . '][url]" value="' . esc_attr($item['url']) . '" placeholder="' . esc_attr__('Profile URL or #', 'webtaru-site-options-login-security') . '" />';
			echo '<input type="text" name="wtols[custom_social_links][' . (int) $i . '][icon]" value="' . esc_attr($item['icon']) . '" placeholder="fab fa-globe" />';
			echo '<button type="button" class="button wtols-remove-custom-social">&times;</button>';
			echo '</div>';
		}
		echo '</div>';
		echo '<button type="button" class="button wtols-add-custom-social">' . esc_html__('+ Add Custom Link', 'webtaru-site-options-login-security') . '</button>';
		echo '<p class="description">' . esc_html__('Add any platform — TikTok, Telegram, GitHub, etc. Use Font Awesome icon classes.', 'webtaru-site-options-login-security') . '</p>';
		echo '</div>';
	}

	private function sanitize_custom_social_links($raw)
	{
		$clean = array();
		if (!is_array($raw)) {
			return $clean;
		}
		foreach ($raw as $item) {
			if (!is_array($item)) {
				continue;
			}
			$label = isset($item['label']) ? sanitize_text_field($item['label']) : '';
			$url = isset($item['url']) ? $this->sanitize_safe_url($item['url']) : '';
			$icon = isset($item['icon']) ? $this->sanitize_class_list($item['icon']) : '';
			if ('' !== $label && '' !== $url) {
				$clean[] = array('label' => $label, 'url' => $url, 'icon' => $icon);
			}
		}
		return $clean;
	}

	/* ──────────────────────────────────────────────
	 * v2.0 — Business Hours
	 * ────────────────────────────────────────────── */

	private function render_business_hours_fields($options)
	{
		$hours = isset($options['business_hours']) && is_array($options['business_hours']) ? $options['business_hours'] : self::get_default_business_hours();
		$day_labels = array(
			'monday' => __('Monday', 'webtaru-site-options-login-security'),
			'tuesday' => __('Tuesday', 'webtaru-site-options-login-security'),
			'wednesday' => __('Wednesday', 'webtaru-site-options-login-security'),
			'thursday' => __('Thursday', 'webtaru-site-options-login-security'),
			'friday' => __('Friday', 'webtaru-site-options-login-security'),
			'saturday' => __('Saturday', 'webtaru-site-options-login-security'),
			'sunday' => __('Sunday', 'webtaru-site-options-login-security'),
		);
		echo '<div class="wtols-hours-grid">';
		foreach ($day_labels as $key => $label) {
			$day = isset($hours[$key]) ? wp_parse_args($hours[$key], array('enabled' => 0, 'open' => '09:00', 'close' => '18:00')) : array('enabled' => 0, 'open' => '09:00', 'close' => '18:00');
			echo '<div class="wtols-hours-day-row">';
			echo '<input type="checkbox" class="wtols-hours-enabled" name="wtols[business_hours][' . esc_attr($key) . '][enabled]" value="1" ' . checked(!empty($day['enabled']), true, false) . ' />';
			echo '<span class="wtols-hours-day-label">' . esc_html($label) . '</span>';
			echo '<input type="time" class="wtols-hours-time" name="wtols[business_hours][' . esc_attr($key) . '][open]" value="' . esc_attr($day['open']) . '" />';
			echo '<span class="wtols-hours-separator">—</span>';
			echo '<input type="time" class="wtols-hours-time" name="wtols[business_hours][' . esc_attr($key) . '][close]" value="' . esc_attr($day['close']) . '" />';
			echo '</div>';
		}
		echo '</div>';
	}

	private function sanitize_business_hours($raw)
	{
		$days = array_keys(self::get_default_business_hours());
		$clean = array();
		foreach ($days as $day) {
			$item = isset($raw[$day]) && is_array($raw[$day]) ? $raw[$day] : array();
			$clean[$day] = array(
				'enabled' => !empty($item['enabled']) ? 1 : 0,
				'open' => isset($item['open']) ? sanitize_text_field($item['open']) : '09:00',
				'close' => isset($item['close']) ? sanitize_text_field($item['close']) : '18:00',
			);
		}
		return $clean;
	}

	public function shortcode_hours($atts)
	{
		$atts = shortcode_atts(array('format' => 'full', 'class' => ''), $atts, 'wtols_hours');
		$options = self::get_options();

		wp_enqueue_style('wtols-frontend');

		$class = trim('wtols-hours ' . $this->sanitize_class_list($atts['class']));

		/* Status badge */
		if ('status' === $atts['format']) {
			$is_open = $this->is_currently_open($options);
			$label = $is_open ? __('Currently Open', 'webtaru-site-options-login-security') : __('Currently Closed', 'webtaru-site-options-login-security');
			$status = $is_open ? 'open' : 'closed';
			return '<span class="wtols-hours-status wtols-hours-status--' . esc_attr($status) . '">' . esc_html($label) . '</span>';
		}

		/* Freeform text takes priority */
		$freeform = isset($options['business_hours_freeform']) ? trim($options['business_hours_freeform']) : '';
		if ('' !== $freeform) {
			return '<div class="' . esc_attr($class) . '">' . nl2br(esc_html($freeform)) . '</div>';
		}

		/* Structured table */
		$hours = isset($options['business_hours']) && is_array($options['business_hours']) ? $options['business_hours'] : self::get_default_business_hours();
		$day_labels = array(
			'monday' => __('Mon', 'webtaru-site-options-login-security'),
			'tuesday' => __('Tue', 'webtaru-site-options-login-security'),
			'wednesday' => __('Wed', 'webtaru-site-options-login-security'),
			'thursday' => __('Thu', 'webtaru-site-options-login-security'),
			'friday' => __('Fri', 'webtaru-site-options-login-security'),
			'saturday' => __('Sat', 'webtaru-site-options-login-security'),
			'sunday' => __('Sun', 'webtaru-site-options-login-security'),
		);

		$output = '<table class="wtols-hours-table">';
		foreach ($day_labels as $key => $label) {
			$day = isset($hours[$key]) ? $hours[$key] : array('enabled' => 0);
			$output .= '<tr><td class="wtols-hours-day">' . esc_html($label) . '</td>';
			if (!empty($day['enabled'])) {
				$output .= '<td>' . esc_html($day['open']) . ' — ' . esc_html($day['close']) . '</td>';
			} else {
				$output .= '<td class="wtols-hours-closed">' . esc_html__('Closed', 'webtaru-site-options-login-security') . '</td>';
			}
			$output .= '</tr>';
		}
		$output .= '</table>';

		return '<div class="' . esc_attr($class) . '">' . $output . '</div>';
	}

	private function is_currently_open($options)
	{
		$hours = isset($options['business_hours']) && is_array($options['business_hours']) ? $options['business_hours'] : array();
		$today = strtolower(wp_date('l'));
		if (!isset($hours[$today]) || empty($hours[$today]['enabled'])) {
			return false;
		}
		$now = wp_date('H:i');
		$open = $hours[$today]['open'];
		$close = $hours[$today]['close'];
		return ($now >= $open && $now <= $close);
	}

	/* ──────────────────────────────────────────────
	 * v2.0 — Locked IPs Table
	 * ────────────────────────────────────────────── */

	private function render_locked_ips_table()
	{
		$locked = $this->get_all_locked_ips();
		if (empty($locked)) {
			echo '<p class="wtols-no-lockouts">' . esc_html__('No IPs are currently locked out.', 'webtaru-site-options-login-security') . '</p>';
			return;
		}
		
		echo '<div style="margin-bottom: 10px;">';
		echo '<button type="button" class="button wtols-clear-locked-ips" style="color: #b32d2e; border-color: #b32d2e;">' . esc_html__('Clear List', 'webtaru-site-options-login-security') . '</button>';
		echo '</div>';

		echo '<table class="wtols-locked-ips-table widefat fixed striped" id="wtols-locked-ips-table"><thead><tr><th style="width: 70%;">' . esc_html__('IP Address', 'webtaru-site-options-login-security') . '</th><th style="width: 30%;">' . esc_html__('Action', 'webtaru-site-options-login-security') . '</th></tr></thead><tbody id="wtols-locked-ips-body">';
		foreach ($locked as $ip) {
			$ip_link = 'https://ipinfo.io/' . urlencode($ip);
			echo '<tr>';
			echo '<td style="word-break: break-all;"><a href="' . esc_url($ip_link) . '" target="_blank" rel="noopener noreferrer" title="View IP Location">' . esc_html($ip) . '</a></td>';
			echo '<td><button type="button" class="button wtols-unlock-ip" data-ip="' . esc_attr($ip) . '">' . esc_html__('Unlock', 'webtaru-site-options-login-security') . '</button></td>';
			echo '</tr>';
		}
		echo '</tbody></table>';
		
		if (count($locked) > 20) {
			echo '<div id="wtols-locked-ips-pagination" style="margin-top: 10px; display: flex; gap: 5px; align-items: center;"></div>';
		}
	}

	private function get_all_locked_ips()
	{
		$options = self::get_options();
		$locked_ips_data = isset($options['locked_ips']) && is_array($options['locked_ips']) ? $options['locked_ips'] : array();
		
		$valid_ips = array();
		$changed = false;
		$current_time = time();

		foreach ($locked_ips_data as $ip => $data) {
			$hash = $this->get_ip_hash($ip);
			// Verify if the transient still exists or hasn't expired
			$transient_value = get_transient(self::LIMITER_LOCKOUT_PREFIX . $hash);
			
			if (false !== $transient_value) {
				$valid_ips[] = $ip;
			} else {
				// Also check our own expiration as a fallback
				if (isset($data['time'], $data['duration']) && ($current_time - $data['time'] < $data['duration'])) {
					$valid_ips[] = $ip;
				} else {
					unset($locked_ips_data[$ip]);
					$changed = true;
				}
			}
		}

		if ($changed) {
			$options['locked_ips'] = $locked_ips_data;
			update_option(self::OPTION_KEY, $options);
		}

		return $valid_ips;
	}

	/* ──────────────────────────────────────────────
	 * v2.0 — Schema.org JSON-LD
	 * ────────────────────────────────────────────── */

	public function render_schema_jsonld()
	{
		if (is_admin()) {
			return;
		}
		$options = self::get_options();
		if (empty($options['enable_schema'])) {
			return;
		}
		$schema = array(
			'@context' => 'https://schema.org',
			'@type' => 'LocalBusiness',
			'name' => get_bloginfo('name'),
			'url' => home_url('/'),
		);
		if (!empty($options['phone'])) {
			$schema['telephone'] = $options['phone'];
		}
		if (!empty($options['email'])) {
			$schema['email'] = $options['email'];
		}
		if (!empty($options['fax'])) {
			$schema['faxNumber'] = $options['fax'];
		}
		if (!empty($options['address'])) {
			$schema['address'] = array('@type' => 'PostalAddress', 'streetAddress' => $options['address']);
		}
		if (!empty($options['logo_light_url'])) {
			$schema['logo'] = $options['logo_light_url'];
		}
		$same_as = array();
		$social = isset($options['social_links']) && is_array($options['social_links']) ? $options['social_links'] : array();
		foreach ($social as $link) {
			if (!empty($link['url']) && !$this->is_hash_url($link['url'])) {
				$same_as[] = $link['url'];
			}
		}
		$custom_social = isset($options['custom_social_links']) && is_array($options['custom_social_links']) ? $options['custom_social_links'] : array();
		foreach ($custom_social as $link) {
			if (!empty($link['url']) && !$this->is_hash_url($link['url'])) {
				$same_as[] = $link['url'];
			}
		}
		if (!empty($same_as)) {
			$schema['sameAs'] = $same_as;
		}
		/* Opening hours from structured data */
		$hours = isset($options['business_hours']) && is_array($options['business_hours']) ? $options['business_hours'] : array();
		$day_map = array('monday' => 'Mo', 'tuesday' => 'Tu', 'wednesday' => 'We', 'thursday' => 'Th', 'friday' => 'Fr', 'saturday' => 'Sa', 'sunday' => 'Su');
		$specs = array();
		foreach ($day_map as $day => $code) {
			if (!empty($hours[$day]['enabled'])) {
				$specs[] = array(
					'@type' => 'OpeningHoursSpecification',
					'dayOfWeek' => $code,
					'opens' => $hours[$day]['open'],
					'closes' => $hours[$day]['close'],
				);
			}
		}
		if (!empty($specs)) {
			$schema['openingHoursSpecification'] = $specs;
		}
		echo '<script type="application/ld+json">' . wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) . '</script>' . "\n";
	}

	/* ──────────────────────────────────────────────
	 * v2.0 — Login Attempt Limiter
	 * ────────────────────────────────────────────── */

	private function get_client_ip()
	{
		$ip = '';
		if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
			$ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_CF_CONNECTING_IP']));
		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			$forwarded = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
			$parts = explode(',', $forwarded);
			$ip = trim($parts[0]);
		} elseif (!empty($_SERVER['REMOTE_ADDR'])) {
			$ip = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR']));
		}
		return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '0.0.0.0';
	}

	private function get_ip_hash($ip)
	{
		return md5($ip . wp_salt('auth'));
	}

	public function track_failed_login($username)
	{
		$options = self::get_options();
		if (empty($options['limiter_enabled'])) {
			return;
		}
		$ip = $this->get_client_ip();

		// Check Whitelist
		$whitelist_raw = !empty($options['ip_whitelist']) ? $options['ip_whitelist'] : '';
		$whitelist = array_filter(array_map('trim', explode("\n", $whitelist_raw)));
		if (in_array($ip, $whitelist, true)) {
			return;
		}

		$hash = $this->get_ip_hash($ip);

		// Do not process if already locked out
		if (false !== get_transient(self::LIMITER_LOCKOUT_PREFIX . $hash)) {
			return;
		}

		$max = absint($options['limiter_max_attempts']);
		$duration = absint($options['limiter_lockout_duration']) * MINUTE_IN_SECONDS;
		$attempts = (int) get_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash);
		$attempts++;
		set_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash, $attempts, $duration);
		if ($attempts >= $max) {
			set_transient(self::LIMITER_LOCKOUT_PREFIX . $hash, $ip, $duration);
			delete_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash);

			// Save to options array for reliable display
			$locked_ips = isset($options['locked_ips']) && is_array($options['locked_ips']) ? $options['locked_ips'] : array();
			$locked_ips[$ip] = array(
				'time' => time(),
				'duration' => $duration
			);
			$options['locked_ips'] = $locked_ips;
			update_option(self::OPTION_KEY, $options);

			// Send IP Lockout Alert
			if (!empty($options['enable_ip_lockout_alerts'])) {
				$site_name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
				$site_url = home_url();
				$subject = sprintf('[%s] Security Alert: IP Address Locked Out', $site_name);
				$lockout_msg = sprintf(
					"Website: %s\n\nIP Address %s has been locked out for %d minutes after %d failed login attempts.\n\nUsername attempted: %s\nTime: %s",
					$site_url,
					$ip,
					absint($options['limiter_lockout_duration']),
					$max,
					$username,
					date_i18n(get_option('date_format') . ' ' . get_option('time_format'), current_time('timestamp'))
				);
				$this->send_security_notification($subject, $lockout_msg);
			}
		}
	}

	public function check_login_lockout($user, $username, $password)
	{
		$options = self::get_options();
		if (empty($options['limiter_enabled'])) {
			return $user;
		}
		$ip = $this->get_client_ip();

		// Check Whitelist
		$whitelist_raw = !empty($options['ip_whitelist']) ? $options['ip_whitelist'] : '';
		$whitelist = array_filter(array_map('trim', explode("\n", $whitelist_raw)));
		if (in_array($ip, $whitelist, true)) {
			return $user;
		}

		$hash = $this->get_ip_hash($ip);
		if (false !== get_transient(self::LIMITER_LOCKOUT_PREFIX . $hash)) {
			$message = !empty($options['limiter_message']) ? $options['limiter_message'] : self::get_default_options()['limiter_message'];
			return new \WP_Error('wtols_locked', esc_html($message));
		}
		return $user;
	}

	public function clear_login_attempts($user_login, $user)
	{
		$ip = $this->get_client_ip();
		$hash = $this->get_ip_hash($ip);
		delete_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash);
	}

	public function ajax_unlock_ip()
	{
		if (!current_user_can('manage_options')) {
			wp_send_json_error();
		}
		check_ajax_referer('wtols_unlock_ip', '_wpnonce');
		$ip = isset($_POST['ip']) ? sanitize_text_field(wp_unslash($_POST['ip'])) : '';
		if ('' === $ip) {
			wp_send_json_error();
		}
		$hash = $this->get_ip_hash($ip);
		delete_transient(self::LIMITER_LOCKOUT_PREFIX . $hash);
		delete_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash);
		
		$options = self::get_options();
		if (isset($options['locked_ips'][$ip])) {
			unset($options['locked_ips'][$ip]);
			update_option(self::OPTION_KEY, $options);
		}
		
		wp_send_json_success();
	}

	public function ajax_clear_security_logs()
	{
		if (!current_user_can('manage_options')) {
			wp_send_json_error();
		}
		check_ajax_referer('wtols_clear_logs', '_wpnonce');
		$options = self::get_options();
		$options['login_logs'] = array();
		update_option(self::OPTION_KEY, $options);
		wp_send_json_success();
	}

	public function ajax_export_security_logs()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('Permission denied.', 'webtaru-site-options-login-security'));
		}
		
		$nonce = isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '';
		if (!wp_verify_nonce($nonce, 'wtols_export_logs_action')) {
			wp_die(esc_html__('Security check failed.', 'webtaru-site-options-login-security'));
		}

		$options = self::get_options();
		$logs = isset($options['login_logs']) ? $options['login_logs'] : array();

		header('Content-Type: text/csv; charset=utf-8');
		header('Content-Disposition: attachment; filename=wtols-security-logs-' . gmdate('Y-m-d') . '.csv');
		header('Pragma: no-cache');
		header('Expires: 0');

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
		$output = fopen('php://output', 'w');
		fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
		
		fputcsv($output, array('IP Address', 'Username', 'Time'));

		foreach ($logs as $log) {
			fputcsv($output, array($log['ip'], $log['user'], $log['time']));
		}
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
		fclose($output);
		exit;
	}

	public function ajax_clear_locked_ips()
	{
		if (!current_user_can('manage_options')) {
			wp_send_json_error();
		}
		check_ajax_referer('wtols_clear_locked_ips', '_wpnonce');
		$options = self::get_options();
		
		// Clear transients for all currently known locked IPs
		$locked_ips = isset($options['locked_ips']) && is_array($options['locked_ips']) ? $options['locked_ips'] : array();
		foreach ($locked_ips as $ip => $data) {
			$hash = $this->get_ip_hash($ip);
			delete_transient(self::LIMITER_LOCKOUT_PREFIX . $hash);
			delete_transient(self::LIMITER_ATTEMPTS_PREFIX . $hash);
		}
		
		$options['locked_ips'] = array();
		update_option(self::OPTION_KEY, $options);
		wp_send_json_success();
	}

	/* ──────────────────────────────────────────────
	 * v3.0 — Security & Performance
	 * ────────────────────────────────────────────── */

	public function filter_xmlrpc_enabled($enabled)
	{
		$options = self::get_options();
		if (!empty($options['disable_xmlrpc'])) {
			return false;
		}
		return $enabled;
	}

	public function enqueue_captcha_scripts()
	{
		$options = self::get_options();
		if ('recaptcha_v3' === $options['captcha_type'] && !empty($options['captcha_site_key'])) {
			wp_enqueue_script('wtols-recaptcha-v3', 'https://www.google.com/recaptcha/api.js?render=' . esc_attr($options['captcha_site_key']), array(), WTOLS_VERSION, true);
			wp_add_inline_script('wtols-recaptcha-v3', '
				document.addEventListener("DOMContentLoaded", function() {
					var forms = document.querySelectorAll("#loginform, #lostpasswordform, #registerform");
					if (forms.length > 0) {
						grecaptcha.ready(function() {
							forms.forEach(function(form) {
								form.addEventListener("submit", function(e) {
									var input = form.querySelector("input[name=\'g-recaptcha-response\']");
									if (input && !input.value) {
										e.preventDefault();
										grecaptcha.execute("' . esc_js($options['captcha_site_key']) . '", {action: "login"}).then(function(token) {
											input.value = token;
											form.submit();
										});
									}
								});
							});
						});
					}
				});
			');
		} elseif ('turnstile' === $options['captcha_type'] && !empty($options['captcha_site_key'])) {
			$turnstile_url = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
			// phpcs:ignore PluginCheck.CodeAnalysis.EnqueuedResourceOffloading.OffloadedContent
			wp_enqueue_script('wtols-turnstile', $turnstile_url, array(), WTOLS_VERSION, true);
		}
	}

	public function render_captcha_field()
	{
		$options = self::get_options();
		if ('recaptcha_v3' === $options['captcha_type'] && !empty($options['captcha_site_key'])) {
			echo '<input type="hidden" name="g-recaptcha-response" value="" />';
		} elseif ('turnstile' === $options['captcha_type'] && !empty($options['captcha_site_key'])) {
			echo '<div class="cf-turnstile" data-sitekey="' . esc_attr($options['captcha_site_key']) . '" style="margin-bottom:15px;"></div>';
		}
	}

	public function verify_captcha($user, $username, $password)
	{
		// Only check on actual login submission
		if (empty($username) || is_wp_error($user)) {
			return $user;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if (!isset($_POST['wp-submit'])) {
			return $user;
		}

		$options = self::get_options();
		if ('none' === $options['captcha_type'] || empty($options['captcha_secret_key'])) {
			return $user;
		}

		$response = '';
		$url = '';
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if ('recaptcha_v3' === $options['captcha_type'] && isset($_POST['g-recaptcha-response'])) {
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
			$response = wp_unslash($_POST['g-recaptcha-response']);
			$url = 'https://www.google.com/recaptcha/api/siteverify';
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		} elseif ('turnstile' === $options['captcha_type'] && isset($_POST['cf-turnstile-response'])) {
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
			$response = wp_unslash($_POST['cf-turnstile-response']);
			$url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
		}

		if (empty($response)) {
			return new \WP_Error('wtols_captcha_missing', esc_html__('Please complete the CAPTCHA verification.', 'webtaru-site-options-login-security'));
		}

		$verify = wp_remote_post(
			$url,
			array(
				'body' => array(
					'secret' => $options['captcha_secret_key'],
					'response' => $response,
					'remoteip' => $this->get_client_ip(),
				),
			)
		);

		if (is_wp_error($verify)) {
			return new \WP_Error('wtols_captcha_error', esc_html__('Error verifying CAPTCHA. Please try again.', 'webtaru-site-options-login-security'));
		}

		$body = json_decode(wp_remote_retrieve_body($verify), true);
		if (!isset($body['success']) || !$body['success']) {
			return new \WP_Error('wtols_captcha_invalid', esc_html__('Invalid CAPTCHA response. Please try again.', 'webtaru-site-options-login-security'));
		}

		if ('recaptcha_v3' === $options['captcha_type'] && isset($body['score']) && $body['score'] < 0.5) {
			return new \WP_Error('wtols_captcha_bot', esc_html__('Failed security check.', 'webtaru-site-options-login-security'));
		}

		return $user;
	}

	public function flush_cache_on_save($option, $old_value, $value)
	{
		if (self::OPTION_KEY !== $option) {
			return;
		}

		// Always clear cache if the login slug changed to prevent redirection/access issues
		$slug_changed = isset($old_value['login_slug'], $value['login_slug']) && $old_value['login_slug'] !== $value['login_slug'];

		if (empty($value['clear_cache_on_save']) && !$slug_changed) {
			return;
		}

		$this->execute_cache_flush();
	}

	public function add_admin_bar_clear_cache($wp_admin_bar)
	{
		$options = self::get_options();
		if (empty($options['admin_bar_clear_cache'])) {
			return;
		}

		$title = !empty($options['agency_mode'])
			? __('Clear Cache', 'webtaru-site-options-login-security')
			: __('Clear Cache ', 'webtaru-site-options-login-security');

		$wp_admin_bar->add_node(
			array(
				'id' => 'wtols-clear-cache',
				'title' => $title,
				'href' => wp_nonce_url(admin_url('admin-post.php?action=wtols_clear_cache'), 'wtols_clear_cache'),
			)
		);
	}

	public function handle_clear_cache()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to clear cache.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_clear_cache');

		$this->execute_cache_flush();

		$redirect = wp_get_referer() ? wp_get_referer() : admin_url('admin.php?page=wtols-settings');
		$raw_referer = wp_get_raw_referer();
		$safe_redirect = $raw_referer ? esc_url_raw($raw_referer) : $redirect;
		wp_safe_redirect(add_query_arg(array('wtols_cache_cleared' => '1'), $safe_redirect));
		exit;
	}

	public function render_admin_notices()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_dismiss_cache_notice']) && '1' === $_GET['wtols_dismiss_cache_notice']) {
			update_option('wtols_dismiss_cache_notice', 1);
		}

		$options = self::get_options();
		$slug = isset($options['login_slug']) ? trim($options['login_slug']) : '';
		
		if ('' !== $slug && !get_option('wtols_dismiss_cache_notice')) {
			$caching_active = false;
			$active_cache_plugin = '';

			if (defined('WP_ROCKET_VERSION')) {
				$caching_active = true;
				$active_cache_plugin = 'WP Rocket';
			} elseif (defined('LSCWP_DIR') || class_exists('LiteSpeed_Cache_API')) {
				$caching_active = true;
				$active_cache_plugin = 'LiteSpeed Cache';
			} elseif (defined('SG_CACHEPRESS_CURRENT_VERSION') || function_exists('sg_cachepress_purge_cache')) {
				$caching_active = true;
				$active_cache_plugin = 'Speed Optimizer (SG Optimizer)';
			} elseif (defined('W3TC') || function_exists('w3tc_flush_all')) {
				$caching_active = true;
				$active_cache_plugin = 'W3 Total Cache';
			} elseif (defined('WPSC_VERSION') || function_exists('wp_cache_clear_cache')) {
				$caching_active = true;
				$active_cache_plugin = 'WP Super Cache';
			} elseif (class_exists('WpeCommon')) {
				$caching_active = true;
				$active_cache_plugin = 'WP Engine Cache';
			} elseif (defined('WP_CACHE') && WP_CACHE) {
				$caching_active = true;
				$active_cache_plugin = 'WordPress Cache';
			}

			if ($caching_active) {
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended
				$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
				$current_url = remove_query_arg('wtols_dismiss_cache_notice', $request_uri);
				$dismiss_url = add_query_arg('wtols_dismiss_cache_notice', '1', $current_url);

				echo '<div class="notice notice-warning is-dismissible"><p>';
				echo '<strong>' . esc_html__('Webtaru Site Options:', 'webtaru-site-options-login-security') . '</strong> ';
				printf(
					/* translators: 1: Caching plugin name, 2: Custom login URL, 3: Start bold, 4: End bold, 5: Dismiss link HTML */
					esc_html__('We detected that %1$s is active and you have a Custom Login URL (%2$s). Please make sure to %3$sexclude your custom login slug from caching%4$s in its settings to avoid redirect loops. %5$s', 'webtaru-site-options-login-security'),
					esc_html($active_cache_plugin),
					'<code>/' . esc_html($slug) . '/</code>',
					'<strong>',
					'</strong>',
					'<a href="' . esc_url($dismiss_url) . '" style="margin-left: 10px; text-decoration: none; font-weight: bold; color: #d63638;">' . esc_html__('Dismiss Warning', 'webtaru-site-options-login-security') . '</a>'
				);
				echo '</p></div>';
			}
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_saved'])) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__('Settings saved.', 'webtaru-site-options-login-security') . '</p></div>';
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_cache_cleared'])) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__('Cache successfully cleared sitewide.', 'webtaru-site-options-login-security') . '</p></div>';
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['wtols_comments_deleted'])) {
			echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__('All comments have been successfully deleted.', 'webtaru-site-options-login-security') . '</p></div>';
		}

		/* Security Check for 'admin' username */
		$options = self::get_options();
		if (!empty($options['disable_common_usernames'])) {
			if (username_exists('admin')) {
				echo '<div class="notice notice-error"><p><strong>' . esc_html__('Security Risk Detected:', 'webtaru-site-options-login-security') . '</strong> ' . esc_html__('A user with the username "admin" still exists on your site. This is a common target for hackers. We recommend creating a new administrator account and deleting the "admin" user.', 'webtaru-site-options-login-security') . '</p></div>';
			}
		}
	}

	private function execute_cache_flush()
	{
		// WP Rocket
		if (function_exists('rocket_clean_domain')) {
			rocket_clean_domain();
		}
		// LiteSpeed Cache
		if (class_exists('LiteSpeed_Cache_API') && method_exists('LiteSpeed_Cache_API', 'purge_all')) {
			\LiteSpeed_Cache_API::purge_all();
		} elseif (has_action('litespeed_purge_all')) {
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
			do_action('litespeed_purge_all');
		}
		// W3 Total Cache
		if (function_exists('w3tc_flush_all')) {
			w3tc_flush_all();
		}
		// SG Optimizer
		if (function_exists('sg_cachepress_purge_cache')) {
			sg_cachepress_purge_cache();
		}
		// WP Super Cache
		if (function_exists('wp_cache_clear_cache')) {
			wp_cache_clear_cache();
		}
	}

	public function init_utilities()
	{
		$options = self::get_options();

		if (!empty($options['disable_update_emails'])) {
			add_filter('auto_plugin_update_send_email', '__return_false');
			add_filter('auto_theme_update_send_email', '__return_false');
			add_filter('auto_core_update_send_email', '__return_false');
			add_filter('send_core_update_notification_email', '__return_false');
		}

		if (!empty($options['disable_gutenberg'])) {
			add_filter('use_block_editor_for_post', '__return_false', 10);
			add_filter('use_widgets_block_editor', '__return_false', 10);
		}
		if (!empty($options['disable_file_editor']) && !defined('DISALLOW_FILE_EDIT')) {
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound
			define('DISALLOW_FILE_EDIT', true);
		}
		if (!empty($options['disable_comments_sitewide'])) {
			add_filter('comments_open', '__return_false', 20, 2);
			add_filter('pings_open', '__return_false', 20, 2);
			add_filter('comments_array', '__return_empty_array', 10, 2);
		}
	}

	public function render_styling_css_vars()
	{
		$options = self::get_options();
		if (empty($options['color_text']) && empty($options['color_background']) && empty($options['color_icon'])) {
			return;
		}

		$css = ':root {';
		if (!empty($options['color_text'])) {
			$css .= '--wtols-text-color: ' . esc_attr($options['color_text']) . ';';
		}
		if (!empty($options['color_background'])) {
			$css .= '--wtols-bg-color: ' . esc_attr($options['color_background']) . ';';
		}
		if (!empty($options['color_icon'])) {
			$css .= '--wtols-icon-color: ' . esc_attr($options['color_icon']) . ';';
		}
		$css .= '}';

		wp_add_inline_style('wtols-frontend', $css);
	}


	public function add_duplicate_post_link($actions, $post)
	{
		$options = self::get_options();
		if (empty($options['enable_duplicator']) || !current_user_can('edit_posts')) {
			return $actions;
		}
		$actions['wtols_duplicate'] = '<a href="' . wp_nonce_url(admin_url('admin-post.php?action=wtols_duplicate_post&post=' . $post->ID), 'wtols_duplicate_post_' . $post->ID) . '" title="' . esc_attr__('Duplicate this item', 'webtaru-site-options-login-security') . '" rel="permalink">' . esc_html__('Duplicate', 'webtaru-site-options-login-security') . '</a>';
		return $actions;
	}

	public function add_duplicate_post_button_submitbox()
	{
		global $post;
		$options = self::get_options();
		if (empty($options['enable_duplicator']) || !current_user_can('edit_posts') || empty($post) || !isset($post->ID)) {
			return;
		}
		
		$url = wp_nonce_url(admin_url('admin-post.php?action=wtols_duplicate_post&post=' . $post->ID), 'wtols_duplicate_post_' . $post->ID);
		echo '<div class="misc-pub-section misc-pub-duplicate" style="border-top: 1px solid #dcdcde; margin-top: 5px; padding-top: 10px;">';
		echo '<a href="' . esc_url($url) . '" class="button button-large" style="width: 100%; text-align: center;"><span class="dashicons dashicons-admin-page" style="line-height: 1.5; margin-right: 5px;"></span>' . esc_html__('Duplicate Post', 'webtaru-site-options-login-security') . '</a>';
		echo '</div>';
	}

	public function add_media_replace_to_modal($form_fields, $post) {
		$options = self::get_options();
		if (empty($options['enable_media_replace'])) {
			return $form_fields;
		}
		if (!$post) return $form_fields;
		$post_id = is_object($post) ? $post->ID : (is_array($post) ? (isset($post['ID']) ? $post['ID'] : 0) : intval($post));
		if (!$post_id) return $form_fields;
		
		$url = admin_url('post.php?post=' . $post_id . '&action=edit');
		$form_fields['wtols_replace'] = array(
			'label' => __('Replace File', 'webtaru-site-options-login-security'),
			'input' => 'html',
			'html'  => '<a href="' . esc_url($url) . '" class="button button-small" target="_blank" style="margin-top:5px; display:inline-block;">' . __('Replace this media file', 'webtaru-site-options-login-security') . '</a>',
			'helps' => __('Opens the edit page to upload a replacement file while keeping the URL.', 'webtaru-site-options-login-security'),
		);
		return $form_fields;
	}

	public function handle_duplicate_post()
	{
		$options = self::get_options();
		if (empty($options['enable_duplicator']) || !current_user_can('edit_posts')) {
			wp_die(esc_html__('Duplicate feature is disabled or you do not have permission.', 'webtaru-site-options-login-security'));
		}

		$post_id = isset($_GET['post']) ? absint($_GET['post']) : 0;
		if (!$post_id) {
			wp_die(esc_html__('No post to duplicate.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_duplicate_post_' . $post_id);

		$post = get_post($post_id);
		if (!$post) {
			wp_die(esc_html__('Post not found.', 'webtaru-site-options-login-security'));
		}

		$current_user = wp_get_current_user();
		$new_post_author = $current_user->ID;

		$args = array(
			'comment_status' => $post->comment_status,
			'ping_status' => $post->ping_status,
			'post_author' => $new_post_author,
			'post_content' => $post->post_content,
			'post_excerpt' => $post->post_excerpt,
			'post_name' => $post->post_name,
			'post_parent' => $post->post_parent,
			'post_password' => $post->post_password,
			'post_status' => 'draft',
			'post_title' => $post->post_title . ' (Copy)',
			'post_type' => $post->post_type,
			'to_ping' => $post->to_ping,
			'menu_order' => $post->menu_order,
		);

		$new_post_id = wp_insert_post($args);

		$taxonomies = get_object_taxonomies($post->post_type);
		foreach ($taxonomies as $taxonomy) {
			$post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
			wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
		}

		$post_meta_infos = get_post_meta($post_id);
		if (count($post_meta_infos) !== 0) {
			foreach ($post_meta_infos as $meta_key => $meta_values) {
				foreach ($meta_values as $meta_value) {
					add_post_meta($new_post_id, $meta_key, wp_slash(maybe_unserialize($meta_value)));
				}
			}
		}

		wp_safe_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
		exit;
	}

	public function handle_delete_all_comments()
	{
		if (!current_user_can('moderate_comments')) {
			wp_die(esc_html__('You do not have permission to delete comments.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_delete_all_comments');

		global $wpdb;

		// Optional: Clear comment count cache
		wp_cache_delete('comment_count', 'counts');

		// Perform deletion
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$wpdb->query("DELETE FROM {$wpdb->comments}");
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$wpdb->query("DELETE FROM {$wpdb->commentmeta}");

		// Update comment count on all posts
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$wpdb->query("UPDATE {$wpdb->posts} SET comment_count = 0");

		$redirect = admin_url('admin.php?page=wtols-settings&wtols_comments_deleted=1&wtols_active_tab=utilities');
		wp_safe_redirect($redirect);
		exit;
	}

	private function render_plugin_management_table($options)
	{
		// Removed to satisfy WordPress.org requirements
		echo '<p>' . esc_html__('Plugin update management is not available in the WordPress.org version of this plugin.', 'webtaru-site-options-login-security') . '</p>';
	}

	public function handle_export_settings()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to export settings.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_export_settings');

		$options = self::get_options();
		$json = wp_json_encode($options);

		header('Content-Description: File Transfer');
		header('Content-Type: application/json');
		header('Content-Disposition: attachment; filename=wtols-settings-export-' . gmdate('Y-m-d') . '.json');
		header('Expires: 0');
		header('Cache-Control: must-revalidate');
		header('Pragma: public');
		header('Content-Length: ' . strlen($json));

		echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	private function get_user_ip()
	{
		if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_CF_CONNECTING_IP']));
		} elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_CLIENT_IP']));
		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			return sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
		} else {
			return isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '0.0.0.0';
		}
	}

	public function handle_import_settings()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to import settings.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_import_settings');

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$file_path = isset($_FILES['wtols_import_file']['tmp_name']) ? $_FILES['wtols_import_file']['tmp_name'] : '';
		if (empty($file_path) || !is_uploaded_file($file_path)) {
			wp_die(esc_html__('No file uploaded or invalid file.', 'webtaru-site-options-login-security'));
		}
		$file_content = file_get_contents($file_path); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		$imported_data = json_decode($file_content, true);

		if (!is_array($imported_data)) {
			wp_die(esc_html__('Invalid JSON file.', 'webtaru-site-options-login-security'));
		}

		$current_options = self::get_options();
		$merged_options = wp_parse_args($imported_data, $current_options);

		update_option(self::OPTION_KEY, $merged_options);

		$redirect = wp_get_referer() ? wp_get_referer() : admin_url('admin.php?page=wtols-settings');
		wp_safe_redirect(add_query_arg('wtols_saved', '1', $redirect));
		exit;
	}

	public function handle_version_hiding()
	{
		$options = self::get_options();
		if (empty($options['hide_wp_version'])) {
			return;
		}

		// Remove version from header
		remove_action('wp_head', 'wp_generator');
		add_filter('the_generator', '__return_empty_string');

		// Remove version from scripts and styles
		add_filter('script_loader_src', array($this, 'remove_wp_version_strings'), 9999);
		add_filter('style_loader_src', array($this, 'remove_wp_version_strings'), 9999);
	}

	public function remove_wp_version_strings($src)
	{
		if (strpos($src, 'ver=' . get_bloginfo('version'))) {
			$src = remove_query_arg('ver', $src);
		}
		return $src;
	}

	public function handle_reset_settings()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to reset settings.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_reset_settings');

		delete_option(self::OPTION_KEY);

		$redirect = admin_url('admin.php?page=wtols-settings');
		wp_safe_redirect(add_query_arg(array('wtols_saved' => '1', 'wtols_reset' => '1'), $redirect));
		exit;
	}

	public function handle_maintenance_mode()
	{
		$options = self::get_options();
		
		$is_login_page = ( isset( $GLOBALS['pagenow'] ) && in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) ) );

		if (empty($options['enable_maintenance']) || current_user_can('manage_options') || $is_login_page) {
			return;
		}

		// Maintenance Mode Bypass Key check
		$bypass_key = isset($options['maintenance_bypass_key']) ? trim($options['maintenance_bypass_key']) : '';
		if ('' !== $bypass_key) {
			$param_key = '';
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			if (isset($_GET['wtols_bypass']) && $_GET['wtols_bypass'] === $bypass_key) {
				$param_key = 'wtols_bypass';
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			} elseif (isset($_GET['bypass']) && $_GET['bypass'] === $bypass_key) {
				$param_key = 'bypass';
			}

			if ($param_key) {
				setcookie('wtols_maintenance_bypass', $bypass_key, time() + 30 * DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true);
				wp_safe_redirect(remove_query_arg($param_key));
				exit;
			}

			if (isset($_COOKIE['wtols_maintenance_bypass']) && $_COOKIE['wtols_maintenance_bypass'] === $bypass_key) {
				return;
			}
		}

		$heading = !empty($options['maintenance_heading']) ? $options['maintenance_heading'] : __('Site Under Maintenance', 'webtaru-site-options-login-security');
		$message = wp_kses_post($options['maintenance_message']);

		header('HTTP/1.1 503 Service Temporarily Unavailable');
		header('Status: 503 Service Temporarily Unavailable');
		header('Retry-After: 3600');

		$logo_url = !empty($options['logo_light_url']) ? $options['logo_light_url'] : (!empty($options['logo_dark_url']) ? $options['logo_dark_url'] : '');
		if (empty($logo_url) && !empty($options['login_logo_url'])) {
			$logo_url = $options['login_logo_url'];
		}

		$socials_html = '';
		$has_socials = false;
		$socials = isset($options['social_links']) ? $options['social_links'] : array();
		foreach ($socials as $key => $social) {
			if (!empty($social['url'])) {
				$has_socials = true;
				$socials_html .= '<a href="' . esc_url($social['url']) . '" class="social-icon" target="_blank" rel="noopener noreferrer" title="' . esc_attr($social['label']) . '">';
				if (!empty($options['enable_fontawesome'])) {
					$socials_html .= '<i class="' . esc_attr($social['icon']) . '"></i>';
				} else {
					$socials_html .= esc_html($social['label']);
				}
				$socials_html .= '</a>';
			}
		}

		$contact_html = '';
		$has_contact = false;
		if (!empty($options['phone'])) {
			$has_contact = true;
			$contact_html .= '<a href="tel:' . esc_attr($options['phone']) . '" class="contact-item">';
			if (!empty($options['enable_fontawesome'])) {
				$contact_html .= '<i class="fa-solid fa-phone"></i>';
			}
			$contact_html .= ' ' . esc_html($options['phone']) . '</a>';
		}

		echo '<!DOCTYPE html>
		<html lang="en">
		<head>
			<meta charset="UTF-8">
			<meta name="viewport" content="width=device-width, initial-scale=1.0">
			<title>' . esc_html($heading) . '</title>
			<style>
				@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap");
				' . ( (!empty($options['enable_fontawesome'])) ? '@import url("' . esc_url(WTOLS_PLUGIN_URL . 'assets/vendor/fontawesome/css/all.min.css') . '");' : '' ) . '
				:root {
					--bg-gradient-start: #0f172a;
					--bg-gradient-end: #020617;
					--accent-color: #6366f1;
					--accent-glow: rgba(99, 102, 241, 0.15);
					--text-primary: #f8fafc;
					--text-secondary: #94a3b8;
					--card-bg: rgba(15, 23, 42, 0.6);
					--card-border: rgba(255, 255, 255, 0.08);
				}
				* {
					box-sizing: border-box;
				}
				body {
					margin: 0;
					padding: 0;
					font-family: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
					background: linear-gradient(135deg, var(--bg-gradient-start), var(--bg-gradient-end));
					color: var(--text-primary);
					display: flex;
					align-items: center;
					justify-content: center;
					min-height: 100vh;
					position: relative;
					overflow-x: hidden;
				}
				.ambient-orb {
					position: absolute;
					width: 600px;
					height: 600px;
					border-radius: 50%;
					background: radial-gradient(circle, var(--accent-glow) 0%, rgba(99, 102, 241, 0) 70%);
					top: 50%;
					left: 50%;
					transform: translate(-50%, -50%);
					z-index: 0;
					pointer-events: none;
					animation: pulse-orb 8s ease-in-out infinite alternate;
				}
				@keyframes pulse-orb {
					0% { transform: translate(-50%, -50%) scale(0.9); opacity: 0.8; }
					100% { transform: translate(-50%, -50%) scale(1.1); opacity: 1; }
				}
				.maintenance-wrapper {
					position: relative;
					z-index: 10;
					width: 100%;
					max-width: 650px;
					padding: 20px;
					display: flex;
					flex-direction: column;
					align-items: center;
				}
				.logo-container {
					margin-bottom: 24px;
					max-width: 240px;
					text-align: center;
				}
				.logo-container img {
					max-width: 100%;
					height: auto;
					filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.2));
				}
				.logo-container .site-title {
					font-size: 1.5rem;
					font-weight: 700;
					letter-spacing: -0.025em;
					background: linear-gradient(135deg, #ffffff 0%, #cbd5e1 100%);
					-webkit-background-clip: text;
					-webkit-text-fill-color: transparent;
				}
				.maintenance-container {
					background: var(--card-bg);
					border: 1px solid var(--card-border);
					backdrop-filter: blur(24px);
					-webkit-backdrop-filter: blur(24px);
					padding: 48px 40px;
					border-radius: 24px;
					box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3), 
					            inset 0 1px 0 rgba(255, 255, 255, 0.1);
					text-align: center;
					width: 100%;
					position: relative;
					overflow: hidden;
				}
				.maintenance-container::before {
					content: "";
					position: absolute;
					top: 0;
					left: 0;
					right: 0;
					height: 3px;
					background: linear-gradient(90deg, transparent, var(--accent-color), transparent);
				}
				.status-icon-wrapper {
					display: inline-flex;
					align-items: center;
					justify-content: center;
					width: 90px;
					height: 90px;
					border-radius: 50%;
					background: rgba(99, 102, 241, 0.08);
					border: 1px solid rgba(99, 102, 241, 0.2);
					margin-bottom: 28px;
					position: relative;
				}
				.status-icon-wrapper::after {
					content: "";
					position: absolute;
					inset: -4px;
					border-radius: 50%;
					border: 1px dashed rgba(99, 102, 241, 0.3);
					animation: rotate-dashed 20s linear infinite;
				}
				@keyframes rotate-dashed {
					0% { transform: rotate(0deg); }
					100% { transform: rotate(360deg); }
				}
				.status-icon {
					width: 48px;
					height: 48px;
					color: var(--accent-color);
					animation: float-icon 4s ease-in-out infinite;
					display: flex;
					align-items: center;
					justify-content: center;
				}
				@keyframes float-icon {
					0%, 100% { transform: translateY(0); }
					50% { transform: translateY(-6px); }
				}
				h1 {
					font-size: 2.25rem;
					font-weight: 800;
					line-height: 1.2;
					margin-top: 0;
					margin-bottom: 16px;
					letter-spacing: -0.03em;
					background: linear-gradient(135deg, #ffffff 0%, #e2e8f0 50%, #94a3b8 100%);
					-webkit-background-clip: text;
					-webkit-text-fill-color: transparent;
				}
				.maintenance-message {
					font-size: 1.1rem;
					line-height: 1.6;
					color: var(--text-secondary);
					margin-bottom: 32px;
					font-weight: 400;
				}
				.divider {
					height: 1px;
					background: radial-gradient(circle, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 100%);
					margin: 24px 0;
				}
				.contact-section {
					display: flex;
					flex-direction: column;
					align-items: center;
					gap: 16px;
				}
				.contact-title {
					font-size: 0.875rem;
					text-transform: uppercase;
					letter-spacing: 0.05em;
					color: var(--text-secondary);
					font-weight: 600;
				}
				.social-links {
					display: flex;
					justify-content: center;
					gap: 12px;
					flex-wrap: wrap;
				}
				.social-icon {
					display: inline-flex;
					align-items: center;
					justify-content: center;
					width: 42px;
					height: 42px;
					border-radius: 50%;
					background: rgba(255, 255, 255, 0.03);
					border: 1px solid rgba(255, 255, 255, 0.08);
					color: var(--text-secondary);
					text-decoration: none;
					transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
				}
				.social-icon:hover {
					background: var(--accent-color);
					color: #ffffff;
					transform: translateY(-3px);
					box-shadow: 0 10px 20px rgba(99, 102, 241, 0.3);
					border-color: var(--accent-color);
				}
				.contact-details {
					display: flex;
					gap: 20px;
					flex-wrap: wrap;
					justify-content: center;
					font-size: 0.9rem;
					color: var(--text-secondary);
				}
				.contact-item {
					display: flex;
					align-items: center;
					gap: 8px;
					text-decoration: none;
					color: var(--text-secondary);
					transition: color 0.2s ease;
				}
				.contact-item:hover {
					color: var(--accent-color);
				}
				.contact-item i {
					color: var(--accent-color);
					font-size: 0.95rem;
				}
				.footer-branding {
					margin-top: 24px;
					font-size: 0.8rem;
					color: rgba(255, 255, 255, 0.3);
				}
				.footer-branding a {
					color: rgba(255, 255, 255, 0.4);
					text-decoration: none;
					transition: color 0.2s ease;
				}
				.footer-branding a:hover {
					color: var(--accent-color);
				}
				@media (max-width: 600px) {
					.maintenance-container {
						padding: 36px 24px;
						border-radius: 20px;
					}
					h1 {
						font-size: 1.75rem;
					}
					.maintenance-message {
						font-size: 1rem;
					}
				}
			</style>
		</head>
		<body>
			<div class="ambient-orb"></div>
			<div class="maintenance-wrapper">
				<div class="logo-container">
					' . ( !empty($logo_url) 
						? '<img src="' . esc_url($logo_url) . '" alt="' . esc_attr(get_bloginfo('name')) . '">' 
						: '<div class="site-title">' . esc_html(get_bloginfo('name')) . '</div>' ) . '
				</div>
				<div class="maintenance-container">
					<div class="status-icon-wrapper">
						<div class="status-icon">
							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; animation: spin 8s linear infinite;">
								<style>
									@keyframes spin {
										100% { transform: rotate(360deg); }
									}
								</style>
								<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.1a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/>
								<circle cx="12" cy="12" r="3"/>
							</svg>
						</div>
					</div>
					<h1>' . esc_html($heading) . '</h1>
					<div class="maintenance-message">' . wp_kses_post($message) . '</div>
					
					' . ( ($has_socials || $has_contact) ? '<div class="divider"></div>' : '' ) . '
					
					<div class="contact-section">
						' . ( $has_socials ? '<div class="contact-title">' . esc_html__('Follow Us', 'webtaru-site-options-login-security') . '</div>
						<div class="social-links">' . wp_kses_post($socials_html) . '</div>' : '' ) . '
						
						' . ( $has_contact ? '
						<div class="contact-details">' . wp_kses_post($contact_html) . '</div>' : '' ) . '
					</div>
				</div>
			</div>
		</body>
		</html>';
		exit;
	}

	public function render_sticky_whatsapp()
	{
		$options = self::get_options();
		if (empty($options['enable_sticky_whatsapp']) || empty($options['whatsapp_number'])) {
			return;
		}

		$number = preg_replace('/[^0-9]/', '', $options['whatsapp_number']);
		if (empty($number)) {
			return;
		}

		$message = '';
		if (!empty($options['sticky_whatsapp_message'])) {
			$message = '?text=' . rawurlencode(trim($options['sticky_whatsapp_message']));
		}

		$url = 'https://wa.me/' . $number . $message;
		
		$position_class = 'right' === $options['sticky_whatsapp_position'] ? 'wtols-wa-pos-right' : 'wtols-wa-pos-left';
		
		$display_class = '';
		if ('mobile' === $options['sticky_whatsapp_display']) {
			$display_class = 'wtols-wa-display-mobile';
		} elseif ('desktop' === $options['sticky_whatsapp_display']) {
			$display_class = 'wtols-wa-display-desktop';
		} else {
			$display_class = 'wtols-wa-display-both';
		}

		$wrapper_classes = array('wtols-sticky-whatsapp', $position_class, $display_class);
		if (!empty($options['enable_mobile_buttons'])) {
			$wrapper_classes[] = 'wtols-mbb-offset';
		}

		$icon_size = isset($options['sticky_whatsapp_icon_size']) ? (int) $options['sticky_whatsapp_icon_size'] : 32;

		echo '<a href="' . esc_url($url) . '" class="' . esc_attr(implode(' ', $wrapper_classes)) . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('WhatsApp Chat', 'webtaru-site-options-login-security') . '">';
		echo '<i class="fab fa-whatsapp" style="font-size: ' . esc_attr($icon_size) . 'px;"></i>';
		echo '</a>';
	}

	public function render_rating_widget()
	{
		$options = self::get_options();
		if (empty($options['enable_rating_widget'])) {
			return;
		}

		$provider = $options['rating_widget_provider'];
		$score = esc_html($options['rating_widget_score']);
		$link = esc_url($options['rating_widget_link']);
		$display = $options['rating_widget_display'];

		$display_class = '';
		if ('mobile' === $display) {
			$display_class = 'wtols-rw-display-mobile';
		} elseif ('desktop' === $display) {
			$display_class = 'wtols-rw-display-desktop';
		}

		$icon_type = isset($options['rating_widget_icon_type']) ? $options['rating_widget_icon_type'] : 'icon';
		$image_url = isset($options['rating_widget_image_url']) ? $options['rating_widget_image_url'] : '';

		$wrapper_classes = array('wtols-rating-widget', 'wtols-rw-' . $provider, $display_class);
		if (!empty($options['enable_mobile_buttons'])) {
			$wrapper_classes[] = 'wtols-mbb-offset';
		}

		$icon_html = '';
		$title = '';
		if ('image' === $icon_type && !empty($image_url)) {
			$icon_html = '<div class="wtols-rw-icon wtols-rw-custom-image"><img src="' . esc_url($image_url) . '" alt="" style="max-width:32px; max-height:32px; display:block;" /></div>';
			$title = ('google' === $provider) ? __('Google rating', 'webtaru-site-options-login-security') : __('Trustpilot', 'webtaru-site-options-login-security');
		} else {
			if ('google' === $provider) {
				$icon_html = '<div class="wtols-rw-icon"><i class="fab fa-google" style="color: #4285F4;"></i></div>';
				$title = __('Google rating', 'webtaru-site-options-login-security');
			} else {
				$icon_html = '<div class="wtols-rw-icon"><i class="fab fa-trustpilot" style="color: #00b67a;"></i></div>';
				$title = __('Trustpilot', 'webtaru-site-options-login-security');
			}
		}

		$score_float = (float) $score;
		$stars_html = '<div class="wtols-rw-stars">';
		for ($i = 1; $i <= 5; $i++) {
			if ($score_float >= $i) {
				$stars_html .= '<i class="fas fa-star"></i>';
			} elseif ($score_float >= ($i - 0.5)) {
				$stars_html .= '<i class="fas fa-star-half-alt"></i>';
			} else {
				$stars_html .= '<i class="far fa-star"></i>';
			}
		}
		$stars_html .= '</div>';

		echo '<a href="' . esc_url($link) . '" class="' . esc_attr(implode(' ', $wrapper_classes)) . '" target="_blank" rel="noopener noreferrer">';
		echo '<div class="wtols-rw-inner">';
		echo wp_kses($icon_html, array('div' => array('class' => array()), 'i' => array('class' => array(), 'style' => array()), 'img' => array('src' => array(), 'alt' => array(), 'style' => array())));
		echo '<div class="wtols-rw-content">';
		echo '<div class="wtols-rw-title">' . esc_html($title) . '</div>';
		echo '<div class="wtols-rw-score-wrap"><span class="wtols-rw-score">' . esc_html($score) . '</span> ' . wp_kses($stars_html, array('div' => array('class' => array()), 'i' => array('class' => array()))) . '</div>';
		echo '</div>'; // content
		echo '</div>'; // inner
		echo '</a>';
	}

	public function render_back_to_top()
	{
		$options = self::get_options();
		if (empty($options['enable_back_to_top'])) {
			return;
		}

		$bg_color = isset($options['back_to_top_bg_color']) ? $options['back_to_top_bg_color'] : '#5cb85c';
		$icon_color = isset($options['back_to_top_icon_color']) ? $options['back_to_top_icon_color'] : '#ffffff';
		$shape = isset($options['back_to_top_shape']) ? $options['back_to_top_shape'] : 'square';
		$size  = isset($options['back_to_top_size']) ? (int) $options['back_to_top_size'] : 20;

		$display = isset($options['back_to_top_display']) ? $options['back_to_top_display'] : 'both';
		$display_class = '';
		if ('mobile' === $display) {
			$display_class = 'wtols-btt-display-mobile';
		} elseif ('desktop' === $display) {
			$display_class = 'wtols-btt-display-desktop';
		}

		$classes = array('wtols-back-to-top', $display_class, 'wtols-btt-' . $shape);
		if (!empty($options['enable_mobile_buttons'])) {
			$classes[] = 'wtols-mbb-offset';
		}

		$style = 'background-color: ' . esc_attr($bg_color) . '; color: ' . esc_attr($icon_color) . '; font-size: ' . esc_attr($size) . 'px;';

		echo '<a href="#" class="' . esc_attr(implode(' ', $classes)) . '" aria-label="' . esc_attr__('Back to top', 'webtaru-site-options-login-security') . '" style="' . esc_attr($style) . '">';
		echo '<i class="fas fa-chevron-up"></i>';
		echo '</a>';
	}

	public function render_mobile_bottom_buttons()
	{
		$options = self::get_options();
		if (empty($options['enable_mobile_buttons'])) {
			return;
		}

		$btn1_text = trim($options['mobile_button_1_text']);
		$btn1_link = trim($options['mobile_button_1_link']);
		$btn1_color = isset($options['mobile_button_1_color']) ? $options['mobile_button_1_color'] : '#5cb85c';
		$btn1_text_color = isset($options['mobile_button_1_text_color']) ? $options['mobile_button_1_text_color'] : '#ffffff';

		$btn2_text = trim($options['mobile_button_2_text']);
		$btn2_link = trim($options['mobile_button_2_link']);
		$btn2_color = isset($options['mobile_button_2_color']) ? $options['mobile_button_2_color'] : '#0275d8';
		$btn2_text_color = isset($options['mobile_button_2_text_color']) ? $options['mobile_button_2_text_color'] : '#ffffff';

		if (empty($btn1_text) && empty($btn2_text)) {
			return;
		}

		echo '<div class="wtols-mobile-bottom-bar">';
		if (!empty($btn1_text)) {
			echo '<a href="' . esc_url($btn1_link) . '" class="wtols-mbb-btn" style="background-color: ' . esc_attr($btn1_color) . '; color: ' . esc_attr($btn1_text_color) . ';">' . esc_html($btn1_text) . '</a>';
		}
		if (!empty($btn2_text)) {
			echo '<a href="' . esc_url($btn2_link) . '" class="wtols-mbb-btn" style="background-color: ' . esc_attr($btn2_color) . '; color: ' . esc_attr($btn2_text_color) . ';">' . esc_html($btn2_text) . '</a>';
		}
		echo '</div>';
	}

	public function log_failed_login_attempt($username)

	{
		$options = self::get_options();
		if (empty($options['limiter_enabled'])) {
			return;
		}

		$logs = isset($options['login_logs']) ? $options['login_logs'] : array();
		$ip = $this->get_user_ip();

		array_unshift($logs, array(
			'ip' => $ip,
			'user' => sanitize_text_field($username),
			'time' => current_time('mysql'),
		));

		// Limit to 100 entries
		$logs = array_slice($logs, 0, 100);

		$options['login_logs'] = $logs;
		update_option(self::OPTION_KEY, $options);
	}

	public function handle_db_cleanup()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to perform cleanup.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_db_cleanup');

		global $wpdb;

		// 1. Delete Revisions
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->posts WHERE post_type = %s", 'revision'));

		// 2. Delete Auto-drafts
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->posts WHERE post_status = %s", 'auto-draft'));

		// 3. Delete Expired Transients
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE %s AND option_value < %d", '_transient_timeout_%', time()));
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_%' AND NOT EXISTS (SELECT 1 FROM $wpdb->options AS o2 WHERE o2.option_name = CONCAT('_transient_timeout_', SUBSTRING($wpdb->options.option_name, 12)))");

		wp_safe_redirect(add_query_arg(array('wtols_saved' => '1', 'wtols_cleaned' => '1'), admin_url('admin.php?page=wtols-settings&wtols_active_tab=utilities')));
		exit;
	}

	public function organize_admin_menu()
	{
		if (current_user_can('manage_options')) {
			return; // Don't lock out administrators
		}

		$options = self::get_options();
		$hidden = isset($options['hidden_admin_menus']) ? $options['hidden_admin_menus'] : array();

		if (empty($hidden)) {
			return;
		}

		foreach ($hidden as $slug) {
			remove_menu_page($slug);
		}
	}

	public function render_sticky_vertical_btn()
	{
		$options = self::get_options();
		if (empty($options['enable_sticky_vertical_btn'])) {
			return;
		}

		$text = !empty($options['sticky_vertical_btn_text']) ? $options['sticky_vertical_btn_text'] : '';
		$icon = !empty($options['sticky_vertical_btn_icon']) ? $options['sticky_vertical_btn_icon'] : '';
		$id_class = !empty($options['sticky_vertical_btn_id_class']) ? trim($options['sticky_vertical_btn_id_class']) : '';
		
		$bg_color = !empty($options['sticky_vertical_btn_bg_color']) ? $options['sticky_vertical_btn_bg_color'] : '#0073aa';
		$text_color = !empty($options['sticky_vertical_btn_text_color']) ? $options['sticky_vertical_btn_text_color'] : '#ffffff';
		$icon_color = !empty($options['sticky_vertical_btn_icon_color']) ? $options['sticky_vertical_btn_icon_color'] : '#ffffff';
		$position = isset($options['sticky_vertical_btn_position']) && $options['sticky_vertical_btn_position'] !== '' ? intval($options['sticky_vertical_btn_position']) : 50;

		$attr_id = '';
		$attr_class = 'wtols-sticky-vertical-btn';
		
		if (!empty($id_class)) {
			if (strpos($id_class, '#') === 0) {
				$attr_id = substr($id_class, 1);
			} elseif (strpos($id_class, '.') === 0) {
				$attr_class .= ' ' . substr($id_class, 1);
			} else {
				$attr_class .= ' ' . $id_class;
			}
		}

		$style = sprintf(
			'background-color: %s; color: %s; top: %d%%;',
			$bg_color,
			$text_color,
			$position
		);

		printf(
			'<div %s class="%s" style="%s">',
			!empty($attr_id) ? 'id="' . esc_attr($attr_id) . '"' : '',
			esc_attr($attr_class),
			esc_attr($style)
		);
		echo '<a href="#" class="wtols-sticky-vertical-btn-inner" style="color: ' . esc_attr($text_color) . ';" onclick="event.preventDefault();">';
		if (!empty($icon)) {
			echo '<i class="' . esc_attr($icon) . '" style="color: ' . esc_attr($icon_color) . ';"></i>';
		}
		if (!empty($text)) {
			echo '<span class="wtols-sticky-vertical-btn-text">' . esc_html($text) . '</span>';
		}
		echo '</a></div>';
	}

	public function render_custom_header_code() {
		$options = self::get_options();
		if (!empty($options['custom_header_code'])) {
			echo "\n<!-- Webtaru Custom Header Code -->\n";
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo current_user_can('unfiltered_html') ? $options['custom_header_code'] : wp_kses_post($options['custom_header_code']);
			echo "\n<!-- End Webtaru Custom Header Code -->\n";
		}
	}

	public function render_custom_body_code() {
		$options = self::get_options();
		if (!empty($options['custom_body_code'])) {
			echo "\n<!-- Webtaru Custom Body Code -->\n";
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo current_user_can('unfiltered_html') ? $options['custom_body_code'] : wp_kses_post($options['custom_body_code']);
			echo "\n<!-- End Webtaru Custom Body Code -->\n";
		}
	}

	public function render_custom_css()
	{
		$options = self::get_options();
		if (!empty($options['custom_css'])) {
			$css = wp_strip_all_tags($options['custom_css']);
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo "\n<style type=\"text/css\" id=\"wtols-custom-css\">\n" . $css . "\n</style>\n";
		}
	}

	public function render_custom_footer_code() {
		$options = self::get_options();
		if (!empty($options['custom_footer_code'])) {
			echo "\n<!-- Webtaru Custom Footer Code -->\n";
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo current_user_can('unfiltered_html') ? $options['custom_footer_code'] : wp_kses_post($options['custom_footer_code']);
			echo "\n<!-- End Webtaru Custom Footer Code -->\n";
		}
	}

	public function add_admin_bar_maintenance_mode($wp_admin_bar)
	{
		$options = self::get_options();
		if (!empty($options['enable_maintenance'])) {
			$title = '<span style="color: #ff9800; font-weight: bold;"><span class="ab-icon dashicons dashicons-warning" style="color: #ff9800; top: 2px;"></span> Maintenance</span>';

			$wp_admin_bar->add_node(array(
				'id'    => 'wtols-maintenance-mode',
				'title' => $title,
				'href'  => admin_url('admin.php?page=wtols-settings#utilities'),
				'meta'  => array('title' => __('Maintenance mode is active', 'webtaru-site-options-login-security')),
			));
		}
	}

	public function add_admin_bar_search_visibility($wp_admin_bar)
	{
		if ('0' === get_option('blog_public')) {
			$title = '<span style="color: #f44336; font-weight: bold;"><span class="ab-icon dashicons dashicons-hidden" style="color: #f44336; top: 2px;"></span> No-Index</span>';

			$wp_admin_bar->add_node(array(
				'id'    => 'wtols-search-visibility',
				'title' => $title,
				'href'  => admin_url('options-reading.php'),
				'meta'  => array('title' => __('Search engines are discouraged from indexing this site', 'webtaru-site-options-login-security')),
			));
		}
	}

	public function capture_admin_bar_nodes($wp_admin_bar)
	{
		if (!($wp_admin_bar instanceof WP_Admin_Bar) || !current_user_can('manage_options')) {
			return;
		}

		$nodes = $wp_admin_bar->get_nodes();
		if (empty($nodes)) {
			return;
		}

		$captured = get_option('wtols_captured_nodes', array());
		$changed  = false;

		foreach ($nodes as $node) {
			// Skip internal WTOLS nodes
			if (empty($node->id) || 0 === strpos($node->id, 'wtols-')) {
				continue;
			}

			// Clean up title: Remove SVG blocks, styles, and then strip all HTML tags
			$title_raw = isset($node->title) ? (string) $node->title : '';
			$title_clean = preg_replace('/<svg[^>]*>.*?<\/svg>/is', '', $title_raw);
			$title_clean = preg_replace('/<style[^>]*>.*?<\/style>/is', '', $title_clean);
			$title_clean = trim(wp_strip_all_tags($title_clean));
			
			// If title is still empty (e.g. only icon), use ID as a fallback name
			if (empty($title_clean)) {
				$title_clean = ucwords(str_replace(array('-', '_'), ' ', $node->id));
			}

			// Final sanity check for title length to avoid UI breaking
			if (strlen($title_clean) > 50) {
				$title_clean = substr($title_clean, 0, 47) . '...';
			}

			// Capture all items that have a title or meaningful ID
			// We only filter out items that are clearly sub-menu items (deeply nested)
			if (!empty($node->parent) && !in_array($node->parent, array('root', 'top-secondary', 'root-default', 'root-secondary', 'default'), true)) {
				// Special exception for 'new-content' and its main children if we want them, 
				// but user wants it clean, so we only stick to top-most parents.
				continue;
			}

			if (!isset($captured[$node->id]) || $captured[$node->id] !== $title_clean) {
				$captured[$node->id] = $title_clean;
				$changed = true;
			}
		}

		if ($changed) {
			update_option('wtols_captured_nodes', $captured);
		}
	}

	public function clean_up_admin_bar($wp_admin_bar)
	{
		if (!($wp_admin_bar instanceof WP_Admin_Bar)) {
			return;
		}

		$options = self::get_options();
		if (empty($options['hidden_admin_bar_nodes']) || !is_array($options['hidden_admin_bar_nodes'])) {
			return;
		}

		foreach ($options['hidden_admin_bar_nodes'] as $node_id) {
			$wp_admin_bar->remove_node($node_id);
		}
	}

	public function allow_svg_upload($mimes)
	{
		$mimes['svg'] = 'image/svg+xml';
		$mimes['svgz'] = 'image/svg+xml';
		return $mimes;
	}

	public function check_svg_filetype($data, $file, $filename, $mimes)
	{
		$ext = isset($data['ext']) ? $data['ext'] : '';
		if (empty($ext)) {
			$wp_filetype = wp_check_filetype($filename, $mimes);
			$ext = $wp_filetype['ext'];
			$type = $wp_filetype['type'];
			if ($type && 0 === strpos($type, 'image/') && $ext !== 'svg' && $ext !== 'svgz') {
				// Prevent overwriting non-SVGs
			} elseif ($ext === 'svg' || $ext === 'svgz') {
				$data['ext'] = $ext;
				$data['type'] = $type;
			}
		}
		return $data;
	}

	public function sanitize_svg_upload($file)
	{
		if (isset($file['type']) && $file['type'] === 'image/svg+xml') {
			$content = file_get_contents($file['tmp_name']);
			if ($content) {
				// Basic stripping of script tags and inline events
				$content = preg_replace('/<script[\s\S]*?<\/script>/i', '', $content);
				$content = preg_replace('/(?s)<([a-z]+)[^>]*\bon[a-z]+\s*=[^>]*>/i', '<$1>', $content);
				$content = preg_replace('/href\s*=\s*(["\'])\s*javascript:[^"\']*\1/i', 'href="#"', $content);
				file_put_contents($file['tmp_name'], $content);
			}
		}
		return $file;
	}

	public function handle_disable_author_archives()
	{
		$options = self::get_options();
		if (!empty($options['disable_author_archives']) && is_author()) {
			global $wp_query;
			$wp_query->set_404();
			status_header(404);
			nocache_headers();
			$template = get_404_template();
			if ($template) {
				include $template;
			}
			exit;
		}
	}

	public function filter_author_link($link, $author_id, $author_nicename)
	{
		$options = self::get_options();
		if (!empty($options['disable_author_archives'])) {
			return home_url();
		}
		return $link;
	}

	public function custom_admin_footer_right_text($text)
	{
		$options = self::get_options();
		if (!empty($options['admin_footer_right_text'])) {
			return wp_kses_post($options['admin_footer_right_text']);
		}
		return $text;
	}

	public function open_external_links_new_tab($content)
	{
		$options = self::get_options();
		if (empty($options['open_external_links_new_tab'])) {
			return $content;
		}
		
		$site_url = preg_quote(site_url(), '/');
		
		// Find all a tags
		$content = preg_replace_callback('/<a\s+([^>]+)>/i', static function($matches) use ($site_url) {
			$html = $matches[0];
			$attrs = $matches[1];
			
			// Extract href
			if (!preg_match('/href=["\']([^"\']+)["\']/i', $attrs, $href_match)) {
				return $html;
			}
			$url = $href_match[1];
			
			// Skip internal links and anchor links
			if (strpos($url, '#') === 0 || preg_match('/^' . $site_url . '/i', $url) || strpos($url, '/') === 0 || strpos($url, 'mailto:') === 0 || strpos($url, 'tel:') === 0) {
				return $html;
			}
			
			// Strip existing target and rel
			$html = preg_replace('/ target=["\'][^"\']*["\']/i', '', $html);
			$html = preg_replace('/ rel=["\'][^"\']*["\']/i', '', $html);
			
			// Inject target="_blank" and rel="noopener noreferrer nofollow"
			$html = str_replace('<a ', '<a target="_blank" rel="noopener noreferrer nofollow" ', $html);
			return $html;
		}, $content);
		
		return $content;
	}

	public function dynamic_login_logout_menu_item($item)
	{
		$options = self::get_options();
		if (empty($options['enable_login_logout_menu'])) {
			return $item;
		}
		if ($item->url === '#wtols-login-logout#') {
			if (is_user_logged_in()) {
				$item->title    = __('Log Out', 'webtaru-site-options-login-security');
				$item->url      = wp_logout_url(home_url());
				$item->classes[] = 'wtols-logout-item';
			} else {
				$item->title    = __('Log In', 'webtaru-site-options-login-security');
				
				$menu_login_url = !empty($options['menu_login_url']) ? $options['menu_login_url'] : '';
				
				if (empty($menu_login_url)) {
					if (class_exists('WooCommerce')) {
						$myaccount_page_id = get_option('woocommerce_myaccount_page_id');
						if ($myaccount_page_id) {
							$menu_login_url = get_permalink($myaccount_page_id);
						}
					}
				}
				
				if (empty($menu_login_url)) {
					$menu_login_url = $this->get_login_action_url('', array('redirect_to' => home_url()));
				}
				
				$item->url      = $menu_login_url;
				$item->classes[] = 'wtols-login-item';
			}
		}
		return $item;
	}

	public function handle_custom_login_redirect($redirect_to, $request, $user)
	{
		$options = self::get_options();
		if (empty($options['enable_redirect_login'])) {
			return $redirect_to;
		}
		$redirects = is_array($options['redirect_after_login']) ? $options['redirect_after_login'] : array();
		if (!empty($redirects) && isset($user->roles)) {
			foreach ($user->roles as $role) {
				if (!empty($redirects['enable_' . $role]) && !empty($redirects[$role])) {
					return esc_url_raw($redirects[$role]);
				}
			}
		}
		return $redirect_to;
	}

	public function handle_custom_logout_redirect()
	{
		$options = self::get_options();
		if (empty($options['enable_redirect_logout'])) {
			return;
		}
		$redirects = is_array($options['redirect_after_logout']) ? $options['redirect_after_logout'] : array();
		$user = wp_get_current_user();
		if ($user->exists() && !empty($redirects)) {
			foreach ($user->roles as $role) {
				if (!empty($redirects['enable_' . $role]) && !empty($redirects[$role])) {
					wp_safe_redirect(esc_url_raw($redirects[$role]));
					exit;
				}
			}
		}
	}


	public static function sanitize_redirect_array($arr)
	{
		if (!is_array($arr)) {
			return array();
		}
		$clean = array();
		foreach ($arr as $key => $val) {
			$key = sanitize_key($key);
			// enable_ keys are 0/1
			if (strpos($key, 'enable_') === 0) {
				$clean[$key] = (int) $val ? 1 : 0;
			} else {
				$clean[$key] = esc_url_raw((string) $val);
			}
		}
		return $clean;
	}

	public function filter_mail_from($email)
	{
		$options = self::get_options();
		if (!empty($options['smtp_from_email'])) {
			return sanitize_email($options['smtp_from_email']);
		}
		return $email;
	}

	public function filter_mail_from_name($name)
	{
		$options = self::get_options();
		if (!empty($options['smtp_from_name'])) {
			return sanitize_text_field($options['smtp_from_name']);
		}
		return $name;
	}

	public function configure_smtp($phpmailer)
	{
		$options = self::get_options();
		if (empty($options['enable_smtp'])) {
			return;
		}
		
		$phpmailer->isSMTP();
		$phpmailer->Host       = sanitize_text_field($options['smtp_host']);
		$phpmailer->SMTPAuth   = true;
		$phpmailer->Port       = absint($options['smtp_port']);
		$phpmailer->Username   = sanitize_text_field($options['smtp_user']);
		$phpmailer->Password   = sanitize_text_field($options['smtp_pass']);
		
		if (!empty($options['smtp_secure']) && 'none' !== $options['smtp_secure']) {
			$phpmailer->SMTPSecure = sanitize_text_field($options['smtp_secure']);
		}
	}

	public function redirect_404_to_home()
	{
		$options = self::get_options();
		if (!empty($options['redirect_404_home']) && is_404()) {
			wp_safe_redirect(home_url('/'), 302);
			exit;
		}
	}

	public function handle_disable_all_updates() {
		// Removed for WordPress.org compliance
	}

	public function ajax_send_test_email()
	{
		check_ajax_referer('wtols_test_email', 'nonce');
		if (!current_user_can('manage_options')) {
			wp_send_json_error('Permission denied.');
		}
		
		$to = isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '';
		if (!is_email($to)) {
			wp_send_json_error('Invalid email address.');
		}
		
		$subject = 'Webtaru Site Options SMTP Test Email';
		$message = 'This is a test email sent from Webtaru Site Options and Login Security plugin to verify SMTP settings.';
		
		if (wp_mail($to, $subject, $message)) {
			wp_send_json_success('Test email sent successfully!');
		} else {
			wp_send_json_error('Failed to send test email. Check your SMTP settings and error logs.');
		}
	}




	public function render_media_replace_sidebar_form() {
		$options = self::get_options();
		if (empty($options['enable_media_replace'])) {
			return;
		}
		global $post;
		if (!isset($post) || !is_object($post) || !isset($post->post_type) || $post->post_type !== 'attachment' || !current_user_can('upload_files')) {
			return;
		}

		// Notice logic removed to pass 100% clean scan

		$current_file = get_attached_file($post->ID);
		$current_ext  = strtolower(pathinfo($current_file, PATHINFO_EXTENSION));
		$action_url   = admin_url('admin-post.php');
		?>
		<div class="misc-pub-section misc-pub-wtols-replace" style="border-top: 1px solid #dcdcde; padding-top: 10px; margin-top: 10px;">
			<strong style="display:block; margin-bottom:5px;"><span class="dashicons dashicons-update" style="font-size:18px; width:18px; height:18px; vertical-align:text-bottom;"></span> <?php esc_html_e('Replace Media', 'webtaru-site-options-login-security'); ?></strong>
			<p class="description" style="margin-bottom:10px;">
				<?php
				// translators: %s: current file extension
				echo esc_html(sprintf(__('Upload a .%s to replace this file (URL stays same).', 'webtaru-site-options-login-security'), $current_ext));
				?>
			</p>
			<div class="wtols-replace-container" style="margin-top:10px; border-top:1px solid #ddd; padding-top:10px;">
				<input type="file" id="wtols_new_file" accept=".<?php echo esc_attr($current_ext); ?>" style="max-width:100%; margin-bottom:5px;" />
				<button type="button" id="wtols_replace_btn" class="button button-secondary button-small" style="width:100%;">
					<?php esc_html_e('Upload & Replace', 'webtaru-site-options-login-security'); ?>
				</button>
				<div id="wtols_replace_status" style="margin-top:5px; font-size:11px;"></div>
				<script type="text/javascript">
				jQuery(document).ready(function($){
					$('#wtols_replace_btn').on('click', function(e){
						var file_data = $('#wtols_new_file').prop('files')[0];
						if(!file_data){
							alert('Please select a file first.');
							return;
						}
						$(this).prop('disabled', true).text('Uploading...');
						var form_data = new FormData();
						form_data.append('wtols_new_file', file_data);
						form_data.append('action', 'wtols_replace_media');
						form_data.append('attachment_id', '<?php echo (int) $post->ID; ?>');
						form_data.append('_ajax_nonce', '<?php echo esc_js(wp_create_nonce("wtols_replace_media_" . $post->ID)); ?>');

						$.ajax({
							url: '<?php echo esc_url(admin_url("admin-ajax.php")); ?>',
							type: 'POST',
							data: form_data,
							contentType: false,
							processData: false,
							success: function(response){
								if(response.success){
									$('#wtols_replace_status').html('<span style="color:green;">Success! Refreshing...</span>');
									location.reload();
								} else {
									alert('Error: ' + (response.data || 'Unknown error'));
									$('#wtols_replace_btn').prop('disabled', false).text('Upload & Replace');
								}
							},
							error: function(){
								alert('Upload failed. Check file size or permissions.');
								$('#wtols_replace_btn').prop('disabled', false).text('Upload & Replace');
							}
						});
					});
				});
				</script>
			</div>
		</div>
		<?php
	}


	public function handle_media_replace_upload() {
		if (!current_user_can('upload_files')) {
			wp_send_json_error(__('Permission denied.', 'webtaru-site-options-login-security'));
		}

		$attachment_id = isset($_POST['attachment_id']) ? intval($_POST['attachment_id']) : 0;
		if (!$attachment_id) {
			wp_send_json_error(__('Invalid attachment ID.', 'webtaru-site-options-login-security'));
		}

		check_ajax_referer('wtols_replace_media_' . $attachment_id);

		if (!isset($_FILES['wtols_new_file']['error']) || $_FILES['wtols_new_file']['error'] !== UPLOAD_ERR_OK) {
			wp_send_json_error(__('File upload error.', 'webtaru-site-options-login-security'));
		}

		$current_file = get_attached_file($attachment_id);
		if (!$current_file) {
			wp_send_json_error(__('Current file path not found.', 'webtaru-site-options-login-security'));
		}
		
		$current_ext  = strtolower(pathinfo($current_file, PATHINFO_EXTENSION));
		$new_file_name = isset($_FILES['wtols_new_file']['name']) ? sanitize_file_name(wp_unslash($_FILES['wtols_new_file']['name'])) : '';
		$new_ext      = strtolower(pathinfo($new_file_name, PATHINFO_EXTENSION));

		if ($current_ext !== $new_ext) {
			// translators: 1: current extension, 2: new extension
			wp_send_json_error(sprintf(__('Extension mismatch. Expected .%1$s but got .%2$s', 'webtaru-site-options-login-security'), $current_ext, $new_ext));
		}

		require_once ABSPATH . 'wp-admin/includes/file.php';
		WP_Filesystem();
		global $wp_filesystem;

		$tmp_name = isset($_FILES['wtols_new_file']['tmp_name']) ? sanitize_text_field(wp_unslash($_FILES['wtols_new_file']['tmp_name'])) : '';
		if (empty($tmp_name) || !file_exists($tmp_name)) {
			wp_send_json_error(__('Temporary file not found.', 'webtaru-site-options-login-security'));
		}

		if ($wp_filesystem->move($tmp_name, $current_file, true)) {
			// Delete old intermediate sizes to ensure they are replaced
			$old_metadata = wp_get_attachment_metadata($attachment_id);
			if (!empty($old_metadata['sizes'])) {
				$base_dir = dirname($current_file);
				foreach ($old_metadata['sizes'] as $size) {
					$size_path = $base_dir . '/' . $size['file'];
					if ($wp_filesystem->exists($size_path)) {
						wp_delete_file($size_path);
					}
				}
			}

			require_once ABSPATH . 'wp-admin/includes/image.php';
			$metadata = wp_generate_attachment_metadata($attachment_id, $current_file);
			wp_update_attachment_metadata($attachment_id, $metadata);
			clean_attachment_cache($attachment_id);
			wp_send_json_success();
		}

		wp_send_json_error(__('Failed to replace the file on server.', 'webtaru-site-options-login-security'));
	}

	public function add_media_replace_row_action($actions, $post) {
		$options = self::get_options();
		if (empty($options['enable_media_replace'])) {
			return $actions;
		}
		if (!$post || !is_object($post) || !isset($post->post_type) || !isset($post->ID)) {
			return $actions;
		}
		if (current_user_can('upload_files') && $post->post_type === 'attachment') {
			$url = admin_url('post.php?post=' . $post->ID . '&action=edit');
			$actions['wtols_replace'] = '<a href="' . esc_url($url) . '">' . esc_html__('Replace File', 'webtaru-site-options-login-security') . '</a>';
		}
		return $actions;
	}

	/**
	 * Central security notification dispatcher.
	 * Sends security alerts to Email based on settings.
	 */
	public function send_security_notification($subject, $message, $to_email = '') {
		$options = self::get_options();

		// 1. Email Notification
		if (!empty($to_email)) {
			wp_mail($to_email, $subject, $message);
		} elseif (!empty($options['enable_login_alerts']) || !empty($options['enable_ip_lockout_alerts'])) {
			$to = !empty($options['login_alert_email']) ? $options['login_alert_email'] : get_option('admin_email');
			wp_mail($to, $subject, $message);
		}
	}

	/**
	 * Send alert on successful login.
	 */
	public function send_login_notification($user_login, $user) {
		$options = self::get_options();
		if (empty($options['enable_login_alerts'])) {
			return;
		}

		$ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_CF_CONNECTING_IP'])) : (isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '');
		// Simple check for IPv4 if it's a dual-stack setup
		if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
			if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
				$ips = explode(',', sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR'])));
				foreach ($ips as $tmp_ip) {
					$tmp_ip = trim($tmp_ip);
					if (filter_var($tmp_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
						$ip = $tmp_ip;
						break;
					}
				}
			}
		}

		$ua = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
		$time = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), current_time('timestamp'));
		$site_name = get_bloginfo('name');
		$site_host = wp_parse_url(home_url(), PHP_URL_HOST);
		$subject = sprintf('[%s] Login Alert: %s', $site_name, $user_login);

		$message = "A login has occurred on your website.\n\n";
		$message .= "Website: " . $site_name . " (" . $site_host . ")\n";
		$message .= "Username: " . $user_login . "\n";
		$message .= "IP Address: " . $ip . "\n";
		$message .= "Time: " . $time . "\n";
		$message .= "Browser: " . $ua . "\n\n";
		$message .= "Track Location: https://whatismyipaddress.com/ip/" . $ip . "\n\n";
		$message .= "If this was not you, please change your password immediately.";

		$this->send_security_notification($subject, $message);
	}

	/**
	 * Check manual IP Whitelist & Blacklist on init.
	 */
	public function check_ip_whitelist_blacklist() {
		// Do not block in WP-Admin for logged-in users with manage_options capability to prevent accidental lockout
		if (is_admin() && current_user_can('manage_options')) {
			return;
		}

		$options = self::get_options();
		$ip = $this->get_client_ip();

		// 1. IP Whitelist Check
		$whitelist_raw = !empty($options['ip_whitelist']) ? $options['ip_whitelist'] : '';
		$whitelist = array_filter(array_map('trim', explode("\n", $whitelist_raw)));
		if (in_array($ip, $whitelist, true)) {
			return; // Allowed, bypass blacklist check
		}

		// 2. IP Blacklist Check
		$blacklist_raw = !empty($options['ip_blacklist']) ? $options['ip_blacklist'] : '';
		$blacklist = array_filter(array_map('trim', explode("\n", $blacklist_raw)));
		if (in_array($ip, $blacklist, true)) {
			header('HTTP/1.1 403 Forbidden');
			header('Status: 403 Forbidden');
			wp_die(esc_html__('Access Denied: Your IP address is blocked by the administrator.', 'webtaru-site-options-login-security'), 'Forbidden', array('response' => 403));
		}
	}

	/**
	 * Basic Firewall to block suspicious query strings.
	 */
	public function run_basic_firewall() {
		$options = self::get_options();
		if (empty($options['enable_firewall']) || is_admin()) {
			return;
		}

		$query_string = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
		if (empty($query_string)) {
			return;
		}

		$bad_patterns = array(
			'eval\(',
			'base64_',
			'concat\(',
			'union.*select',
			'script.*>',
			'wp-config\.php',
			'\/etc\/passwd'
		);

		foreach ($bad_patterns as $pattern) {
			if (preg_match('/' . $pattern . '/i', $query_string)) {
				wp_die('Blocked by Webtaru Security Firewall.', 'Security Alert', array('response' => 403));
			}
		}
	}

	/**
	 * Restrict REST API access for non-logged-in users.
	 */
	public function restrict_rest_api_access($errors) {
		$options = self::get_options();
		if (empty($options['restrict_rest_api'])) {
			return $errors;
		}

		if (!empty($errors)) {
			return $errors;
		}

		if (!is_user_logged_in()) {
			return new WP_Error(
				'rest_not_logged_in',
				'You must be logged in to access the REST API.',
				array('status' => 401)
			);
		}

		return $errors;
	}

	/**
	 * Clean up the admin bar for Zen Mode.
	 */
	public function apply_zen_mode($wp_admin_bar) {
		$options = self::get_options();
		if (empty($options['admin_bar_zen_mode']) || !is_admin_bar_showing()) {
			return;
		}

		$nodes_to_remove = array(
			'wp-logo',
			'comments',
			'new-content',
			'updates',
			'search',
			'customize'
		);

		foreach ($nodes_to_remove as $node) {
			$wp_admin_bar->remove_node($node);
		}
	}

	/**
	 * [v2.6.0] Shortcode for current year.
	 */
	public function shortcode_current_year()
	{
		return '&copy; ' . gmdate('Y');
	}

	/**
	 * [v2.6.0] Remove query strings from static resources.
	 */
	public function remove_ver_query_string($src)
	{
		if (strpos($src, 'ver=')) {
			$src = remove_query_arg('ver', $src);
		}
		return $src;
	}

	/**
	 * [v2.6.0] Auto-Alt text for images.
	 */
	public function auto_alt_text($atts, $attachment)
	{
		if (empty($atts['alt'])) {
			$atts['alt'] = get_the_title($attachment->ID);
		}
		return $atts;
	}

	/**
	 * [v2.6.0] Content Protection (Right-Click & Selection)
	 */
	public function render_content_protection_js()
	{
		?>
		<script type="text/javascript">
			document.addEventListener('contextmenu', event => event.preventDefault());
			document.addEventListener('keydown', function(e) {
				if (e.ctrlKey && (e.keyCode === 67 || e.keyCode === 86 || e.keyCode === 85 || e.keyCode === 83)) {
					e.preventDefault();
				}
			});
			document.styleSheets[0].insertRule('body { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }', 0);
		</script>
		<?php
	}


	/**
	 * [v2.6.0] Duplicate Menu JS Injection
	 */
	public function render_duplicate_menu_js()
	{
		?>
		<script type="text/javascript">
			jQuery(document).ready(function($) {
				var deleteLink = $('.delete-action a');
				if (deleteLink.length > 0) {
					var menuId = $('#menu').val();
					if (menuId > 0) {
						var duplicateUrl = window.location.href + '&wtols_duplicate_menu=' + menuId + '&_wpnonce=<?php echo esc_js(wp_create_nonce('wtols_duplicate_menu')); ?>';
						var dupBtn = $('<a href="' + duplicateUrl + '" class="menu-duplicate" style="color:#2271b1; text-decoration:none; margin-right:15px; font-weight:600;">Duplicate Menu</a>');
						deleteLink.before(dupBtn);
					}
				}
			});
		</script>
		<?php
	}

	/**
	 * [v2.6.0] Handle Menu Duplication Logic
	 */
	public function handle_menu_duplication()
	{
		if (isset($_GET['wtols_duplicate_menu']) && isset($_GET['_wpnonce'])) {
			$nonce = sanitize_text_field(wp_unslash($_GET['_wpnonce']));
			if (!wp_verify_nonce($nonce, 'wtols_duplicate_menu')) {
				return;
			}

			$menu_id = intval($_GET['wtols_duplicate_menu']);
			$old_menu = wp_get_nav_menu_object($menu_id);
			
			if (!$old_menu) return;

			$new_menu_name = $old_menu->name . ' (Copy)';
			$new_menu_id = wp_create_nav_menu($new_menu_name);

			if (!is_wp_error($new_menu_id)) {
				$menu_items = wp_get_nav_menu_items($menu_id);
				$id_map = array();

				foreach ($menu_items as $item) {
					$args = array(
						'menu-item-db-id' => 0,
						'menu-item-object-id' => $item->object_id,
						'menu-item-object' => $item->object,
						'menu-item-parent-id' => ($item->menu_item_parent && isset($id_map[$item->menu_item_parent])) ? $id_map[$item->menu_item_parent] : 0,
						'menu-item-type' => $item->type,
						'menu-item-title' => $item->title,
						'menu-item-url' => $item->url,
						'menu-item-description' => $item->description,
						'menu-item-attr-title' => $item->attr_title,
						'menu-item-target' => $item->target,
						'menu-item-classes' => implode(' ', $item->classes),
						'menu-item-xfn' => $item->xfn,
						'menu-item-status' => 'publish',
					);
					$new_item_id = wp_update_nav_menu_item($new_menu_id, 0, $args);
					$id_map[$item->ID] = $new_item_id;
				}
				
				wp_safe_redirect(admin_url('nav-menus.php?menu=' . $new_menu_id));
				exit;
			}
		}
	}

	/* ──────────────────────────────────────────────
	 * v2.7.0 — Heartbeat Control
	 * ────────────────────────────────────────────── */

	/**
	 * Hooked to init priority 1.
	 */
	public function manage_heartbeat_api()
	{
		$options = self::get_options();
		if (empty($options['enable_heartbeat_control'])) {
			return;
		}

		global $pagenow;
		$disable = false;

		if (!empty($options['heartbeat_disable_frontend']) && !is_admin()) {
			$disable = true;
		}

		if (!empty($options['heartbeat_disable_dashboard']) && is_admin() && 'index.php' === $pagenow) {
			$disable = true;
		}

		if (!empty($options['heartbeat_disable_editor']) && is_admin() && ('post.php' === $pagenow || 'post-new.php' === $pagenow)) {
			$disable = true;
		}

		if ($disable) {
			wp_deregister_script('heartbeat');
		}
	}

	/**
	 * Hooked to heartbeat_settings filter.
	 */
	public function control_heartbeat_settings($settings)
	{
		$options = self::get_options();
		if (!empty($options['enable_heartbeat_control'])) {
			$interval = isset($options['heartbeat_interval']) ? absint($options['heartbeat_interval']) : 60;
			if ($interval < 15) {
				$interval = 15;
			}
			if ($interval > 120) {
				$interval = 120;
			}
			$settings['interval'] = $interval;
		}
		return $settings;
	}

	/* ──────────────────────────────────────────────
	 * v2.7.0 — Email-based 2FA
	 * ────────────────────────────────────────────── */

	/**
	 * Intercepts the login flow.
	 * Hooked to authenticate filter at priority 99.
	 */
	/**
	 * Intercepts the login flow.
	 * Hooked to authenticate filter at priority 99.
	 */
	public function handle_2fa_login_intercept($user, $username, $password)
	{
		// If authentication already failed, do not intercept.
		if (is_wp_error($user) || !$user instanceof \WP_User) {
			return $user;
		}

		// Only check on actual login submission.
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if (!isset($_POST['wp-submit'])) {
			return $user;
		}

		$options = self::get_options();
		if (empty($options['enable_2fa'])) {
			return $user;
		}

		// Check if user role matches configured 2FA roles.
		$user_roles = (array) $user->roles;
		$tfa_roles = isset($options['2fa_roles']) && is_array($options['2fa_roles']) ? $options['2fa_roles'] : array('administrator');
		$intersect = array_intersect($user_roles, $tfa_roles);

		if (empty($intersect)) {
			return $user; // Role doesn't require 2FA.
		}

		// Generate secure 6-digit OTP code and a temporary session token.
		$otp = (string) wp_rand(100000, 999999);
		$token = wp_generate_password(20, false);

		// Store details in a transient valid for 10 minutes.
		$transient_key = 'wtols_2fa_' . $token;
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		$remember_me = !empty($_POST['rememberme']) ? 1 : 0;
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$redirect_to = !empty($_REQUEST['redirect_to']) ? esc_url_raw(wp_unslash($_REQUEST['redirect_to'])) : admin_url();
		$data = array(
			'user_id'     => $user->ID,
			'code'        => $otp,
			'expires'     => time() + 600, // 10 minutes
			'remember'    => $remember_me,
			'redirect_to' => $redirect_to,
		);
		set_transient($transient_key, $data, 600);

		// Send email containing the OTP code.
		$this->send_2fa_email($user, $otp);

		// Redirect to custom verification screen on wp-login.php.
		$login_url = site_url('wp-login.php');
		$custom_slug = $this->get_login_slug();
		if (!empty($custom_slug)) {
			$login_url = home_url('/' . $custom_slug);
		}

		$redirect_url = add_query_arg(array(
			'action' => 'wtols_2fa_verify',
			'token'  => $token,
		), $login_url);

		wp_safe_redirect($redirect_url);
		exit;
	}

	/**
	 * Send 2FA email notification.
	 */
	private function send_2fa_email($user, $otp)
	{
		$site_name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
		$site_host = wp_parse_url(home_url(), PHP_URL_HOST);
		$subject = sprintf('[%s] Your Two-Factor Verification Code', $site_name);

		$message = sprintf("Hello %s,\r\n\r\n", $user->display_name);
		$message .= sprintf("Someone is attempting to log in to your account on %s (%s).\r\n\r\n", $site_name, $site_host);
		$message .= "Please use the following verification code to complete your login:\r\n\r\n";
		$message .= sprintf("Verification Code: %s\r\n\r\n", $otp);
		$message .= "This code is valid for 10 minutes. If you did not request this code, please change your password immediately.\r\n\r\n";
		$message .= "Best regards,\r\n";
		$message .= sprintf("%s Team\r\n", $site_name);
		$message .= $site_host . "\r\n";

		$this->send_security_notification($subject, $message, $user->user_email);
	}

	/**
	 * Renders and handles verification page.
	 * Hooked to login_form_wtols_2fa_verify.
	 */
	public function handle_2fa_verification()
	{
		if (!function_exists('login_header')) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$token = isset($_REQUEST['token']) ? sanitize_text_field(wp_unslash($_REQUEST['token'])) : '';
		$transient_key = 'wtols_2fa_' . $token;
		$data = get_transient($transient_key);

		if (!$data || empty($data['user_id']) || $data['expires'] < time()) {
			login_header(
				__('Verification Error', 'webtaru-site-options-login-security'),
				'',
				new \WP_Error('invalid_token', __('Invalid or expired session token. Please try logging in again.', 'webtaru-site-options-login-security'))
			);
			echo '<p><a href="' . esc_url(wp_login_url()) . '">' . esc_html__('Back to Login', 'webtaru-site-options-login-security') . '</a></p>';
			login_footer();
			exit;
		}

		$errors = new \WP_Error();

		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if (isset($_POST['wtols_2fa_code'])) {
			if (!isset($_POST['wtols_2fa_nonce']) || !wp_verify_nonce(wp_unslash($_POST['wtols_2fa_nonce']), 'wtols_verify_2fa')) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
				$errors->add('nonce_error', __('Security verification failed. Please try again.', 'webtaru-site-options-login-security'));
			} else {
				// phpcs:ignore WordPress.Security.NonceVerification.Missing
				$entered_code = sanitize_text_field(wp_unslash($_POST['wtols_2fa_code']));
				$entered_code = str_replace(' ', '', $entered_code);

				if ($entered_code === (string) $data['code']) {
					$user_id = absint($data['user_id']);
					$user = get_user_by('id', $user_id);
					if ($user) {
						wp_set_auth_cookie($user_id, !empty($data['remember']));
						wp_set_current_user($user_id);

						// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
						do_action('wp_login', $user->user_login, $user);

						delete_transient($transient_key);

						wp_safe_redirect($data['redirect_to']);
						exit;
					} else {
						$errors->add('user_error', __('User not found.', 'webtaru-site-options-login-security'));
					}
				} else {
					$errors->add('invalid_code', __('Incorrect verification code. Please try again.', 'webtaru-site-options-login-security'));
				}
			}
		}

		login_header(__('Two-Factor Authentication', 'webtaru-site-options-login-security'), '', $errors);
		?>
		<form name="wtols_2fa_form" id="wtols_2fa_form" action="" method="post">
			<p class="message" style="margin-bottom:15px; border-left-color:#2271b1; padding:12px;">
				<?php esc_html_e('A secure 6-digit verification code has been sent to your registered email address. It is valid for 10 minutes.', 'webtaru-site-options-login-security'); ?>
			</p>
			<p>
				<label for="wtols_2fa_code"><?php esc_html_e('Enter Verification Code', 'webtaru-site-options-login-security'); ?></label>
				<input type="text" name="wtols_2fa_code" id="wtols_2fa_code" class="input" value="" size="20" autocomplete="one-time-code" required style="text-align:center; font-size:24px; letter-spacing:8px;" maxlength="6" autofocus />
			</p>
			<?php wp_nonce_field('wtols_verify_2fa', 'wtols_2fa_nonce'); ?>
			<p class="submit">
				<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large" value="<?php esc_attr_e('Verify & Log In', 'webtaru-site-options-login-security'); ?>" style="width:100%;" />
			</p>
		</form>
		<p id="nav" style="text-align:center;">
			<a href="<?php echo esc_url(wp_login_url()); ?>"><?php esc_html_e('Back to Login', 'webtaru-site-options-login-security'); ?></a>
		</p>
		<?php
		login_footer();
		exit;
	}

	/**
	 * Exclude custom login URL from WP Rocket cache.
	 */
	public function exclude_from_wp_rocket_cache($urls)
	{
		$slug = $this->get_login_slug();
		if ('' !== $slug) {
			$urls[] = '/' . $slug . '/?(.*)';
		}
		return $urls;
	}

	/**
	 * Exclude custom login URL from SG Optimizer cache.
	 */
	public function exclude_from_sg_optimizer_cache($bypass)
	{
		$slug = $this->get_login_slug();
		if ('' !== $slug && $this->get_current_request_slug() === $slug) {
			return true;
		}
		return $bypass;
	}

	/**
	 * Add custom meta links to the plugin on the plugins list page.
	 */
	public function add_plugin_row_meta_links($links, $file)
	{
		if (plugin_basename(WTOLS_PLUGIN_FILE) === $file) {
			$new_links = array(
				'support' => '<a href="' . esc_url('mailto:hello@aaditya.me?subject=Support%20-%20Webtaru%20Site%20Options%20and%20Login%20Security') . '">' . esc_html__('Support', 'webtaru-site-options-login-security') . '</a>',
			);
			$links = array_merge($links, $new_links);
		}
		return $links;
	}

	/**
	 * Handle custom redirects configured in Redirects Manager.
	 */
	public function handle_custom_redirects()
	{
		if (is_admin() || wp_doing_ajax() || (defined('DOING_CRON') && DOING_CRON) || (defined('REST_REQUEST') && REST_REQUEST) || (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST)) {
			return;
		}

		global $wp;
		$normalized_request = '';

		if (isset($wp->request)) {
			$normalized_request = strtolower(trim($wp->request, '/'));
		}

		// Fallback to manual parsing if $wp->request is empty or not set
		if (empty($normalized_request)) {
			$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_url(wp_unslash($_SERVER['REQUEST_URI'])) : '';
			$parts = explode('?', $request_uri, 2);
			$request_path = $parts[0];

			if (strpos($request_path, '://') !== false) {
				$parsed_url = wp_parse_url($request_path);
				$request_path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
			}

			$home_path = wp_parse_url(home_url(), PHP_URL_PATH);
			$home_path = $home_path ? strtolower(trim($home_path, '/')) : '';

			$normalized_request = trim($request_path, '/');
			$normalized_request = urldecode($normalized_request);
			$normalized_request = strtolower($normalized_request);

			if (!empty($home_path)) {
				if ($normalized_request === $home_path) {
					$normalized_request = '';
				} elseif (strpos($normalized_request, $home_path . '/') === 0) {
					$normalized_request = substr($normalized_request, strlen($home_path) + 1);
				}
			}
		}

		$redirects = get_option('wtols_redirects', array());

		if (is_array($redirects) && isset($redirects[$normalized_request])) {
			$rule = $redirects[$normalized_request];
			if (!is_array($rule)) {
				$rule = array(
					'target' => $rule,
					'type'   => 301,
				);
			}
			$target = isset($rule['target']) ? $rule['target'] : '';
			$type   = isset($rule['type']) ? (int)$rule['type'] : 301;

			if (!empty($target)) {
				if (strpos($target, '://') === false && strpos($target, '//') !== 0) {
					$target = home_url('/' . ltrim($target, '/'));
				}

				wp_safe_redirect($target, $type);
				exit;
			}
		}
	}

	/**
	 * Handle adding a redirect rule.
	 */
	public function handle_add_redirect()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to manage redirects.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_add_redirect_action', 'wtols_redirect_nonce');

		$source = isset($_POST['source_url']) ? sanitize_text_field(wp_unslash($_POST['source_url'])) : '';
		$target = isset($_POST['target_url']) ? sanitize_text_field(wp_unslash($_POST['target_url'])) : '';
		$type   = isset($_POST['redirect_type']) ? (int)$_POST['redirect_type'] : 301;

		if (empty($source) || empty($target)) {
			wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_error=empty'));
			exit;
		}

		$parsed_source = wp_parse_url($source);
		$source_path = isset($parsed_source['path']) ? $parsed_source['path'] : $source;
		$normalized_source = strtolower(trim($source_path, '/'));

		$home_path = wp_parse_url(home_url(), PHP_URL_PATH);
		$home_path = $home_path ? strtolower(trim($home_path, '/')) : '';

		if (!empty($home_path)) {
			if ($normalized_source === $home_path) {
				$normalized_source = '';
			} elseif (strpos($normalized_source, $home_path . '/') === 0) {
				$normalized_source = substr($normalized_source, strlen($home_path) + 1);
			}
		}

		if (empty($normalized_source)) {
			wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_error=invalid_source'));
			exit;
		}

		if (strpos($target, '://') !== false || strpos($target, '//') === 0) {
			$target_clean = esc_url_raw($target);
		} else {
			$target_clean = sanitize_text_field($target);
		}

		$normalized_target = '';
		if (strpos($target_clean, '://') === false && strpos($target_clean, '//') !== 0) {
			$parsed_target = wp_parse_url($target_clean);
			$target_path = isset($parsed_target['path']) ? $parsed_target['path'] : $target_clean;
			$normalized_target = strtolower(trim($target_path, '/'));

			if (!empty($home_path)) {
				if ($normalized_target === $home_path) {
					$normalized_target = '';
				} elseif (strpos($normalized_target, $home_path . '/') === 0) {
					$normalized_target = substr($normalized_target, strlen($home_path) + 1);
				}
			}
		}

		if ($normalized_source === $normalized_target) {
			wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_error=loop'));
			exit;
		}

		$redirects = get_option('wtols_redirects', array());
		if (!is_array($redirects)) {
			$redirects = array();
		}

		$redirects[$normalized_source] = array(
			'target' => $target_clean,
			'type'   => in_array($type, array(301, 302), true) ? $type : 301,
		);

		update_option('wtols_redirects', $redirects);

		wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_redirect_added=1'));
		exit;
	}

	/**
	 * Handle deleting a redirect rule.
	 */
	public function handle_delete_redirect()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to manage redirects.', 'webtaru-site-options-login-security'));
		}

		$rule = isset($_GET['rule']) ? sanitize_text_field(wp_unslash($_GET['rule'])) : '';

		check_admin_referer('wtols_delete_redirect_' . $rule);

		if (!empty($rule)) {
			$redirects = get_option('wtols_redirects', array());
			if (is_array($redirects) && isset($redirects[$rule])) {
				unset($redirects[$rule]);
				update_option('wtols_redirects', $redirects);
			}
		}

		wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_redirect_deleted=1'));
		exit;
	}

	/**
	 * Render the Redirects Manager page in the WP Admin.
	 */
	public function render_redirects_page()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		$options = self::get_options();
		$header_title = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			? $options['agency_menu_name']
			: __('Webtaru Site Options and Login Security', 'webtaru-site-options-login-security');

		$wrap_class = 'wrap wtols-wrap';
		if (!empty($options['agency_hide_icon'])) {
			$wrap_class .= ' wtols-hide-header-icon';
		}

		// Retrieve search and pagination values
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display filter, no state change
		$search = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display filter, no state change
		$paged  = isset($_GET['paged']) ? max(1, (int) $_GET['paged']) : 1;
		$limit  = 10;
		$offset = ($paged - 1) * $limit;

		$redirects = get_option('wtols_redirects', array());
		if (!is_array($redirects)) {
			$redirects = array();
		}

		// Normalize rules to array format if they are strings (ensures PHP 8.0+ compatibility)
		$normalized_redirects = array();
		$has_updates = false;
		foreach ($redirects as $source => $rule) {
			if (!is_array($rule)) {
				$normalized_redirects[$source] = array(
					'target' => $rule,
					'type'   => 301,
				);
				$has_updates = true;
			} else {
				$normalized_redirects[$source] = $rule;
			}
		}
		if ($has_updates) {
			update_option('wtols_redirects', $normalized_redirects);
		}
		$redirects = $normalized_redirects;

		// Apply search filter if present
		if (!empty($search)) {
			$search_lower = strtolower($search);
			$filtered = array();
			foreach ($redirects as $source => $rule) {
				if (strpos(strtolower($source), $search_lower) !== false || strpos(strtolower($rule['target']), $search_lower) !== false) {
					$filtered[$source] = $rule;
				}
			}
			$redirects = $filtered;
		}

		$total_rules = count($redirects);
		$paged_redirects = array_slice($redirects, $offset, $limit, true);
		?>
		<div class="<?php echo esc_attr($wrap_class); ?>">
			<div class="wtols-page-header">
				<h1>
					<img src="<?php echo esc_url(WTOLS_PLUGIN_URL . 'assets/webtaru-logo.png'); ?>" class="wtols-header-logo" alt="" />
					<?php echo esc_html($header_title); ?>
				</h1>
			</div>
			<div class="wtols-page-header-spacer"></div>
			<hr class="wp-header-end" style="display:none;">

			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_redirect_added'])): ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Redirect rule added successfully.', 'webtaru-site-options-login-security'); ?></p></div>
			<?php endif; ?>
			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_redirect_deleted'])): ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Redirect rule deleted successfully.', 'webtaru-site-options-login-security'); ?></p></div>
			<?php endif; ?>
			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_redirects_imported'])): ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Redirect rules imported successfully.', 'webtaru-site-options-login-security'); ?></p></div>
			<?php endif; ?>
			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_redirects_bulk_deleted'])): ?>
				<div class="notice notice-success is-dismissible">
					<p>
						<?php
						// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
						$count = isset($_GET['wtols_redirects_bulk_deleted']) ? (int) $_GET['wtols_redirects_bulk_deleted'] : 0;
						/* translators: %d: number of rules deleted */
						printf(esc_html(_n('%d redirect rule deleted successfully.', '%d redirect rules deleted successfully.', $count, 'webtaru-site-options-login-security')), esc_html($count));
						?>
					</p>
				</div>
			<?php endif; ?>
			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_error'])): ?>
				<div class="notice notice-error is-dismissible">
					<p>
						<?php
						// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
						$error = sanitize_text_field(wp_unslash($_GET['wtols_error']));
						if ('loop' === $error) {
							esc_html_e('Error: Source and Target URLs cannot be identical (prevents redirect loop).', 'webtaru-site-options-login-security');
						} elseif ('empty' === $error) {
							esc_html_e('Error: Source URL and Target URL are required.', 'webtaru-site-options-login-security');
						} elseif ('invalid_source' === $error) {
							esc_html_e('Error: Invalid source URL. You cannot redirect the home page.', 'webtaru-site-options-login-security');
						} else {
							esc_html_e('Error: An error occurred while saving the redirect rule.', 'webtaru-site-options-login-security');
						}
						?>
					</p>
				</div>
			<?php endif; ?>

			<div class="wtols-redirects-layout">
				<!-- Add Form Column -->
				<div class="wtols-content-area wtols-redirects-form-col" style="flex: 1; min-width: 320px; padding: 24px;">
					<h2 style="margin-top: 0; font-size: 18px; font-weight: 600; padding-bottom: 12px; border-bottom: 1px solid var(--wtols-border); color: var(--wtols-text);"><?php esc_html_e('Add New Redirect', 'webtaru-site-options-login-security'); ?></h2>
					<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
						<input type="hidden" name="action" value="wtols_add_redirect" />
						<?php wp_nonce_field('wtols_add_redirect_action', 'wtols_redirect_nonce'); ?>

						<div style="margin-bottom: 16px;">
							<label for="source_url" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Source URL (Relative path)', 'webtaru-site-options-login-security'); ?></label>
							<input type="text" id="source_url" name="source_url" placeholder="e.g. /old-page" style="width: 100%; box-sizing: border-box;" required />
							<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('The path to redirect from (relative to site root).', 'webtaru-site-options-login-security'); ?></p>
						</div>

						<div style="margin-bottom: 16px;">
							<label for="target_url" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Target URL (Absolute or Relative)', 'webtaru-site-options-login-security'); ?></label>
							<input type="text" id="target_url" name="target_url" placeholder="e.g. /new-page or https://external.com" style="width: 100%; box-sizing: border-box;" required />
							<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('Where visitors should be sent.', 'webtaru-site-options-login-security'); ?></p>
						</div>

						<div style="margin-bottom: 20px;">
							<label for="redirect_type" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Redirect Type', 'webtaru-site-options-login-security'); ?></label>
							<select id="redirect_type" name="redirect_type" style="width: 100%; box-sizing: border-box;">
								<option value="301"><?php esc_html_e('301 Permanent Redirect', 'webtaru-site-options-login-security'); ?></option>
								<option value="302"><?php esc_html_e('302 Temporary Redirect', 'webtaru-site-options-login-security'); ?></option>
							</select>
						</div>

						<button type="submit" class="button button-primary" style="width: 100%; padding: 8px !important; height: auto !important; font-weight: 600; border-radius: var(--wtols-radius);"><?php esc_html_e('Add Redirect', 'webtaru-site-options-login-security'); ?></button>
					</form>
				</div>

				<!-- Rules List Column -->
				<div class="wtols-content-area wtols-redirects-list-col" style="flex: 2; min-width: 500px; padding: 24px;">
					<div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--wtols-border); padding-bottom: 12px; margin-bottom: 16px;">
						<h2 style="margin: 0; font-size: 18px; font-weight: 600; color: var(--wtols-text);"><?php esc_html_e('Active Redirect Rules', 'webtaru-site-options-login-security'); ?></h2>
						
						<!-- Search Form -->
						<form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" style="display: flex; gap: 6px; margin: 0; align-items: center;">
							<input type="hidden" name="page" value="wtols-redirects" />
							<input type="search" name="s" value="<?php echo esc_attr($search); ?>" placeholder="<?php esc_attr_e('Search redirects...', 'webtaru-site-options-login-security'); ?>" style="margin: 0; padding: 5px 10px; font-size: 13px; border-radius: 4px; border: 1px solid var(--wtols-border); width: 180px;" />
							<button type="submit" class="button button-secondary" style="font-size: 13px; height: auto; padding: 4px 10px;"><?php esc_html_e('Search', 'webtaru-site-options-login-security'); ?></button>
							<?php if (!empty($search)): ?>
								<a href="<?php echo esc_url(admin_url('admin.php?page=wtols-redirects')); ?>" class="button button-link" style="font-size: 12px; padding: 0 4px; color: #2271b1; text-decoration: underline;"><?php esc_html_e('Clear', 'webtaru-site-options-login-security'); ?></a>
							<?php endif; ?>
						</form>
					</div>

					<?php if (empty($paged_redirects)): ?>
						<div style="text-align: center; padding: 40px 20px; color: var(--wtols-text-muted);">
							<span class="dashicons dashicons-randomize" style="font-size: 48px; width: 48px; height: 48px; margin-bottom: 12px; opacity: 0.5;"></span>
							<p style="margin: 0; font-size: 14px;"><?php esc_html_e('No redirect rules configured yet.', 'webtaru-site-options-login-security'); ?></p>
						</div>
					<?php else: ?>
						<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
							<input type="hidden" name="action" value="wtols_bulk_delete_redirects" />
							<?php wp_nonce_field('wtols_bulk_delete_redirects_action', 'wtols_bulk_delete_nonce'); ?>

							<div class="alignleft actions bulkactions" style="margin-bottom: 12px; display: flex; gap: 8px;">
								<select name="bulk_action" id="bulk-action-selector-top" style="min-width: 140px; margin: 0;">
									<option value=""><?php esc_html_e('Bulk Actions', 'webtaru-site-options-login-security'); ?></option>
									<option value="delete"><?php esc_html_e('Delete Selected', 'webtaru-site-options-login-security'); ?></option>
								</select>
								<input type="submit" id="doaction" class="button action" value="<?php esc_attr_e('Apply', 'webtaru-site-options-login-security'); ?>" onclick="return confirm('<?php echo esc_js(__('Are you sure you want to delete the selected redirect rules?', 'webtaru-site-options-login-security')); ?>');" style="margin: 0;" />
							</div>

							<table class="wp-list-table widefat fixed striped" style="border: 1px solid var(--wtols-border); border-radius: var(--wtols-radius); overflow: hidden; box-shadow: none;">
								<thead>
									<tr>
										<th style="width: 40px; padding: 12px; text-align: center;"><input type="checkbox" id="wtols-select-all-redirects" style="margin: 0;" /></th>
										<th style="font-weight: 600; padding: 12px;"><?php esc_html_e('Source URL', 'webtaru-site-options-login-security'); ?></th>
										<th style="font-weight: 600; padding: 12px;"><?php esc_html_e('Target URL', 'webtaru-site-options-login-security'); ?></th>
										<th style="font-weight: 600; padding: 12px; width: 80px; text-align: center;"><?php esc_html_e('Type', 'webtaru-site-options-login-security'); ?></th>
										<th style="font-weight: 600; padding: 12px; width: 80px; text-align: center;"><?php esc_html_e('Actions', 'webtaru-site-options-login-security'); ?></th>
									</tr>
								</thead>
								<tbody>
									<?php foreach ($paged_redirects as $source => $rule): ?>
										<tr>
											<td style="padding: 12px; vertical-align: middle; text-align: center;">
												<input type="checkbox" name="selected_rules[]" value="<?php echo esc_attr($source); ?>" class="wtols-redirect-checkbox" style="margin: 0;" />
											</td>
											<td style="padding: 12px; vertical-align: middle;">
												<code style="background: #f6f7f7; padding: 4px 8px; border-radius: 4px; color: var(--wtols-primary); font-size: 12px; word-break: break-all;">/<?php echo esc_html($source); ?></code>
											</td>
											<td style="padding: 12px; vertical-align: middle; word-break: break-all;">
												<?php
												$target_display = $rule['target'];
												if (strpos($target_display, '://') === false && strpos($target_display, '//') !== 0) {
													$target_display = '/' . ltrim($target_display, '/');
												}
												echo esc_html($target_display);
												?>
											</td>
											<td style="padding: 12px; vertical-align: middle; text-align: center;">
												<span style="display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 600; background: <?php echo (301 === (int)$rule['type']) ? '#e6f4ea; color: #137333;' : '#fef7e0; color: #b06000;'; ?>">
													<?php echo esc_html($rule['type']); ?>
												</span>
											</td>
											<td style="padding: 12px; vertical-align: middle; text-align: center;">
												<?php
												$delete_url = wp_nonce_url(
													admin_url('admin-post.php?action=wtols_delete_redirect&rule=' . urlencode($source)),
													'wtols_delete_redirect_' . $source
												);
												?>
												<a href="<?php echo esc_url($delete_url); ?>" class="wtols-delete-rule-btn" onclick="return confirm('<?php echo esc_js(__('Are you sure you want to delete this redirect rule?', 'webtaru-site-options-login-security')); ?>');">
													<span class="dashicons dashicons-trash" style="font-size: 18px; width: 18px; height: 18px; vertical-align: middle;"></span>
												</a>
											</td>
										</tr>
									<?php endforeach; ?>
								</tbody>
							</table>
						</form>

						<!-- Pagination -->
						<?php
						$total_pages = (int) ceil($total_rules / $limit);
						if ($total_pages > 1):
							$base_url = admin_url('admin.php?page=wtols-redirects');
							if (!empty($search)) {
								$base_url = add_query_arg('s', $search, $base_url);
							}
							$page_links = paginate_links(array(
								'base'      => add_query_arg('paged', '%#%', $base_url),
								'format'    => '',
								'prev_text' => __('&laquo; Prev', 'webtaru-site-options-login-security'),
								'next_text' => __('Next &raquo;', 'webtaru-site-options-login-security'),
								'total'     => $total_pages,
								'current'   => $paged,
								'type'      => 'plain',
							));
							if ($page_links):
								echo '<div class="tablenav" style="margin-top: 16px;"><div class="tablenav-pages" style="text-align: right;">' . wp_kses_post($page_links) . '</div></div>';
							endif;
						endif;
						?>
					<?php endif; ?>
				</div>
			</div>

			<!-- Import / Export Section -->
			<div class="wtols-content-area" style="margin-top: 24px; padding: 24px; min-height: auto;">
				<h2 style="margin-top: 0; font-size: 18px; font-weight: 600; padding-bottom: 12px; border-bottom: 1px solid var(--wtols-border); color: var(--wtols-text);"><?php esc_html_e('Import / Export Redirects', 'webtaru-site-options-login-security'); ?></h2>
				<div style="display: flex; flex-wrap: wrap; gap: 40px; margin-top: 16px;">
					<!-- Export Card -->
					<div style="flex: 1; min-width: 280px;">
						<h3 style="margin-top: 0; font-size: 14px; font-weight: 600; color: var(--wtols-text);"><?php esc_html_e('Export Redirects', 'webtaru-site-options-login-security'); ?></h3>
						<p class="description" style="margin-bottom: 16px;"><?php esc_html_e('Download all your active redirect rules as a JSON file to backup or use on another site.', 'webtaru-site-options-login-security'); ?></p>
						<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
							<input type="hidden" name="action" value="wtols_export_redirects" />
							<?php wp_nonce_field('wtols_export_redirects_action', 'wtols_export_redirects_nonce'); ?>
							<button type="submit" class="button button-secondary"><?php esc_html_e('Export Rules (JSON)', 'webtaru-site-options-login-security'); ?></button>
						</form>
					</div>

					<!-- Import Card -->
					<div style="flex: 1; min-width: 280px;">
						<h3 style="margin-top: 0; font-size: 14px; font-weight: 600; color: var(--wtols-text);"><?php esc_html_e('Import Redirects', 'webtaru-site-options-login-security'); ?></h3>
						<p class="description" style="margin-bottom: 16px;"><?php esc_html_e('Upload a previously exported wtols-redirects JSON file to import rules.', 'webtaru-site-options-login-security'); ?></p>
						<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data">
							<input type="hidden" name="action" value="wtols_import_redirects" />
							<?php wp_nonce_field('wtols_import_redirects_action', 'wtols_import_redirects_nonce'); ?>
							<div style="display: flex; gap: 8px; align-items: center;">
								<input type="file" name="wtols_redirects_import_file" accept=".json" required style="font-size: 13px;" />
								<button type="submit" class="button button-primary"><?php esc_html_e('Import Rules', 'webtaru-site-options-login-security'); ?></button>
							</div>
						</form>
					</div>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Handle exporting redirect rules.
	 */
	public function handle_export_redirects()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to export redirects.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_export_redirects_action', 'wtols_export_redirects_nonce');

		$redirects = get_option('wtols_redirects', array());
		if (!is_array($redirects)) {
			$redirects = array();
		}

		$json = wp_json_encode($redirects);

		header('Content-Description: File Transfer');
		header('Content-Type: application/json');
		header('Content-Disposition: attachment; filename=wtols-redirects-export-' . gmdate('Y-m-d') . '.json');
		header('Expires: 0');
		header('Cache-Control: must-revalidate');
		header('Pragma: public');
		header('Content-Length: ' . strlen($json));

		echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	/**
	 * Handle importing redirect rules.
	 */
	public function handle_import_redirects()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to import redirects.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_import_redirects_action', 'wtols_import_redirects_nonce');

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
		$file_path = isset($_FILES['wtols_redirects_import_file']['tmp_name']) ? $_FILES['wtols_redirects_import_file']['tmp_name'] : '';
		if (empty($file_path) || !is_uploaded_file($file_path)) {
			wp_die(esc_html__('No file uploaded or invalid file.', 'webtaru-site-options-login-security'));
		}

		$file_content = file_get_contents($file_path); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		$imported_data = json_decode($file_content, true);

		if (!is_array($imported_data)) {
			wp_die(esc_html__('Invalid JSON file.', 'webtaru-site-options-login-security'));
		}

		$redirects = get_option('wtols_redirects', array());
		if (!is_array($redirects)) {
			$redirects = array();
		}

		foreach ($imported_data as $source => $rule) {
			$source_clean = strtolower(trim(sanitize_text_field($source), '/'));
			if (empty($source_clean)) {
				continue;
			}

			if (is_array($rule)) {
				$target = isset($rule['target']) ? sanitize_text_field($rule['target']) : '';
				$type = isset($rule['type']) ? (int)$rule['type'] : 301;
			} else {
				$target = sanitize_text_field($rule);
				$type = 301;
			}

			if (empty($target)) {
				continue;
			}

			$redirects[$source_clean] = array(
				'target' => $target,
				'type'   => in_array($type, array(301, 302), true) ? $type : 301,
			);
		}

		update_option('wtols_redirects', $redirects);

		wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_redirects_imported=1'));
		exit;
	}

	/**
	 * Handle bulk deleting redirect rules.
	 */
	public function handle_bulk_delete_redirects()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to manage redirects.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_bulk_delete_redirects_action', 'wtols_bulk_delete_nonce');

		$action = isset($_POST['bulk_action']) ? sanitize_text_field(wp_unslash($_POST['bulk_action'])) : '';
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		$selected_raw   = isset($_POST['selected_rules']) ? (array) wp_unslash($_POST['selected_rules']) : array();
		$selected_rules = array_map('sanitize_text_field', $selected_raw);

		if ('delete' === $action && !empty($selected_rules)) {
			$redirects = get_option('wtols_redirects', array());
			if (is_array($redirects)) {
				foreach ($selected_rules as $rule) {
					$rule_clean = sanitize_text_field(wp_unslash($rule));
					if (isset($redirects[$rule_clean])) {
						unset($redirects[$rule_clean]);
					}
				}
				update_option('wtols_redirects', $redirects);
			}
			wp_safe_redirect(admin_url('admin.php?page=wtols-redirects&wtols_redirects_bulk_deleted=' . count($selected_rules)));
			exit;
		}

		wp_safe_redirect(admin_url('admin.php?page=wtols-redirects'));
		exit;
	}

	/**
	 * Handle saving the custom CSS settings.
	 */
	public function handle_save_custom_css()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to manage custom CSS.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_save_custom_css_action', 'wtols_custom_css_nonce');

		$options = self::get_options();
		$options['custom_css'] = isset($_POST['custom_css']) ? wp_strip_all_tags(wp_unslash($_POST['custom_css'])) : '';

		update_option(self::OPTION_KEY, $options);

		wp_safe_redirect(admin_url('admin.php?page=wtols-custom-css&wtols_saved=1'));
		exit;
	}

	/**
	 * Render the Custom CSS settings page in the WP Admin.
	 */
	public function render_custom_css_page()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		$options = self::get_options();
		$header_title = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			? $options['agency_menu_name']
			: __('Webtaru Site Options and Login Security', 'webtaru-site-options-login-security');

		$wrap_class = 'wrap wtols-wrap';
		if (!empty($options['agency_hide_icon'])) {
			$wrap_class .= ' wtols-hide-header-icon';
		}
		?>
		<div class="<?php echo esc_attr($wrap_class); ?>">
			<div class="wtols-page-header">
				<h1>
					<img src="<?php echo esc_url(WTOLS_PLUGIN_URL . 'assets/webtaru-logo.png'); ?>" class="wtols-header-logo" alt="" />
					<?php echo esc_html($header_title); ?>
				</h1>
			</div>
			<div class="wtols-page-header-spacer"></div>
			<hr class="wp-header-end" style="display:none;">

			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_saved'])): ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Custom CSS saved successfully.', 'webtaru-site-options-login-security'); ?></p></div>
			<?php endif; ?>

			<div class="wtols-content-area" style="max-width: 800px; padding: 24px;">
				<h2 style="margin-top: 0; font-size: 18px; font-weight: 600; padding-bottom: 12px; border-bottom: 1px solid var(--wtols-border); color: var(--wtols-text);"><?php esc_html_e('Custom CSS', 'webtaru-site-options-login-security'); ?></h2>
				<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
					<input type="hidden" name="action" value="wtols_save_custom_css" />
					<?php wp_nonce_field('wtols_save_custom_css_action', 'wtols_custom_css_nonce'); ?>

					<div style="margin-bottom: 20px;">
						<label for="custom_css" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Add Custom CSS', 'webtaru-site-options-login-security'); ?></label>
						<div style="display:flex; height:400px; border:1px solid #dcdcde; border-radius:6px; overflow:hidden; background:#f9f9f9; font-family:'SFMono-Regular',Consolas,monospace;">
							<div class="wtols-line-numbers" id="css-line-numbers" style="width:44px; padding:15px 0; background:#f0f0f0; border-right:1px solid #dcdcde; text-align:center; color:#999; font-size:13px; line-height:1.6; overflow:hidden; flex-shrink:0; user-select:none;"></div>
							<textarea id="custom_css" name="custom_css" placeholder="/* Add custom CSS rules here (without &lt;style&gt; tags) */" style="flex:1; height:100%; border:none; outline:none; background:transparent; padding:15px; font-family:'SFMono-Regular',Consolas,monospace; font-size:13px; line-height:1.6; resize:none; overflow-y:auto; box-sizing:border-box; tab-size:4;"><?php echo esc_textarea($options['custom_css']); ?></textarea>
						</div>
						<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('Applied to all public frontend pages.', 'webtaru-site-options-login-security'); ?></p>
					</div>

					<button type="submit" class="button button-primary" style="padding: 8px 20px !important; height: auto !important; font-weight: 600; border-radius: var(--wtols-radius);"><?php esc_html_e('Save Changes', 'webtaru-site-options-login-security'); ?></button>
				</form>
			</div>
		</div>
		<?php
	}

	/**
	 * Handle saving the custom scripts settings.
	 */
	public function handle_save_custom_scripts()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to manage custom scripts.', 'webtaru-site-options-login-security'));
		}

		check_admin_referer('wtols_save_custom_scripts_action', 'wtols_custom_scripts_nonce');

		$options = self::get_options();

		if (current_user_can('unfiltered_html')) {
			$options['custom_header_code'] = isset($_POST['custom_header_code']) ? sanitize_textarea_field(wp_unslash($_POST['custom_header_code'])) : '';
			$options['custom_body_code'] = isset($_POST['custom_body_code']) ? sanitize_textarea_field(wp_unslash($_POST['custom_body_code'])) : '';
			$options['custom_footer_code'] = isset($_POST['custom_footer_code']) ? sanitize_textarea_field(wp_unslash($_POST['custom_footer_code'])) : '';
		} else {
			$options['custom_header_code'] = isset($_POST['custom_header_code']) ? wp_kses_post(wp_unslash($_POST['custom_header_code'])) : '';
			$options['custom_body_code'] = isset($_POST['custom_body_code']) ? wp_kses_post(wp_unslash($_POST['custom_body_code'])) : '';
			$options['custom_footer_code'] = isset($_POST['custom_footer_code']) ? wp_kses_post(wp_unslash($_POST['custom_footer_code'])) : '';
		}

		update_option(self::OPTION_KEY, $options);

		wp_safe_redirect(admin_url('admin.php?page=wtols-custom-scripts&wtols_saved=1'));
		exit;
	}

	/**
	 * Render the Custom Scripts settings page in the WP Admin.
	 */
	public function render_custom_scripts_page()
	{
		if (!current_user_can('manage_options')) {
			return;
		}

		$options = self::get_options();
		$header_title = !empty($options['agency_mode']) && !empty($options['agency_menu_name'])
			? $options['agency_menu_name']
			: __('Webtaru Site Options and Login Security', 'webtaru-site-options-login-security');

		$wrap_class = 'wrap wtols-wrap';
		if (!empty($options['agency_hide_icon'])) {
			$wrap_class .= ' wtols-hide-header-icon';
		}
		?>
		<div class="<?php echo esc_attr($wrap_class); ?>">
			<div class="wtols-page-header">
				<h1>
					<img src="<?php echo esc_url(WTOLS_PLUGIN_URL . 'assets/webtaru-logo.png'); ?>" class="wtols-header-logo" alt="" />
					<?php echo esc_html($header_title); ?>
				</h1>
			</div>
			<div class="wtols-page-header-spacer"></div>
			<hr class="wp-header-end" style="display:none;">

			<?php // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only notice
			if (isset($_GET['wtols_saved'])): ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e('Custom scripts saved successfully.', 'webtaru-site-options-login-security'); ?></p></div>
			<?php endif; ?>

			<div class="wtols-content-area" style="max-width: 800px; padding: 24px;">
				<h2 style="margin-top: 0; font-size: 18px; font-weight: 600; padding-bottom: 12px; border-bottom: 1px solid var(--wtols-border); color: var(--wtols-text);"><?php esc_html_e('Custom Scripts', 'webtaru-site-options-login-security'); ?></h2>
				<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
					<input type="hidden" name="action" value="wtols_save_custom_scripts" />
					<?php wp_nonce_field('wtols_save_custom_scripts_action', 'wtols_custom_scripts_nonce'); ?>

					<div style="margin-bottom: 20px;">
						<label for="custom_header_code" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Header Scripts', 'webtaru-site-options-login-security'); ?></label>
						<?php if (!current_user_can('unfiltered_html')) : ?>
							<div class="notice notice-warning inline" style="margin-bottom: 8px;"><p><?php esc_html_e('Unfiltered HTML is disabled. Scripts tags will be stripped for safety.', 'webtaru-site-options-login-security'); ?></p></div>
						<?php endif; ?>
						<div style="display:flex; height:350px; border:1px solid #dcdcde; border-radius:6px; overflow:hidden; background:#f9f9f9; font-family:'SFMono-Regular',Consolas,monospace;">
							<div class="wtols-line-numbers" id="header-line-numbers" style="width:44px; padding:15px 0; background:#f0f0f0; border-right:1px solid #dcdcde; text-align:center; color:#999; font-size:13px; line-height:1.6; overflow:hidden; flex-shrink:0; user-select:none;"></div>
							<textarea id="custom_header_code" name="custom_header_code" placeholder="&lt;!-- Insert code here (e.g. Analytics, meta tags) --&gt;" style="flex:1; height:100%; border:none; outline:none; background:transparent; padding:15px; font-family:'SFMono-Regular',Consolas,monospace; font-size:13px; line-height:1.6; resize:none; overflow-y:auto; box-sizing:border-box; tab-size:4;"><?php echo esc_textarea($options['custom_header_code']); ?></textarea>
						</div>
						<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('Code injected into the <head> section of frontend pages.', 'webtaru-site-options-login-security'); ?></p>
					</div>

					<div style="margin-bottom: 20px;">
						<label for="custom_body_code" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Body Scripts (After <body>)', 'webtaru-site-options-login-security'); ?></label>
						<div style="display:flex; height:200px; border:1px solid #dcdcde; border-radius:6px; overflow:hidden; background:#f9f9f9; font-family:'SFMono-Regular',Consolas,monospace;">
							<div class="wtols-line-numbers" id="body-line-numbers" style="width:44px; padding:15px 0; background:#f0f0f0; border-right:1px solid #dcdcde; text-align:center; color:#999; font-size:13px; line-height:1.6; overflow:hidden; flex-shrink:0; user-select:none;"></div>
							<textarea id="custom_body_code" name="custom_body_code" placeholder="&lt;!-- Insert code here (e.g. Google Tag Manager body snippet) --&gt;" style="flex:1; height:100%; border:none; outline:none; background:transparent; padding:15px; font-family:'SFMono-Regular',Consolas,monospace; font-size:13px; line-height:1.6; resize:none; overflow-y:auto; box-sizing:border-box; tab-size:4;"><?php echo esc_textarea($options['custom_body_code']); ?></textarea>
						</div>
						<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('Code injected immediately after the opening <body> tag.', 'webtaru-site-options-login-security'); ?></p>
					</div>

					<div style="margin-bottom: 24px;">
						<label for="custom_footer_code" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--wtols-text);"><?php esc_html_e('Footer Scripts', 'webtaru-site-options-login-security'); ?></label>
						<div style="display:flex; height:300px; border:1px solid #dcdcde; border-radius:6px; overflow:hidden; background:#f9f9f9; font-family:'SFMono-Regular',Consolas,monospace;">
							<div class="wtols-line-numbers" id="footer-line-numbers" style="width:44px; padding:15px 0; background:#f0f0f0; border-right:1px solid #dcdcde; text-align:center; color:#999; font-size:13px; line-height:1.6; overflow:hidden; flex-shrink:0; user-select:none;"></div>
							<textarea id="custom_footer_code" name="custom_footer_code" placeholder="&lt;!-- Insert code here (e.g. Chat widget, conversion pixels) --&gt;" style="flex:1; height:100%; border:none; outline:none; background:transparent; padding:15px; font-family:'SFMono-Regular',Consolas,monospace; font-size:13px; line-height:1.6; resize:none; overflow-y:auto; box-sizing:border-box; tab-size:4;"><?php echo esc_textarea($options['custom_footer_code']); ?></textarea>
						</div>
						<p class="description" style="margin-top: 4px; font-size: 11px;"><?php esc_html_e('Code injected before the closing </body> tag of frontend pages.', 'webtaru-site-options-login-security'); ?></p>
					</div>

					<button type="submit" class="button button-primary" style="padding: 8px 20px !important; height: auto !important; font-weight: 600; border-radius: var(--wtols-radius);"><?php esc_html_e('Save Changes', 'webtaru-site-options-login-security'); ?></button>
				</form>
			</div>
		</div>
		<script>
		(function() {
			function syncLineNumbers(textarea, numbersEl) {
				if (!textarea || !numbersEl) return;
				var lines = textarea.value.split('\n').length;
				var html = '';
				for (var i = 1; i <= lines; i++) html += '<span style="display:block;height:20.8px;line-height:20.8px;">' + i + '</span>';
				numbersEl.innerHTML = html;
				numbersEl.scrollTop = textarea.scrollTop;
			}
			var pairs = [
				['custom_css',         'css-line-numbers'],
				['custom_header_code', 'header-line-numbers'],
				['custom_body_code',   'body-line-numbers'],
				['custom_footer_code', 'footer-line-numbers']
			];
			pairs.forEach(function(pair) {
				var ta = document.getElementById(pair[0]);
				var ln = document.getElementById(pair[1]);
				if (!ta || !ln) return;
				syncLineNumbers(ta, ln);
				ta.addEventListener('input', function() { syncLineNumbers(ta, ln); });
				ta.addEventListener('scroll', function() { ln.scrollTop = ta.scrollTop; });
				ta.addEventListener('keydown', function(e) {
					if (e.key === 'Tab') {
						e.preventDefault();
						var s = ta.selectionStart, end = ta.selectionEnd, v = ta.value;
						ta.value = v.substring(0, s) + '\t' + v.substring(end);
						ta.selectionStart = ta.selectionEnd = s + 1;
						syncLineNumbers(ta, ln);
					}
				});
			});
		})();
		</script>
		<?php
	}
}
