<?php
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );

/**
 * Class smart_convert_currency_unit_conversion
 *
 * Main class for the Smart Convert – Currency & Unit Conversion plugin administration.
 * Handles admin menu registration, asset enqueuing, AJAX requests,
 * manual updates, template management, and custom unit logic.
 */
class smart_convert_currency_unit_conversion {
    private $smart_convert_currency_unit_conversion_options;

    /**
     * Constructor.
     * Registers all necessary hooks for the admin area.
     */
    public function __construct() {
        // Admin Menu and Page Initialization
        add_action( 'admin_menu', array( $this, 'smart_convert_currency_unit_conversion_add_plugin_page' ) );
        add_action( 'admin_init', array( $this, 'smart_convert_currency_unit_conversion_page_init' ) );
        
        // Asset Enqueuing
        // Hook for admin scripts (Dashboard, Settings page, etc.)
        add_action( 'admin_enqueue_scripts', array( $this, 'smart_convert_currency_unit_conversion_admin_enqueue_scripts' ) );
        // Hook for block editor assets (Gutenberg)
        add_action( 'enqueue_block_editor_assets', array( $this, 'smart_convert_currency_unit_conversion_enqueue_editor_styles' ) );
        
        //Scripsts for shared assets
        add_action( 'wp_enqueue_scripts', array( $this, 'smart_convert_currency_unit_conversion_register_shared_assets' ) );
        
        // Also register assets for frontend if needed (usually handled by index.php or specific shortcode logic, but registering style here ensures availability)
        add_action( 'init', array( $this, 'smart_convert_currency_unit_conversion_register_shared_assets' ) );

        // Manual Update Actions (admin_post)
        add_action( 'admin_post_smart_convert_currency_unit_conversion_manual_rates_update', array( $this, 'smart_convert_currency_unit_conversion_manual_rates_update' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_manual_units_update', array( $this, 'smart_convert_currency_unit_conversion_manual_units_update' ) );
        
        // General Logic
        add_action( 'admin_init', array( $this, 'smart_convert_currency_unit_conversion_welcome_redirect_logic' ) );
        add_action( 'wp_ajax_smart_convert_currency_unit_conversion_activate_connection', array( $this, 'ajax_activate_connection' ) );
        
        // Template Management Actions (admin_post)
        add_action( 'admin_post_smart_convert_currency_unit_conversion_save_template', array( $this, 'smart_convert_currency_unit_conversion_save_template' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_delete_template', array( $this, 'smart_convert_currency_unit_conversion_delete_template' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_duplicate_template', array( $this, 'smart_convert_currency_unit_conversion_duplicate_template' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_set_default_template', array( $this, 'smart_convert_currency_unit_conversion_set_default_template' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_export_templates', array( $this, 'smart_convert_currency_unit_conversion_export_templates' ) );
        add_action( 'admin_post_smart_convert_currency_unit_conversion_import_templates', array( $this, 'smart_convert_currency_unit_conversion_import_templates' ) );
        
        // Template Management AJAX
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_save_template', array($this, 'ajax_save_template'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_delete_template', array($this, 'ajax_delete_template'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_get_edit_form', array($this, 'ajax_get_edit_form'));
        
        // Unit Management AJAX
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_get_unit_details', array($this, 'ajax_get_unit_details'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_export_units', array($this, 'ajax_export_units'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_import_units', array($this, 'ajax_import_units'));
        
        // Manual Updates AJAX
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_update_rates', array($this, 'ajax_manual_rates_update'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_update_units', array($this, 'ajax_manual_units_update'));

        // Custom Units Registration Hooks
        add_action('wp_ajax_smart_convert_currency_unit_conversion_check_unit_code', array($this, 'ajax_check_unit_code'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_save_custom_unit', array($this, 'ajax_save_custom_unit'));
        add_action('wp_ajax_smart_convert_currency_unit_conversion_ajax_delete_custom_unit', array($this, 'ajax_delete_custom_unit'));

        // Settings Link on Plugin Page
        add_filter( 'plugin_action_links_' . plugin_basename( dirname(dirname(__FILE__)) ) . '/index.php', array( $this, 'smart_convert_currency_unit_conversion_add_action_links' ) );
        
        // Translation fixes
        add_filter( 'load_script_translation_file', array( $this, 'smart_convert_currency_unit_conversion_json_translation_file_en_us' ), 20, 3 );
        add_filter( 'pre_load_script_translations', array( $this, 'smart_convert_currency_unit_conversion_force_json_content_locale' ), 10, 4 );
    }
    
    /**
     * Registers the shared CSS file used by block editor, onboarding, and frontend.
     */
        public function smart_convert_currency_unit_conversion_register_shared_assets() {
            // Register the style first
            wp_register_style(
                'smart-convert-currency-unit-conversion-shared-style',
                SMART_CONVERT_PLUGIN_URL . '/assets/css/smart-convert-currency-unit-conversion.css',
                array(), // No dependencies
                SMART_CONVERT_VERSION
            );
        
            // Enqueue the style to load it on the frontend
            wp_enqueue_style( 'smart-convert-currency-unit-conversion-shared-style' );
        }
        
    

    /**
     * Enqueues scripts and styles for the Block Editor (Gutenberg).
     */
    public function smart_convert_currency_unit_conversion_enqueue_editor_styles() {
        $plugin_version = defined('SMART_CONVERT_VERSION') ? SMART_CONVERT_VERSION : time();

        // 1. Enqueue Admin Style
        wp_enqueue_style( 'smart-convert-currency-unit-conversion-admin-style', SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-admin.css', array(), $plugin_version );
        
        // 2. Enqueue Shared CSS (Fix: Direct enqueue with file check)
        $css_path = SMART_CONVERT_PLUGIN_DIR . '/assets/css/smart-convert-currency-unit-conversion.css';
        $css_url  = SMART_CONVERT_PLUGIN_URL . '/assets/css/smart-convert-currency-unit-conversion.css';

        if ( file_exists( $css_path ) ) {
            // Use file modification time for cache busting (ensures instant update on changes)
            wp_enqueue_style( 
                'smart-convert-currency-unit-conversion-shared-style', 
                $css_url, 
                array(), 
                filemtime( $css_path ) 
            );
        }

        // 3. Enqueue the Block Script
        wp_enqueue_script(
            'smart-convert-currency-unit-conversion-block',
            SMART_CONVERT_PLUGIN_URL . '/smart-convert-currency-unit-conversion-block.js',
            array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components', 'wp-server-side-render' ),
            $plugin_version,
            true
        );

        // 4. Enqueue the Inline Script
        wp_enqueue_script(
            'smart-convert-currency-unit-conversion-inline',
            SMART_CONVERT_PLUGIN_URL . '/smart-convert-currency-unit-conversion-inline.js',
            array( 'wp-rich-text', 'wp-element', 'wp-i18n', 'wp-components', 'wp-block-editor' ),
            $plugin_version,
            true
        );

        // 5. Load Translations
        if ( function_exists( 'wp_set_script_translations' ) ) {
            wp_set_script_translations( 'smart-convert-currency-unit-conversion-block', 'smart-convert-currency-unit-conversion', SMART_CONVERT_PLUGIN_DIR . '/languages' );
            wp_set_script_translations( 'smart-convert-currency-unit-conversion-inline', 'smart-convert-currency-unit-conversion', SMART_CONVERT_PLUGIN_DIR . '/languages' );
        }

        // 6. Force English Translations (Fix logic for WP core issue)
        $locale = get_locale();
        $lang_code = substr( $locale, 0, 2 );
        $supported_langs = array('cs', 'de', 'es', 'fr', 'id', 'it', 'ja', 'nl', 'pl', 'pt', 'ru', 'tr');
        $force_english = ( strpos( $locale, 'en' ) === 0 || ! in_array( $lang_code, $supported_langs, true ) );
        $domain = 'smart-convert-currency-unit-conversion';
        $languages_dir = trailingslashit( SMART_CONVERT_PLUGIN_DIR ) . 'languages/';
        $inline_json_expected = $languages_dir . $domain . '-' . $locale . '-smart-convert-currency-unit-conversion-inline.json';
        $block_json_expected  = $languages_dir . $domain . '-' . $locale . '-smart-convert-currency-unit-conversion-block.json';

        if ( $force_english ) {
            $scripts_to_fix = [
                'smart-convert-currency-unit-conversion-block'  => 'smart-convert-currency-unit-conversion-en_US-smart-convert-currency-unit-conversion-block.json'
            ];
            foreach ($scripts_to_fix as $handle => $filename) {
                $json_path = SMART_CONVERT_PLUGIN_DIR . '/languages/' . $filename;
                if ( file_exists( $json_path ) ) {
                    $json_content = file_get_contents( $json_path );
                    if ( $json_content ) {
                        // Remove BOM if present
                        $json_content = preg_replace('/^\xEF\xBB\xBF/', '', $json_content); 
                        $decoded = json_decode( $json_content, true );
                        
                        // Attempt recovery if JSON is invalid (e.g., trailing comma/char)
                        if ( $decoded === null ) {
                            $temp = trim( substr( $json_content, 0, -1 ) );
                            $try_dec = json_decode( $temp, true );
                            if ( $try_dec ) $decoded = $try_dec;
                        }
                        
                        if ( $decoded && isset( $decoded['locale_data']['smart-convert-currency-unit-conversion'] ) ) {
                            $data = $decoded['locale_data']['smart-convert-currency-unit-conversion'];
                            // Force current locale to match the loaded English data
                            $data['']['lang'] = $locale; 
                            wp_add_inline_script( $handle, 'wp.i18n.setLocaleData( ' . wp_json_encode( $data ) . ', "smart-convert-currency-unit-conversion" );', 'before' );
                        }
                    }
                }
            }
        } else {
            // Runtime override for locale-specific script translations when WP resolves EN unexpectedly.
            $scripts_to_fix = [
                'smart-convert-currency-unit-conversion-block'  => basename( $block_json_expected ),
            ];
            foreach ( $scripts_to_fix as $handle => $filename ) {
                $json_path = SMART_CONVERT_PLUGIN_DIR . '/languages/' . $filename;
                if ( file_exists( $json_path ) ) {
                    $json_content = file_get_contents( $json_path );
                    if ( $json_content ) {
                        $json_content = preg_replace( '/^\xEF\xBB\xBF/', '', $json_content );
                        $decoded = json_decode( $json_content, true );
                        if ( $decoded && isset( $decoded['locale_data']['smart-convert-currency-unit-conversion'] ) ) {
                            $data = $decoded['locale_data']['smart-convert-currency-unit-conversion'];
                            if ( isset( $data[''] ) && is_array( $data[''] ) ) {
                                $data['']['lang'] = $locale;
                            }
                            wp_add_inline_script( $handle, 'wp.i18n.setLocaleData( ' . wp_json_encode( $data ) . ', "smart-convert-currency-unit-conversion" );', 'before' );
                        }
                    }
                }
            }
        }

    // Move inline color variables from PHP to proper wp_add_inline_style
    // Fetch color settings from plugin options for bubble tooltips
    $options = get_option('smart_convert_currency_unit_conversion_option_name', array());
    if (!is_array($options)) { $options = array(); }
    
    $bg_color = isset($options['smart_convert_currency_unit_conversion_bubble_color']) && !empty($options['smart_convert_currency_unit_conversion_bubble_color']) ? $options['smart_convert_currency_unit_conversion_bubble_color'] : '#424242';
    $text_color = isset($options['smart_convert_currency_unit_conversion_bubble_font']) && !empty($options['smart_convert_currency_unit_conversion_bubble_font']) ? $options['smart_convert_currency_unit_conversion_bubble_font'] : '#ffffff';
    
    // Inject CSS variables into the editor to control tooltip colors dynamically
    $custom_css = "
        :root {
            --smart-convert-currency-unit-conversion-bubble-bg: " . sanitize_hex_color($bg_color) . ";
            --smart-convert-currency-unit-conversion-bubble-text: " . sanitize_hex_color($text_color) . ";
        }
    ";
    wp_add_inline_style('smart-convert-currency-unit-conversion-admin-style', $custom_css);

        // 7. Pass Data to JS
        $templates = function_exists('smart_convert_currency_unit_conversion_get_all_templates') ? smart_convert_currency_unit_conversion_get_all_templates() : [];
        $default_currency = isset($this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency']) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency'] : 'USD';
        
        global $wpdb;
        $custom_units_cache_key = 'smart_convert_currency_unit_conversion_editor_custom_units';
        $custom_units_raw = wp_cache_get( $custom_units_cache_key, 'smart_convert_currency_unit_conversion' );

        if ( false === $custom_units_raw ) {
            $table_name = $wpdb->prefix . 'smart_convert_currency_unit_conversion_units';
            $table_name_escaped = '`' . esc_sql( $table_name ) . '`';
            // Check table existence before query to prevent errors on fresh install
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Table existence check on custom table.
            if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name ) {
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Reading custom table for editor autosuggest.
                $custom_units_raw = $wpdb->get_results( "SELECT DISTINCT unit_from, unit_from_name FROM {$table_name_escaped} WHERE is_custom = 1", ARRAY_A );
                wp_cache_set( $custom_units_cache_key, $custom_units_raw, 'smart_convert_currency_unit_conversion', 3600 );
            } else {
                $custom_units_raw = array();
            }
        }
        
        $custom_units_list = array();
        if ( is_array( $custom_units_raw ) ) {
            foreach ( $custom_units_raw as $row ) {
                $code = $row['unit_from'];
                $name = $row['unit_from_name'];
                if ( ! empty( $name ) ) {
                    $custom_units_list[] = array( 'value' => $code, 'label' => sprintf( '%s (%s)', $code, $name ) );
                } else {
                    $custom_units_list[] = array( 'value' => $code, 'label' => $code );
                }
            }
        }

        $templates_data = array(
            'templates' => array_map(function($t) {
                return array(
                    'key' => $t['template_key'],
                    'name' => $t['template_name'],
                    'type' => $t['template_type'],
                    'isDefaultCurrency' => isset($t['is_default_currency']) && $t['is_default_currency'] == 1,
                    'isDefaultUnits' => isset($t['is_default_units']) && $t['is_default_units'] == 1
                );
            }, $templates),
            'defaultCurrency' => $default_currency,
            'defaultCurrencyKey' => function_exists('smart_convert_currency_unit_conversion_get_default_currency_template') ? smart_convert_currency_unit_conversion_get_default_currency_template()['template_key'] : 'default',
            'customUnits' => $custom_units_list,
            'unitCatalogEnglishMap' => function_exists( 'smart_convert_currency_unit_conversion_get_unit_catalog_english_map' )
                ? smart_convert_currency_unit_conversion_get_unit_catalog_english_map()
                : array(),
        );

        wp_localize_script( 'smart-convert-currency-unit-conversion-block', 'SmartConvertCurrencyUnitConversionTemplates', $templates_data );
        wp_localize_script( 'smart-convert-currency-unit-conversion-inline', 'SmartConvertCurrencyUnitConversionSettings', $templates_data );

        // 8. Inject Block Strings
        wp_localize_script( 'smart-convert-currency-unit-conversion-block', 'SmartConvertCurrencyUnitConversionBlockStrings', array(
            // translators: English: "Smart Convert". Usage: Untranslated Gutenberg block name used for searching in the WordPress admin. This heading appears in the editor sidebar when configuring the block. Variables: No dynamic placeholders. Linguistics: Noun phrase used as a title, not a full sentence. Constraints: Keep it relatively short so it fits on one line in WordPress admin headings.
            'blockTitle'    => __( 'Smart Convert', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "The block allows you to easily insert a dynamic currency or unit converter directly into the page content with options to set default values, precision, and visual style using predefined templates.". Usage: Helper description for the Smart Convert Free block, displayed in the Gutenberg editor sidebar. It explains that the block allows users to easily insert a dynamic converter directly into page content, with options for default values, precision, and visual style via predefined templates. Variables: No dynamic placeholders. Linguistics: Short explanatory sentence or phrase addressed to site administrators. Constraints: Can be longer than labels, but still keep it clear and focused on what the control does.
            'blockDesc'     => __( 'The block allows you to easily insert a dynamic currency or unit converter directly into the page content with options to set default values, precision, and visual style using predefined templates.', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "currency". Invisible search keyword alias helping users locate the block in the Gutenberg editor sidebar. Translators should use the most common local term. This concise phrase belongs to the Smart Convert block configuration and contains no dynamic placeholders.
            'keyword1'      => __( 'currency', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "money". Secondary invisible search keyword alias. Translators should select a related local synonym. This concise phrase belongs to the Smart Convert Gutenberg block configuration and contains no dynamic placeholders.
            'keyword2'      => __( 'money', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Smart Convert Settings". Usage: Heading in the Gutenberg block's right sidebar for configuring conversion parameters. The "Smart Convert Free" portion remains untranslated. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read.
            'settingsTitle' => __( 'Smart Convert Settings', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Live Preview". Editor section heading demonstrating the final frontend result (styles, colors, and calculations). Translators should adapt this to distinguish the editing interface from the visual output. This concise phrase belongs to the Smart Convert Gutenberg block configuration and contains no dynamic placeholders.
            'livePreview'   => __( 'Live Preview', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Amount". Usage: Label for the field where users enter the numerical value to be converted. This generic text appears in the Gutenberg block editor sidebar during configuration. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read.
            'labelAmount'   => __( 'Amount', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Original Currency / Unit". Usage: Heading for the field used to select the source currency or unit. This generic text appears in the Gutenberg sidebar. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read.
            'labelFrom'     => _x( 'Original Currency / Unit', 'label.form.source_unit', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Target Currency / Unit". Usage: Heading for the field used to select the destination currency or unit. This generic text appears in the Gutenberg sidebar. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read.
            'labelTo'       => _x( 'Target Currency / Unit', 'label.form.target_unit', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Number of Decimal Places". Usage: Heading for the field where users specify the desired decimal precision for the output. This generic text appears in the Gutenberg sidebar. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read.
            'labelDecimals' => __( 'Number of Decimal Places', 'smart-convert-currency-unit-conversion' ),
            'labelOutput'   => __( 'Conversion Display Format', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Enter the value or amount to be converted to another unit or currency. Use a period to separate decimal places.". Usage: Help text for the 'Amount' field (gutenberg-inline-convert-amount) in the Gutenberg sidebar, instructing users to enter the value for conversion and use a period for decimals. Variables: No dynamic placeholders. Linguistics: Short explanatory sentence or phrase addressed to site administrators. Constraints: Can be longer than labels, but still keep it clear and focused on what the control does.
            'hintCommon'    => __( 'Enter the value or amount to be converted to another unit or currency. Use a period to separate decimal places.', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Select the name of the template to be used for displaying the conversion from the autosuggest.". Usage: Help text for the display format field, instructing users to choose an output template from the autosuggest dropdown. Variables: No dynamic placeholders. Linguistics: Short explanatory sentence or phrase addressed to site administrators. Constraints: Can be longer than labels, but still keep it clear and focused on what the control does.
            'hintOutput'    => __( 'Select the name of the template to be used for displaying the conversion from the autosuggest.', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "System". Usage: Label identifying default templates included during plugin installation. This generic interface text belongs to template management and may appear in admin screens or frontend outputs. It contains no dynamic placeholders, usually functions as a short noun phrase or sentence, and should be kept concise and easy to read.
            'badgeBuiltin'  => __( 'System', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Default Template for Currency Conversions". Usage: Settings section heading for selecting the primary currency display template. This generic interface text belongs to template management and may appear in admin screens or frontend outputs. It contains no dynamic placeholders, usually functions as a short noun phrase or sentence, and should be kept concise and readable.
            'badgeDefCurr'  => __( 'Default Template for Currency Conversions', 'smart-convert-currency-unit-conversion' ),
            // translators: English: "Default Template for Unit Conversions". Usage: Settings section heading for selecting the primary unit conversion display template. This generic interface string belongs to unit management and may appear in Smart Convert admin screens or frontend outputs. It lacks dynamic placeholders, typically acts as a short noun phrase or sentence, and should be kept concise and readable without strict length limits.
            'badgeDefUnit'  => __( 'Default Template for Unit Conversions', 'smart-convert-currency-unit-conversion' ),
        ));
    }
    
    
    /**
     * AJAX Handler for manual currency rates update.
     * * Triggers the update process for currency rates via AJAX.
     * Allows background processing even if the user navigates away or closes the modal.
     */
    public function ajax_manual_rates_update() {
        // Security check
        check_ajax_referer('smart_convert_currency_unit_conversion_manual_rates_update_action');
        // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error(
                array( 'message' => __( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) )
            );
        }

        // Important: Allow the script to continue running in the background even if the connection closes.
        ignore_user_abort(true);
        // set_time_limit(300); // Optional: Set max execution time to 5 minutes

        if (function_exists('smart_convert_currency_unit_conversion_update_currency_csv')) {
            $res = smart_convert_currency_unit_conversion_update_currency_csv();
            
            if (is_wp_error($res)) {
                wp_send_json_error(['message' => $res->get_error_message()]);
            } elseif (is_array($res) && $res['success']) {
                // Security: Remove the source URL from the response before sending back to client.
                unset($res['source']); 
                wp_send_json_success($res);
            }
        }
        
        // translators: English: "An unknown error occurred.". Universal fallback message when the system cannot identify the specific problem. This declarative text belongs to the general settings and shared UI of the Smart Convert plugin, appearing in admin notices, AJAX responses, or the frontend without dynamic placeholders.
        wp_send_json_error(
            array( 'message' => __( 'An unknown error occurred.', 'smart-convert-currency-unit-conversion' ) )
        );
    }

    /**
     * AJAX Handler for manual units update.
     * * Forces an update of the unit definitions CSV.
     */
    public function ajax_manual_units_update() {
        check_ajax_referer('smart_convert_currency_unit_conversion_manual_units_update_action');
        // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error(
                array( 'message' => __( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) )
            );
        }

        ignore_user_abort(true);
        // set_time_limit(300);

        if (function_exists('smart_convert_currency_unit_conversion_update_units_csv_once')) {
            $res = smart_convert_currency_unit_conversion_update_units_csv_once(true); // Force update is set to true
            
            if (is_wp_error($res)) {
                wp_send_json_error(['message' => $res->get_error_message()]);
            } elseif (is_array($res) && $res['success']) {
                unset($res['source']); // Remove source URL
                wp_send_json_success($res);
            }
        }
        
        // translators: English: "An unknown error occurred.". Universal fallback message when the system cannot identify the specific problem. This declarative text belongs to the general settings and shared UI of the Smart Convert plugin, appearing in admin notices, AJAX responses, or the frontend without dynamic placeholders.
        wp_send_json_error(
            array( 'message' => __( 'An unknown error occurred.', 'smart-convert-currency-unit-conversion' ) )
        );
    }

    /**
     * POST Handler for manual currency rates update (Fallback).
     * * Handles the standard form submission (non-AJAX) for updating rates.
     * Sets a transient with the result message to display on the next page load.
     */
    public function smart_convert_currency_unit_conversion_manual_rates_update() {
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_die(
                esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' )
            );
        }

        $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ) : '';
        if ( ! wp_verify_nonce( $nonce, 'smart_convert_currency_unit_conversion_manual_rates_update_action' ) ) {
            // translators: English: "Security check failed. Please try again.". Usage: Concise error message shown when a security check or related operation fails (e.g., invalid input, server problems, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_die(
                esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' )
            );
        }

        $status  = 'error';
        // translators: English: "❌ Rate update failed". Usage: Declarative modal error message clearly explaining a failed currency update. Belonging to exchange rate management, it appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and should remain concise and readable without strict length limits.
        $message = __( '❌ Rate update failed', 'smart-convert-currency-unit-conversion' );

        if ( function_exists( 'smart_convert_currency_unit_conversion_update_currency_csv' ) ) {
            // Call the function which returns an array or WP_Error
            $res = smart_convert_currency_unit_conversion_update_currency_csv(); 
            
            if ( is_wp_error( $res ) ) {
                // translators: English: "❌ Rate update failed". Usage: Declarative modal error message clearly explaining a failed currency update. Belonging to exchange rate management, it appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and should remain concise and readable without strict length limits.
                $message = __( '❌ Rate update failed', 'smart-convert-currency-unit-conversion' ) . ' (' . esc_html( $res->get_error_message() ) . ')';
            } elseif ( is_array($res) && isset($res['success']) && $res['success'] === true ) {
                $status  = 'success';
                $source = isset($res['source']) ? $res['source'] : 'unknown';
                // Append source information to the success message
                // translators: ✔️ Currency rates updated!: Source identifier (e.g., URL or name of the update source). Usage: Positive declarative modal message confirming a successful update including a dynamic source detail.
                $message = sprintf(
                    __( '✔️ Currency rates updated!', 'smart-convert-currency-unit-conversion' ),
                    esc_html( $source )
                );
            } else {
                // translators: English: "❌ Rate update failed". Usage: Declarative modal error message clearly explaining a failed currency update. Belonging to exchange rate management, it appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and should remain concise and readable without strict length limits.
                $message = __( '❌ Rate update failed', 'smart-convert-currency-unit-conversion' );
            }
        } else {
            // translators: English: "❌ Rate update failed because a required function is missing". Usage: Declarative modal error message explaining a failure due to missing functions. Belonging to exchange rate management, it is displayed in WordPress admin notices, AJAX responses, or occasionally on the frontend. It contains no dynamic placeholders and must be kept concise and easy to read without strict length limits.
            $message = __( '❌ Rate update failed because a required function is missing', 'smart-convert-currency-unit-conversion' );
        }

        set_transient( 'smart_convert_currency_unit_conversion_update_rates_status', array( 'status' => $status, 'message' => $message ), 30 );
        wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=rates' ) );
        exit;
    }
    
    /**
     * POST Handler for manual units update (Fallback).
     * * Handles the standard form submission (non-AJAX) for updating unit definitions.
     */
    public function smart_convert_currency_unit_conversion_manual_units_update() {
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_die(
                esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' )
            );
        }

        check_admin_referer( 'smart_convert_currency_unit_conversion_manual_units_update_action' );

        $status = 'error';
        // translators: English: "Units update failed.". Declarative error message indicating a bulk modification process failed (e.g., script timeout). It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
        $message = __( 'Units update failed.', 'smart-convert-currency-unit-conversion' );

        if ( function_exists( 'smart_convert_currency_unit_conversion_update_units_csv_once' ) ) {
            $res = smart_convert_currency_unit_conversion_update_units_csv_once(true);
            
            if ( is_wp_error( $res ) ) {
                // translators: English: "Units update failed.". Declarative error message indicating a bulk modification process failed (e.g., script timeout). It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                $message = __( 'Units update failed.', 'smart-convert-currency-unit-conversion' ) . ': ' . $res->get_error_message();
            } elseif ( is_array($res) && isset($res['success']) && $res['success'] ) {
                $status = 'success';
                $rows = isset($res['rows']) ? intval($res['rows']) : 0;
                $message = sprintf(
                    /* translators: %d: Number of imported unit pairs. */
                    __( 'The database was successfully updated, a total of %d unit pairs were imported.', 'smart-convert-currency-unit-conversion' ),
                    $rows
                );
            } else {
                // translators: English: "Units update failed.". Declarative error message indicating a bulk modification process failed (e.g., script timeout). It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                $message = __( 'Units update failed.', 'smart-convert-currency-unit-conversion' ) . ' (' . __( 'An unknown error occurred.', 'smart-convert-currency-unit-conversion' ) . ').';
            }
        }

        // Change: Use a unique transient name specifically for unit updates
        set_transient( 'smart_convert_currency_unit_conversion_update_units_status', array( 'status' => $status, 'message' => $message ), 30 );
        
        // Change: Redirect specifically to the units tab
        wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=units' ) );
        exit;
    }

    /**
     * Enqueue Admin Scripts and Styles.
     * * Loads JS and CSS required for the plugin settings page.
     * Handles localization of strings and data for JavaScript usage.
     *
     * @param string $hook The current admin page hook.
     */
public function smart_convert_currency_unit_conversion_admin_enqueue_scripts( $hook ) {
        // 1. Determine if we are on the onboarding page (using sanitization for security scanners)
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading URL parameters for display logic only, no data modification.
        $current_page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $current_tab  = isset( $_GET['tab'] )  ? sanitize_key( $_GET['tab'] )  : '';

        $is_onboarding = ( $current_page === 'smart-convert-currency-unit-conversion' && $current_tab === 'onboarding' );

        // 2. Enqueue shared styles specifically for the Onboarding page
        if ( $is_onboarding ) {
            wp_enqueue_style( 'smart-convert-currency-unit-conversion-shared-style' );
            // Note: We intentionally do NOT return here, as we need to proceed to load color variables below.
        }

        // 3. HOOK CHECK: If we are not on the specific plugin page AND not on the onboarding page, exit.
        // This prevents loading assets globally in the WP Admin.
        if ( $hook !== 'settings_page_smart-convert-currency-unit-conversion' && ! $is_onboarding ) {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only tab switch used for UI rendering.
        $current_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';

        wp_enqueue_style( 'jquery-ui-style', SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-jquery-ui.css', array(), SMART_CONVERT_VERSION );

		// 1b. NEW: Custom Admin Styles for the Design System
		wp_enqueue_style( 'smart-convert-currency-unit-conversion-admin-style', SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-admin.css', array(), SMART_CONVERT_VERSION );


        // Fetch color settings from plugin options
            $options = get_option('smart_convert_currency_unit_conversion_option_name');
            $bg_color = isset($options['smart_convert_currency_unit_conversion_bubble_color']) && !empty($options['smart_convert_currency_unit_conversion_bubble_color']) ? $options['smart_convert_currency_unit_conversion_bubble_color'] : '#424242';
            $text_color = isset($options['smart_convert_currency_unit_conversion_bubble_font']) && !empty($options['smart_convert_currency_unit_conversion_bubble_font']) ? $options['smart_convert_currency_unit_conversion_bubble_font'] : '#ffffff';
        
            // Inject CSS variables into the admin header to control tooltip colors dynamically
            $custom_css = "
                :root {
                    --smart-convert-currency-unit-conversion-bubble-bg: " . sanitize_hex_color($bg_color) . ";
                    --smart-convert-currency-unit-conversion-bubble-text: " . sanitize_hex_color($text_color) . ";
                }
            ";
            wp_add_inline_style( 'smart-convert-currency-unit-conversion-admin-style', $custom_css );
            
		// 2. AJAX Update Script
		wp_enqueue_script(
			'smart-convert-currency-unit-conversion-ajax-update',
			SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-ajax-update.js',
			array( 'jquery', 'jquery-effects-core' ), // 'jquery-effects-core' required for easing animations
			SMART_CONVERT_VERSION,
			true
		);

		wp_localize_script( 'smart-convert-currency-unit-conversion-ajax-update', 'SmartConvertCurrencyUnitConversionAjax', array(
			// translators: English: "Preparing to establish a connection with the source server…". Usage: First step of the update process, shown while connection preparations are underway. This generic interface string belongs to exchange rate management and may appear in admin screens or frontend outputs. It lacks dynamic placeholders, usually forms a short noun phrase or sentence, and requires a concise, readable translation.
			'preparing'    => __( 'Preparing to establish a connection with the source server…', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Downloading current currency rates…". Usage: Third step of the update process, shown during the active rate download. This generic exchange rate management text may appear in admin screens or frontend outputs. It lacks dynamic placeholders, typically functions as a short noun phrase or sentence, and should remain concise and readable without strict length limits.
			'downloading'  => __( 'Downloading current currency rates…', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Updating currency database on your server…". Usage: Fourth step of the update process, displayed while saving the new database. This generic interface string belongs to exchange rate management and may appear in admin screens or frontend outputs. It lacks dynamic placeholders, usually forms a short noun phrase or sentence, and must remain concise and readable.
			'processing'   => __( 'Updating currency database on your server…', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Currency rates updated!". Usage: Positive declarative confirmation message representing the final successful step of the update process. Belonging to exchange rate management, it appears to administrators in admin notices or AJAX responses. It lacks dynamic placeholders and should be kept concise and easy to read without strict length limits.
			'success'      => __( 'Currency rates updated!', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Currency rate update failed.". Usage: Declarative error message cleanly explaining a failed rate update. Belonging to exchange rate management, it is shown in WordPress admin notices, AJAX responses, or occasionally on the frontend. It contains no dynamic placeholders and must be kept concise and easy to read without strict length limits.
			'error'        => __( 'Currency rate update failed.', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Please wait…". Usage: Modal heading displayed after manually triggering a rate update. This noun phrase serves as a section title shown at the top of Smart Convert admin pages or boxes. It contains no dynamic placeholders and must be short enough to fit gracefully on one line in WordPress admin headings.
			'title'        => __( 'Please wait…', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Preparing to establish a connection with the source server…". Usage: First step of the update process, shown while connection preparations are underway. This generic interface string belongs to exchange rate management and may appear in admin screens or frontend outputs. It lacks dynamic placeholders, usually forms a short noun phrase or sentence, and requires a concise, readable translation.
			'initializing' => __( 'Preparing to establish a connection with the source server…', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Server error:". Usage: Declarative error message preceding additional server failure details. Belonging to exchange rate management, it is displayed in WordPress admin notices, AJAX responses, or occasionally on the frontend. It contains no dynamic placeholders and requires a concise, readable translation without strict length limits.
			'server_error' => __( 'Server error:', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "%d items were successfully updated in the database.". Usage: Positive declarative confirmation message displaying the exact number of updated database items. Belonging to exchange rate management, it is shown to administrators in admin notices or AJAX responses. The variable %d represents a numeric value. It requires a concise, readable translation without strict length limits.
			'success_rows' => __( '%d items were successfully updated in the database.', 'smart-convert-currency-unit-conversion' ),
		) );
		// 3. Load translations for scripts
		if ( function_exists( 'wp_set_script_translations' ) ) {
			wp_set_script_translations(
				'smart-convert-currency-unit-conversion-inline',
				'smart-convert-currency-unit-conversion',
				SMART_CONVERT_PLUGIN_DIR . '/languages'
			);
		}

		// 4. Enqueue the inline script handling logic
		wp_enqueue_script(
			'smart-convert-currency-unit-conversion-inline',
			SMART_CONVERT_PLUGIN_URL . '/smart-convert-currency-unit-conversion-inline.js',
			array( 'jquery-ui-autocomplete', 'wp-i18n' ),
			'20251120',
			true
		);

		// 5. Prepare Data for JS (Currency Codes)
		$currency_codes = $this->get_all_currency_codes();

		// 5a. Fetch currency names for administration display
		$currency_labels = array();
		if ( function_exists( 'smart_convert_currency_unit_conversion_get_unit_name' ) ) {
			foreach ( $currency_codes as $code ) {
				$code_upper = strtoupper( $code );
				$name       = smart_convert_currency_unit_conversion_get_unit_name( $code_upper );
				if ( ! empty( $name ) && $name !== $code_upper ) {
					$currency_labels[ strtolower( $code_upper ) ] = $name;
				}
			}
		}

		if ( ! empty( $currency_labels ) ) {
			wp_localize_script(
				'smart-convert-currency-unit-conversion-inline',
				'SmartConvertCurrencyUnitConversionAdmin',
				array(
					'currencyLabels' => $currency_labels,
				)
			);
		}

		// 6. Inline JS logic for the Autocomplete field.
		// This script handles the behavior of the default currency input field.
		$inline_js = '
		jQuery(document).ready(function($) {
			const { __ } = wp.i18n;
			const codes = ' . wp_json_encode( $currency_codes ) . ';
			
			function getLabel(code) {
				if (!code) return "";
				let c     = String(code).toUpperCase();
				let lower = String(code).toLowerCase();
				let name  = "";

				if ( window.SmartConvertCurrencyUnitConversionAdmin && window.SmartConvertCurrencyUnitConversionAdmin.currencyLabels ) {
					let map = window.SmartConvertCurrencyUnitConversionAdmin.currencyLabels;
					if ( map[ lower ] ) {
						name = map[ lower ];
					}
				}

				if ( !name ) {
					let key  = "global-unit-" + lower;
					// translators: English: "global-unit-<code>". Dynamic key fallback used for localized currency/unit labels in admin autocomplete.
					let text = __( key, "smart-convert-currency-unit-conversion" );
					if ( text && text !== key ) {
						name = text;
					}
				}

				if ( name ) {
					return c + " - " + name;
				}
				return c;
			}

			const sourceData = codes.map( function( code ) {
				return {
					label: getLabel(code),
					value: code 
				};
			});

			$( "#smart_convert_currency_unit_conversion_default_currency_autocomplete" ).autocomplete({
                appendTo: ".smart-convert-currency-unit-conversion-settings-wrapper", // <--- KEY CHANGE: Ensure dropdown stays within wrapper
                source: sourceData,
                delay: 0,
                minLength: 0,
                autoFocus: true,
                select: function( event, ui ) {
                    event.preventDefault();
                    $( "#smart_convert_currency_unit_conversion_default_currency_autocomplete" ).val( ui.item.label );
                    $( "#smart_convert_currency_unit_conversion_default_currency" ).val( ui.item.value );
                },
				change: function( event, ui ) {
					if ( !ui.item ) {
						let val = $(this).val().trim();
						if ( val === "" ) {
							$( "#smart_convert_currency_unit_conversion_default_currency" ).val( "" );
							return;
						}
						let match = sourceData.find( item => 
							item.value.toLowerCase() === val.toLowerCase() || 
							item.label.toLowerCase().includes(val.toLowerCase())
						);
						if ( match ) {
							$(this).val( match.label );
							$( "#smart_convert_currency_unit_conversion_default_currency" ).val( match.value );
						} else {
							$(this).val( "" ); 
							$( "#smart_convert_currency_unit_conversion_default_currency" ).val( "" );
						}
					}
				}
			}).on("focus", function () {
				$(this).autocomplete("search", "");
			});
			
			let currentVal = $( "#smart_convert_currency_unit_conversion_default_currency" ).val();
			if ( currentVal ) {
				$( "#smart_convert_currency_unit_conversion_default_currency_autocomplete" ).val( getLabel(currentVal) );
			}
		});
		';

		wp_add_inline_script( 'smart-convert-currency-unit-conversion-inline', $inline_js );

		// Specific Enqueue for Templates Tab
		if ( $hook === 'settings_page_smart-convert-currency-unit-conversion' && $current_tab === 'templates' ) {
			wp_enqueue_script(
				'smart-convert-currency-unit-conversion-templates',
				SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-templates.js',
				array( 'jquery' ),
				SMART_CONVERT_VERSION,
				true
			);

			wp_localize_script( 'smart-convert-currency-unit-conversion-templates', 'SmartConvertCurrencyUnitConversionTemplatesAjax', array(
				'ajaxUrl'       => admin_url( 'admin-ajax.php' ),
				// translators: English: "Saving templates…". Status message displayed during the save process. This concise phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders.
				'saving'        => __( 'Saving templates…', 'smart-convert-currency-unit-conversion' ),
				// translators: English: "Save Template". Button label used while editing an existing template. This short imperative command belongs to template management and appears near forms in Smart Convert admin pages without dynamic placeholders.
				// translators: English: "Save Template". Primary button label used to persist template changes in admin.
				'save'          => _x( 'Save Template', 'action.save.template', 'smart-convert-currency-unit-conversion' ),
				// translators: English: "Loading templates, please wait…". Status message shown while templates are being loaded. This concise phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders.
				'loading'       => __( 'Loading templates, please wait…', 'smart-convert-currency-unit-conversion' ),
				// translators: English: "Edit Template". Usage: Imperative button or link label allowing users to delete the template. This text belongs to template management and appears near related forms on Smart Convert admin pages. It lacks dynamic placeholders and must remain extremely short to fit standard WordPress buttons.
				// translators: English: "Edit Template". Button/link label used to open template editing mode.
				'edit'          => _x( 'Edit Template', 'action.edit.template', 'smart-convert-currency-unit-conversion' ),
				// translators: English: "Are you sure you want to delete this template? A deleted template cannot be restored.". Usage: Confirmation prompt warning users that template deletion is irreversible. This generic interface string belongs to template management and may appear in admin screens or frontend outputs. It lacks dynamic placeholders, typically functions as a short noun phrase or sentence, and requires a concise, readable translation.
				'confirmDelete' => __( 'Are you sure you want to delete this template? A deleted template cannot be restored.', 'smart-convert-currency-unit-conversion' ),
				// translators: English: "An error occurred!". Usage: Declarative fallback error message for unidentifiable failures. Belonging to template management, it is shown in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and should remain concise and readable.
				'errorGeneric'  => __( 'An error occurred!', 'smart-convert-currency-unit-conversion' )
			) );
		}


		// ENQUEUE CUSTOM UNITS SCRIPT
		// Loads scripts only on the 'units' tab.
		if ( $hook === 'settings_page_smart-convert-currency-unit-conversion' && $current_tab === 'units' ) {
			wp_enqueue_script(
				'smart-convert-currency-unit-conversion-custom-units',
				SMART_CONVERT_PLUGIN_URL . '/admin/smart-convert-currency-unit-conversion-custom-units.js',
				array( 'jquery', 'jquery-ui-autocomplete' ), // Added autocomplete dependency
				SMART_CONVERT_VERSION,
				true
			);

			// --- PREPARE DATA FOR AUTOCOMPLETE (UNITS + CURRENCIES) ---
			global $wpdb;

			// Implement caching for these queries to avoid DirectDatabaseQuery warnings
			$cache_key    = 'smart_convert_currency_unit_conversion_admin_units_currencies_list';
			$cached_lists = wp_cache_get( $cache_key, 'smart_convert_currency_unit_conversion' );

			if ( false === $cached_lists ) {
				// 1. Fetch ALL Units
				// FIX: Use table name directly with prefix to avoid unescaped parameter errors
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom table name is static (prefix + suffix).
				$units = $wpdb->get_col( "SELECT DISTINCT unit_from FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units" );

				// 2. Fetch ALL Currencies
				// FIX: Use table name directly with prefix to avoid unescaped parameter errors
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Custom table name is static (prefix + suffix).
				$currencies = $wpdb->get_col( "SELECT DISTINCT from_currency FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_currencies" );

				$cached_lists = array(
					'units'      => $units,
					'currencies' => $currencies
				);
				wp_cache_set( $cache_key, $cached_lists, 'smart_convert_currency_unit_conversion', 3600 );
			}

			$units      = $cached_lists['units'];
			$currencies = $cached_lists['currencies'];

			// 3. Merge & Sort
			$all_codes = array_unique( array_merge( (array) $units, (array) $currencies ) );
			sort( $all_codes );

			// 4. Prepare Options with Names for the UI
			$select_data = [];
			foreach ( $all_codes as $code ) {
				if ( empty( $code ) ) {
					continue;
				}
				$name = function_exists( 'smart_convert_currency_unit_conversion_get_unit_name' ) ? smart_convert_currency_unit_conversion_get_unit_name( $code ) : $code;

				// Label format: "Czech Koruna (CZK)" or just "CZK"
				$label = ( $name && $name !== strtoupper( $code ) )
					? $name . " (" . strtoupper( $code ) . ")"
					: strtoupper( $code );

				$select_data[] = [
					'val'   => $code, // Value stored in DB
					'label' => $label // Value shown to user
				];
			}

			// Pass data to JS
			wp_localize_script( 'smart-convert-currency-unit-conversion-custom-units', 'SmartConvertCurrencyUnitConversionUnitsData', array(
				'nonce'         => wp_create_nonce( 'smart_convert_currency_unit_conversion_custom_unit_action' ),
				'existingCodes' => array_map( 'strtolower', (array) $units ), // For validation purposes
				'list'          => $select_data, // For Autocomplete dropdown
				'strings'       => array(
					// translators: English: "This code already exists, please choose another one.". Declarative error message shown when an entered code is not unique (e.g., due to invalid input). It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
					'codeExists'    => __( 'This code already exists, please choose another one.', 'smart-convert-currency-unit-conversion' ),
					// translators: English: "This step is irreversible. If the unit is used somewhere, the conversion will stop working.". Informational warning regarding the risks of deletion. This concise phrase belongs to unit and currency management and may appear in admin screens or frontend outputs without dynamic placeholders.
					'confirmDelete' => __( 'This step is irreversible. If the unit is used somewhere, the conversion will stop working.', 'smart-convert-currency-unit-conversion' ),
					// translators: English: "Attention". Modal window heading for non-critical warnings or important notices. This short noun phrase belongs to the general settings and shared UI of the Smart Convert plugin, appearing at the top of admin pages without dynamic placeholders.
					'titleError'    => __( 'Attention', 'smart-convert-currency-unit-conversion' ),
					// "Attention"
					// translators: English: "Success!". Modal window heading confirming the completion of an operation. This positive, concise sentence belongs to the general settings and shared UI of the Smart Convert plugin, displayed to administrators without dynamic placeholders.
					'titleSuccess'  => __( 'Success!', 'smart-convert-currency-unit-conversion' ),
					// "Success"
					// translators: English: "Are you sure you want to delete this custom unit?". Modal window heading requesting confirmation before a destructive action. This short title belongs to the general settings and shared UI of the Smart Convert plugin, appearing at the top of admin pages without dynamic placeholders.
					'titleConfirm'  => __( 'Are you sure you want to delete this custom unit?', 'smart-convert-currency-unit-conversion' ),
					// "Confirmation"
					// translators: English: "OK". Button label to confirm reading an informative alert. This very short command belongs to the general settings and shared UI of the Smart Convert plugin, appearing near admin forms without dynamic placeholders.
					'btnOk'         => __( 'OK', 'smart-convert-currency-unit-conversion' ),
					// "OK"
					// translators: English: "Cancel". Button label to abort an action or close a modal without saving. This very short imperative command belongs to the general settings and shared UI of the Smart Convert plugin, appearing near admin forms without dynamic placeholders.
					// translators: English: "Cancel". Generic modal cancel button label in admin dialogs.
					'btnCancel'     => _x( 'Cancel', 'action.cancel.modal', 'smart-convert-currency-unit-conversion' ),
					// "Cancel"
					// translators: English: "Yes, delete unit.". Red confirmation button text inside a modal detailing a destructive action. This short imperative command belongs to unit and currency management, appearing near admin forms without dynamic placeholders.
					// translators: English: "Yes, delete unit.". Destructive confirmation button in custom unit delete modal.
					'btnDelete'     => _x( 'Yes, delete unit.', 'action.delete.custom_unit', 'smart-convert-currency-unit-conversion' ),
					// "Yes, Delete"

					// NEW STRINGS FOR UPDATED JS
					// translators: English: "Edit Custom Unit". Form heading for modifying an existing configuration. This short noun phrase belongs to unit and currency management and appears at the top of Smart Convert admin pages without dynamic placeholders.
					'titleEdit'     => __( 'Edit Custom Unit', 'smart-convert-currency-unit-conversion' ),
					// "Edit Custom Unit"
					// translators: English: "Add Custom Units". Section heading where administrators configure their own mappings. This short noun phrase belongs to unit and currency management and appears at the top of Smart Convert admin pages without dynamic placeholders.
					'titleAdd'      => __( 'Add Custom Units', 'smart-convert-currency-unit-conversion' ),
					// "Add Custom Unit"
					// translators: English: "Update Unit". Main button label for saving modifications to an existing configuration. This short imperative command belongs to unit and currency management, appearing near admin forms without dynamic placeholders.
					// translators: English: "Update Unit". Primary button label for saving edits to an existing custom unit.
					'btnUpdate'     => _x( 'Update Unit', 'action.update.custom_unit', 'smart-convert-currency-unit-conversion' ),
					// "Update Unit"
					// translators: English: "Save Custom Unit". Main button label for finalizing a completely new configuration. This short imperative command belongs to unit and currency management, appearing near admin forms without dynamic placeholders.
					// translators: English: "Save Custom Unit". Primary button label for creating a new custom unit.
					'btnSave'       => _x( 'Save Custom Unit', 'action.save.custom_unit', 'smart-convert-currency-unit-conversion' ),
					// "Save Custom Unit"
					// translators: English: "Server Error:". Prefix indicating a backend failure (e.g., 500 status or database issue). This declarative text belongs to the general settings and shared UI of the Smart Convert plugin, appearing in admin notices, AJAX responses, or the frontend without dynamic placeholders.
					'errorServer'   => __( 'Server Error: ', 'smart-convert-currency-unit-conversion' ),
					// "Server Error: "
					// translators: English: "Error:". Prefix for general JavaScript or network error messages, preceding the detailed description. This declarative text belongs to the general settings and shared UI of the Smart Convert plugin, appearing in admin notices, AJAX responses, or the frontend without dynamic placeholders.
					'errorGeneric'  => __( 'Error: ', 'smart-convert-currency-unit-conversion' ),
					// "Error: "
					// translators: English: "Yes, this is available!". Positive validation message (often green) confirming an entered value is unique. This concise phrase belongs to the general settings and shared UI of the Smart Convert plugin and may appear in admin screens or frontend outputs without dynamic placeholders.
					'validationOk'  => __( 'Yes, this is available!', 'smart-convert-currency-unit-conversion' ),
					// "OK"
				)
			) );
		}
	}


	/**
	 * AJAX: Check if Unit Code exists.
	 * * Verifies if a unit code is already in use in either the units table
	 * or the currencies table to prevent collisions.
	 */
	public function ajax_check_unit_code() {
		check_ajax_referer( 'smart_convert_currency_unit_conversion_custom_unit_action' );
		// Unslash before sanitization to correctly handle escaped characters
		$code = isset( $_POST['code'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['code'] ) ) ) : '';

		if ( empty( $code ) ) {
			wp_send_json_success();
		}

		global $wpdb;

		// Use caching to satisfy Plugin Check "Direct database call without caching"
		$cache_key   = 'smart_convert_currency_unit_conversion_check_code_' . $code;
		$exists_data = wp_cache_get( $cache_key, 'smart_convert_currency_unit_conversion' );

		if ( false === $exists_data ) {
			// 1. Check in Units Table
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$exists_unit = $wpdb->get_var( $wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units WHERE unit_from = %s",
				$code
			) );

			// 2. Check in Currencies Table (Source or Target)
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery
			$exists_currency = $wpdb->get_var( $wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_currencies WHERE from_currency = %s OR to_currency = %s",
				$code, $code
			) );

			$exists_data = array(
				'unit'     => $exists_unit,
				'currency' => $exists_currency
			);

			// Cache for a short time (e.g., 60 seconds) as this is a validation check
			wp_cache_set( $cache_key, $exists_data, 'smart_convert_currency_unit_conversion', 60 );
		}

		$exists_unit     = $exists_data['unit'];
		$exists_currency = $exists_data['currency'];

		if ( $exists_unit > 0 ) {
			// translators: English: "⚠️ This code cannot be used because it is already in use by another unit.". Declarative error message shown when a code conflicts with an existing one. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
			wp_send_json_error( array( 'message' => __( '⚠️ This code cannot be used because it is already in use by another unit.', 'smart-convert-currency-unit-conversion' ) ) );
		} elseif ( $exists_currency > 0 ) {
			// translators: English: "⚠️ This code cannot be used because it is already in use by a currency.". Declarative error message shown when a custom unit code conflicts with an existing currency. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
			wp_send_json_error( array( 'message' => __( '⚠️ This code cannot be used because it is already in use by a currency.', 'smart-convert-currency-unit-conversion' ) ) );
		} else {
			wp_send_json_success();
		}
	}

/**
     * AJAX: Save Custom Unit (Create or Update).
     * * Handles the creation or modification of custom conversion units.
     * Ensures bidirectional support by creating/updating the reverse pair automatically.
     */
    public function ajax_save_custom_unit() {
        check_ajax_referer( 'smart_convert_currency_unit_conversion_custom_unit_action' );
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have permission to perform this action.". Declarative error message triggered by insufficient access rights. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_units';
        $now   = current_time( 'mysql' );

        // Check if we are Editing (ID > 0) or Creating (ID = 0)
        // Fixed: Added isset check and wp_unslash
        $edit_id   = isset( $_POST['edit_id'] ) ? absint( wp_unslash( $_POST['edit_id'] ) ) : 0;
        $is_update = ( $edit_id > 0 );

        // --- 1. GATHER DATA ---

        // FROM SIDE CONFIGURATION
        // Fixed: Validating isset, unslashing, and sanitizing key
        $mode_from = isset( $_POST['mode_from'] ) ? sanitize_key( wp_unslash( $_POST['mode_from'] ) ) : '';
        
        if ( $mode_from === 'existing' ) {
            // Fixed: Standard sanitization with unslash
            $unit_from = isset( $_POST['existing_from'] ) ? sanitize_text_field( wp_unslash( $_POST['existing_from'] ) ) : '';
            
            if ( empty( $unit_from ) ) {
                // translators: English: "Please fill in the source unit for the conversion.". Declarative error message indicating missing input for the source value. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'Please fill in the source unit for the conversion.', 'smart-convert-currency-unit-conversion' ) ) );
            }
            
            // If using existing, these remain null (DB defaults will apply or stay unchanged)
            $unit_from_name     = null;
            $symbol_from_before = null;
            $symbol_from_after  = null;
        } else {
            // Fixed: Standard sanitization with unslash
            $unit_from      = isset( $_POST['new_from_code'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['new_from_code'] ) ) ) : '';
            $unit_from_name = isset( $_POST['new_from_name'] ) ? sanitize_text_field( wp_unslash( $_POST['new_from_name'] ) ) : '';
            
            // Fixed: Using the new class method instead of closure + unslash
            $symbol_from_before = isset( $_POST['new_from_symbol_before'] ) ? $this->sanitize_unit_symbol( sanitize_text_field( wp_unslash( $_POST['new_from_symbol_before'] ) ) ) : '';
            $symbol_from_after  = isset( $_POST['new_from_symbol_after'] ) ? $this->sanitize_unit_symbol( sanitize_text_field( wp_unslash( $_POST['new_from_symbol_after'] ) ) ) : '';
        }

        // TO SIDE CONFIGURATION
        $mode_to = isset( $_POST['mode_to'] ) ? sanitize_key( wp_unslash( $_POST['mode_to'] ) ) : '';
        
        if ( $mode_to === 'existing' ) {
            $unit_to = isset( $_POST['existing_to'] ) ? sanitize_text_field( wp_unslash( $_POST['existing_to'] ) ) : '';
            
            if ( empty( $unit_to ) ) {
                // translators: English: "Please fill in the target unit for the conversion.". Declarative error message indicating missing input for the target value. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'Please fill in the target unit for the conversion.', 'smart-convert-currency-unit-conversion' ) ) );
            }
            
            $unit_to_name     = null;
            $symbol_to_before = null;
            $symbol_to_after  = null;
        } else {
            $unit_to      = isset( $_POST['new_to_code'] ) ? strtolower( sanitize_text_field( wp_unslash( $_POST['new_to_code'] ) ) ) : '';
            $unit_to_name = isset( $_POST['new_to_name'] ) ? sanitize_text_field( wp_unslash( $_POST['new_to_name'] ) ) : '';
            
            // Fixed: Using the new class method instead of closure + unslash
            $symbol_to_before = isset( $_POST['new_to_symbol_before'] ) ? $this->sanitize_unit_symbol( sanitize_text_field( wp_unslash( $_POST['new_to_symbol_before'] ) ) ) : '';
            $symbol_to_after  = isset( $_POST['new_to_symbol_after'] ) ? $this->sanitize_unit_symbol( sanitize_text_field( wp_unslash( $_POST['new_to_symbol_after'] ) ) ) : '';
        }

        // Float sanitation: handle comma decimal separators
        // Fixed: Check isset and unslash
        $factor_raw = isset( $_POST['factor'] ) ? sanitize_text_field( wp_unslash( $_POST['factor'] ) ) : '0';
        $factor_raw = str_replace( ',', '.', $factor_raw );
        $factor     = (float) $factor_raw;
        
        // --- VALIDATION ---
        if ( empty( $unit_from ) || empty( $unit_to ) ) {
            // translators: English: "The unit codes in the uploaded file violate the rules. The name may only contain characters a-z and 0-9 without spaces; unfortunately, it is not possible to continue.". Declarative error message displayed during an import with invalid formatting. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'The unit codes in the uploaded file violate the rules. The name may only contain characters a-z and 0-9 without spaces; unfortunately, it is not possible to continue.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        if ( $factor <= 0 ) {
            // translators: English: "The conversion factor between units must be greater than 0.". Declarative error message shown for invalid mathematical input. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'The conversion factor between units must be greater than 0.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        if ( $unit_from === $unit_to ) {
            // translators: English: "The \"From\" and \"To\" units must not be the same.". Declarative error message shown when identical source and target values are selected. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'The "From" and "To" units must not be the same.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        // Prepare Data Array for the primary conversion (Forward direction)
        $data_forward = array(
            'unit_from'          => $unit_from,
            'unit_to'            => $unit_to,
            'factor'             => $factor,
            'offset'             => 0.0,
            'symbol_after'       => $symbol_to_after, // Legacy column fallback
            'unit_from_name'     => $unit_from_name,
            'symbol_from_before' => $symbol_from_before,
            'symbol_from_after'  => $symbol_from_after,
            'unit_to_name'       => $unit_to_name,
            'symbol_to_before'   => $symbol_to_before,
            'symbol_to_after'    => $symbol_to_after,
            'is_custom'          => 1,
            'updated_at'         => $now
        );

        $format = array( '%s', '%s', '%f', '%f', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s' );

        // --- EXECUTION ---

        if ( $is_update ) {
            // === UPDATE LOGIC (Main + Reverse Pair) ===
            
            // 1. Fetch the OLD data to identify the existing pair
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- Reading one custom row before update.
            $old_row = $wpdb->get_row(
                $wpdb->prepare(
                    'SELECT * FROM `' . esc_sql( $table ) . '` WHERE id = %d',
                    $edit_id
                )
            );
            
            if ( ! $old_row ) {
                // translators: English: "The unit could not be found, so it cannot be edited.". Declarative error message shown when attempting to access a missing record. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'The unit could not be found, so it cannot be edited.', 'smart-convert-currency-unit-conversion' ) ) );
            }

            // 2. Update the Main Row (A -> B)
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $result = $wpdb->update( $table, $data_forward, array( 'id' => $edit_id ), $format, array( '%d' ) );
            
            if ( $result === false ) {
                // translators: English: "Bad news. A database connection error occurred while updating a custom unit.". Declarative error message indicating a server issue during an update. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'Bad news. A database connection error occurred while updating a custom unit.', 'smart-convert-currency-unit-conversion' ) ) );
            }

            // 3. Update the Reverse Pair (B -> A)
            // Logic: Find the row where unit_from == OLD_B and unit_to == OLD_A.
            $reverse_factor = 1 / $factor;
            
            $data_reverse = array(
                'unit_from'          => $unit_to, // New B
                'unit_to'            => $unit_from, // New A
                'factor'             => $reverse_factor,
                'offset'             => 0.0,
                'symbol_after'       => $symbol_from_after,
                
                // Swap names and symbols for the reverse record
                'unit_from_name'     => $unit_to_name,
                'symbol_from_before' => $symbol_to_before,
                'symbol_from_after'  => $symbol_to_after,
                
                'unit_to_name'       => $unit_from_name,
                'symbol_to_before'   => $symbol_from_before,
                'symbol_to_after'    => $symbol_from_after,
                
                'updated_at'         => $now
            );

            // Update using logical match (not ID) to ensure safety.
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $wpdb->update(
                $table, 
                $data_reverse, 
                array(
                    'unit_from' => $old_row->unit_to, // Old B
                    'unit_to'   => $old_row->unit_from, // Old A
                    'is_custom' => 1
                ), 
                $format, 
                array( '%s', '%s', '%d' )
            );
            
            // Set Flash Message for next page load
            // translators: English: "Custom unit was successfully updated - including the reverse conversion.". Positive confirmation message shown to administrators via admin notices or AJAX responses after editing. It belongs to unit and currency management and contains no dynamic placeholders.
            set_transient(
                'smart_convert_currency_unit_conversion_update_units_status',
                array(
                    'status' => 'success',
                    'message' => __( 'Custom unit was successfully updated - including the reverse conversion.', 'smart-convert-currency-unit-conversion' ),
                ),
                45
            );
            wp_send_json_success();

        } else {
            // === INSERT LOGIC (Create New) ===
            // 1. Insert Forward (A -> B)
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $res1 = $wpdb->insert( $table, $data_forward, $format );

            if ( $res1 === false ) {
                // translators: English: "Bad news. A database connection error occurred while creating a custom unit.". Declarative error message indicating a server issue during creation. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'Bad news. A database connection error occurred while creating a custom unit.', 'smart-convert-currency-unit-conversion' ) ) );
            }

            // 2. Insert Reverse (B -> A) - Auto Generated
            // Calculate inverse factor
            $factor_rev = 1 / $factor;
            
            $data_reverse = array(
                'unit_from'          => $unit_to,
                'unit_to'            => $unit_from,
                'factor'             => $factor_rev,
                'offset'             => 0.0,
                'symbol_after'       => $symbol_from_after,
                'unit_from_name'     => $unit_to_name,
                'symbol_from_before' => $symbol_to_before,
                'symbol_from_after'  => $symbol_to_after,
                'unit_to_name'       => $unit_from_name,
                'symbol_to_before'   => $symbol_from_before,
                'symbol_to_after'    => $symbol_from_after,
                'is_custom'          => 1,
                'updated_at'         => $now
            );

            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $wpdb->insert( $table, $data_reverse, $format );

            // Set Flash Message
            // translators: English: "Custom unit was successfully created!". Positive confirmation message shown to administrators via admin notices or AJAX responses after adding a new record. It belongs to unit and currency management and contains no dynamic placeholders.
            set_transient(
                'smart_convert_currency_unit_conversion_update_units_status',
                array(
                    'status' => 'success',
                    'message' => __( 'Custom unit was successfully created!', 'smart-convert-currency-unit-conversion' ),
                ),
                45
            );
            wp_send_json_success();
        }
    }
    
    /**
     * AJAX: Delete Custom Unit.
     * * Deletes a custom unit pair. It attempts to remove both the selected record
     * and its reverse counterpart to keep the database clean.
     */
public function ajax_delete_custom_unit() {
        check_ajax_referer('smart_convert_currency_unit_conversion_custom_unit_action');
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have permission to perform this action.". Declarative error message triggered by insufficient access rights. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        global $wpdb;
        // Added isset and unslash check
        $id = isset($_POST['id']) ? absint(wp_unslash($_POST['id'])) : 0;
        
        // 1. Get the row to find the pair details before deleting (with Caching)
        $cache_key_row = 'smart_convert_currency_unit_conversion_unit_row_' . $id;
        $row = wp_cache_get($cache_key_row, 'smart_convert_currency_unit_conversion');

        if (false === $row) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units WHERE id = %d", $id));
            if ($row) {
                wp_cache_set($cache_key_row, $row, 'smart_convert_currency_unit_conversion', 300);
            }
        }
        
        if (!$row) {
            // translators: English: "Unit not found.". Declarative error message displayed when attempting to edit a deleted or non-existent record. It belongs to unit and currency management and appears in WordPress admin notices, AJAX responses, or the frontend without dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'Unit not found.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        // 2. Delete the specific row
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $wpdb->delete($wpdb->prefix . 'smart_convert_currency_unit_conversion_units', ['id' => $id]);

        // 3. Try to delete the reverse pair automatically (Best effort)
        // Find row where from=to and to=from AND is_custom=1
        // We do not cache the DELETE query itself, but we should clear caches afterwards.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units WHERE unit_from = %s AND unit_to = %s AND is_custom = 1",
            $row->unit_to,
            $row->unit_from
        ));

        // Invalidate Caches after Delete
        // 1. Clear the list cache
        wp_cache_delete('smart_convert_currency_unit_conversion_admin_units_currencies_list', 'smart_convert_currency_unit_conversion');
        // 2. Clear the specific row cache
        wp_cache_delete($cache_key_row, 'smart_convert_currency_unit_conversion');

        // translators: English: "Custom unit was deleted.". Positive confirmation message shown to administrators via admin notices or AJAX responses after successful removal. It belongs to unit and currency management and contains no dynamic placeholders.
        wp_send_json_success( array( 'message' => __( 'Custom unit was deleted.', 'smart-convert-currency-unit-conversion' ) ) );
    }

    /**
     * Registers the main plugin options page in the admin menu.
     */
	public function smart_convert_currency_unit_conversion_add_plugin_page() {
		add_options_page(
			// translators: English: "Smart Convert Free". Usage: Plugin name (do not translate). It belongs to the general settings and shared UI, appearing across admin screens and frontend outputs depending on the feature. Keep it concise, with no dynamic placeholders.
			__( 'Smart Convert', 'smart-convert-currency-unit-conversion' ),
			// translators: English: "Smart Convert Free". Usage: Plugin name (do not translate). It belongs to the general settings and shared UI, appearing across admin screens and frontend outputs depending on the feature. Keep it concise, with no dynamic placeholders.
			__( 'Smart Convert', 'smart-convert-currency-unit-conversion' ),
			'manage_options',
			'smart-convert-currency-unit-conversion',
			array( $this, 'smart_convert_currency_unit_conversion_create_admin_page' )
		);
	}
    /**
     * AJAX: Save Template.
     * * Handles saving (create or update) of conversion templates via AJAX.
     * Performs validation on the template key and required fields.
     */
    public function ajax_save_template() {
        check_ajax_referer('smart_convert_currency_unit_conversion_save_template_action');
        
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_templates';
        
        // Added isset and unslash checks
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        $is_edit = ($template_id > 0);
        
        $template_key = isset($_POST['template_key']) ? sanitize_text_field(wp_unslash($_POST['template_key'])) : '';
        $template_name = isset($_POST['template_name']) ? sanitize_text_field(wp_unslash($_POST['template_name'])) : '';
        $template_output = isset($_POST['template_output']) ? wp_kses_post(wp_unslash($_POST['template_output'])) : '';
        $template_description = isset($_POST['template_description']) ? sanitize_textarea_field(wp_unslash($_POST['template_description'])) : '';
        
        $template_key = smart_convert_currency_unit_conversion_validate_template_key($template_key);
        if (!$template_key) {
            // translators: English: "Template identifier is invalid. Only characters a-z, 0-9, hyphen, and underscore are allowed.". Usage: Declarative error message clearly defining the allowed characters for a template identifier. Belonging to template management, it is displayed in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and requires a concise, readable translation.
            wp_send_json_error( array( 'message' => __( 'Template identifier is invalid. Only characters a-z, 0-9, hyphen, and underscore are allowed.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        // Check for uniqueness of the key, excluding the current template if editing
        // Assuming smart_convert_currency_unit_conversion_template_key_exists uses caching internally or is light enough.
        // If smart_convert_currency_unit_conversion_template_key_exists does a DB call, it should be wrapped in that function definition.
        if (smart_convert_currency_unit_conversion_template_key_exists($template_key, $template_id)) {
            // translators: English: "A template with this identifier already exists, please choose another one.". Usage: Declarative error message guiding users to pick a unique template identifier. Belonging to template management, it is shown in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and must be kept concise and easy to read.
            wp_send_json_error( array( 'message' => __( 'A template with this identifier already exists, please choose another one.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        if (empty($template_name) || empty($template_output)) {
            // translators: English: "You have not filled in all required fields. They must be filled in before the template can be saved.". Usage: Declarative error message clearly explaining that all required fields must be completed before saving. Belonging to template management, it is displayed in WordPress admin notices, AJAX responses, or occasionally on the frontend. It lacks dynamic placeholders and should remain concise and readable.
            wp_send_json_error( array( 'message' => __( 'You have not filled in all required fields. They must be filled in before the template can be saved.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        $now = current_time('mysql');
        
        if ($is_edit) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $result = $wpdb->update(
                $table,
                array(
                    'template_name' => $template_name,
                    'template_output' => $template_output,
                    'template_description' => $template_description,
                    'modified_at' => $now
                ),
                array('id' => $template_id),
                array('%s', '%s', '%s', '%s'),
                array('%d')
            );
            
            if ($result === false) {
                // translators: English: "Template update failed.". Error message displayed when updating a template fails (e.g., due to invalid input, a server issue, or insufficient permissions). It belongs to template management—which defines how converted values are displayed—and appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. This concise, declarative sentence requires no dynamic placeholders.
                wp_send_json_error( array( 'message' => __( 'Template update failed.', 'smart-convert-currency-unit-conversion' ) ) );
            }
            
            // Clear cache for this specific template if implemented in read functions
            // e.g., wp_cache_delete('smart_convert_currency_unit_conversion_template_' . $template_id, 'smart_convert_currency_unit_conversion');
            
            // Fetch updated template to render the card
            // Ensure this function uses caching if it calls the DB
            $template = smart_convert_currency_unit_conversion_get_template_by_id($template_id);
            
            ob_start();
            $this->render_template_card($template, false);
            $html = ob_get_clean();
            
            wp_send_json_success(array(
                // translators: English: "Template was successfully updated.". Positive confirmation message shown to administrators via admin notices or AJAX responses after a successful edit. It belongs to template management and contains no dynamic placeholders.
                'message' => __( 'Template was successfully updated.', 'smart-convert-currency-unit-conversion' ),
                'html' => $html
            ));
            
        } else {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery
            $result = $wpdb->insert(
                $table,
                array(
                    'template_key' => $template_key,
                    'template_name' => $template_name,
                    'template_output' => $template_output,
                    'template_description' => $template_description,
                    'template_type' => 'custom',
                    'is_default_currency' => 0,
                    'is_default_units' => 0,
                    'created_at' => $now,
                    'modified_at' => $now
                ),
                array('%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s')
            );
            
            if ($result === false) {
                // translators: English: "Failed to create new template.". Usage: Declarative error message cleanly explaining a failed template creation. Belonging to template management, it appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. It contains no dynamic placeholders and should remain concise and readable without strict length limits.
                wp_send_json_error( array( 'message' => __( 'Failed to create new template.', 'smart-convert-currency-unit-conversion' ) ) );
            }
            
            // Clear any list cache regarding templates
            // wp_cache_delete('smart_convert_currency_unit_conversion_templates_list', 'smart_convert_currency_unit_conversion');
            
            // translators: English: "Template was successfully created.". Positive confirmation message shown to administrators via admin notices or AJAX responses after a successful save. It belongs to template management and contains no dynamic placeholders.
            wp_send_json_success(
                array(
                    'message' => __( 'Template was successfully created.', 'smart-convert-currency-unit-conversion' ),
                )
            );
        }
    }
    /**
     * AJAX: Delete Template.
     */
    public function ajax_delete_template() {
        check_ajax_referer('smart_convert_currency_unit_conversion_delete_template_action');
        
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        // Added isset and unslash check
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        $result = smart_convert_currency_unit_conversion_delete_template($template_id);
        
        if (is_wp_error($result)) {
            wp_send_json_error(array('message' => $result->get_error_message()));
        }
        
        // translators: English: "Template was deleted.". Positive confirmation message shown to administrators via admin notices or AJAX responses after successful removal. It belongs to template management and contains no dynamic placeholders.
        wp_send_json_success( array( 'message' => __( 'Template was deleted.', 'smart-convert-currency-unit-conversion' ) ) );
    }

    /**
     * AJAX: Get Edit Form.
     * * Returns the HTML for the template edit form to be loaded into a modal or inline area.
     */
    public function ajax_get_edit_form() {
        check_ajax_referer('smart_convert_currency_unit_conversion_edit_template_action');
        
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Usage: Concise error message displayed when an operation fails (e.g., due to invalid input, server issues, or lacking permissions). It belongs to the general settings and shared UI, appearing in WordPress admin notices, AJAX responses, or occasionally on the frontend during incomplete conversions. Please use a clear declarative sentence with no dynamic placeholders.
            wp_send_json_error( array( 'message' => __( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        // Added isset and unslash check
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        $template = smart_convert_currency_unit_conversion_get_template_by_id($template_id);
        
        if (!$template) {
            // translators: English: "Template not found.". Usage: Declarative error message cleanly explaining a missing template. Belonging to template management, it appears in WordPress admin notices, AJAX responses, or occasionally on the frontend. It contains no dynamic placeholders and requires a concise, readable translation without strict length limits.
            wp_send_json_error( array( 'message' => __( 'Template not found.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        ob_start();
        ?>
        <div class="smart-convert-currency-unit-conversion-template-card">
            <div class="smart-convert-currency-unit-conversion-template-header">
                <h4 class="smart-convert-currency-unit-conversion-template-title">
                    <?php echo esc_html($template['template_name']); ?>
                    <small style="font-weight: normal; color: #646970;">(<?php echo esc_html($template['template_key']); ?>)</small>
                </h4>
            </div>
            <?php $this->render_template_form_ajax($template); ?>
        </div>
        <?php
        $html = ob_get_clean();
        
        wp_send_json_success(array('html' => $html));
    }
    /**
     * Helper to render the template form for AJAX requests.
     * * @param array $template The template data.
     */
private function render_template_form_ajax($template) {
        $template_id = $template['id'];
        $template_key = $template['template_key'];
        $template_name = $template['template_name'];
        $template_output = $template['template_output'];
        $template_description = $template['template_description'];
        
        ?>
        <form class="smart-convert-currency-unit-conversion-template-form-ajax" data-editing="true">
            <input type="hidden" name="template_id" value="<?php echo esc_attr($template_id); ?>" />
            <?php wp_nonce_field('smart_convert_currency_unit_conversion_save_template_action'); ?>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Template Identifier". Form field heading for the identifier, which is subsequently used in the output parameter. This concise noun phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders. ?>
                <?php // translators: English: "Template Key". Field label for the internal template identifier. ?>
                <label for="template_key"><?php echo esc_html( _x( 'Template Identifier', 'label.template.key', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                <input type="text" 
                       name="template_key" 
                       id="template_key" 
                       value="<?php echo esc_attr($template_key); ?>" 
                       class="regular-text" 
                       readonly />
                <?php // translators: English: "Used to uniquely identify the template and is used for formatting the conversion display (in the output parameter). The identifier may only contain characters a-z, 0-9, hyphen, and underscore. Once set, it is not recommended to change the identifier for backward compatibility reasons. If the identifier is changed, conversions on the website will stop working wherever that template is used.". Instructions for site administrators on filling out the Identifier field. It belongs to template management and appears near form fields in admin screens or block editor controls. The text should remain clear and focused on the formatting rules and backward compatibility risks, with no dynamic placeholders. ?>
                <p class="description"><?php echo esc_html__( 'Used to uniquely identify the template and is used for formatting the conversion display (in the output parameter). The identifier may only contain characters a-z, 0-9, hyphen, and underscore. Once set, it is not recommended to change the identifier for backward compatibility reasons. If the identifier is changed, conversions on the website will stop working wherever that template is used.', 'smart-convert-currency-unit-conversion' ); ?></p>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Template Name". Form field label where the term "template" must match phrasing used elsewhere on the site. This short noun phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders. ?>
                <label for="template_name"><?php echo esc_html__( 'Template Name', 'smart-convert-currency-unit-conversion' ); ?> *</label>
                <input type="text" 
                       name="template_name" 
                       id="template_name" 
                       value="<?php echo esc_attr($template_name); ?>" 
                       class="regular-text" 
                       required />
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Conversion Display Format (output)". Form field label for configuring how the converted amount is displayed, corresponding to the shortcode's output parameter. This concise noun phrase belongs to template management and may appear in admin screens or frontend outputs without dynamic placeholders. ?>
                <label for="template_output"><?php echo esc_html__( 'Conversion Display Format (output)', 'smart-convert-currency-unit-conversion' ); ?> *</label>
                <textarea name="template_output" 
                          id="template_output" 
                          rows="3" 
                          required><?php echo esc_textarea($template_output); ?></textarea>
                <?php // translators: English: "You can use the macros {FROM}, {TO}, {FROM_VALUE}, {TO_VALUE}, {FROM_CODE}, {TO_CODE}, {FROM_NAME}, {TO_NAME}, {RATE}, {RATE_INFO}. For a tooltip, use ||hover over this part##text inside the tooltip##||. Instructions for using macros and their outputs can be found in the <a href=\"?page=smart-convert-pro&tab=help\">Help</a> section.". Explanatory text for site administrators detailing available macros (which must not be translated) and tooltip creation instructions (which must be translated). It acts as a helpful hint located near form fields in admin screens or block controls. It belongs to template management and contains no dynamic placeholders. ?>
                <p class="description"><?php echo esc_html__( 'You can use the macros {FROM}, {TO}, {FROM_VALUE}, {TO_VALUE}, {FROM_CODE}, {TO_CODE}, {FROM_NAME}, {TO_NAME}, {RATE}, {RATE_INFO}. For a tooltip, use ||hover over this part##text inside the tooltip##||. Instructions for using macros and their outputs can be found in the <a href="?page=smart-convert-pro&tab=help">Help</a> section.', 'smart-convert-currency-unit-conversion' ); ?></p>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Template Description (for your internal use)". Heading of a form field where administrators can add internal notes to identify template usage. This clear, explanatory phrase belongs to template management and appears next to or below form fields in Smart Convert admin screens or block editor controls. It contains no dynamic placeholders. ?>
                <label for="template_description"><?php echo esc_html__( 'Template Description (for your internal use)', 'smart-convert-currency-unit-conversion' ); ?></label>
                <textarea name="template_description" 
                          id="template_description" 
                          rows="2"><?php echo esc_textarea($template_description); ?></textarea>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-actions">
                <button type="submit" class="button button-primary">
                    <?php // translators: English: "Save Template". Button label used while editing an existing template. This short imperative command belongs to template management and appears near forms in Smart Convert admin pages without dynamic placeholders. ?>
                    <?php echo esc_html( _x( 'Save Template', 'action.save.template', 'smart-convert-currency-unit-conversion' ) ); ?>
                </button>
                <button type="button" class="button smart-convert-currency-unit-conversion-cancel-edit-ajax">
                    <?php // translators: English: "Cancel Edits". Usage: Button allowing users to discard unsaved template changes. This generic interface text belongs to template management and may appear in admin screens or frontend outputs. It contains no dynamic placeholders, typically acts as a short noun phrase or sentence, and requires a concise, readable translation. ?>
                    <?php echo esc_html( _x( 'Cancel Edits', 'action.cancel.template_edit', 'smart-convert-currency-unit-conversion' ) ); ?>
                </button>
            </div>
        </form>
        <?php
    }

    /**
     * Renders the main admin page content.
     * * Handles tab switching logic and renders the appropriate content for
     * Settings, Templates, Rates, Units, or Help.
     */
    public function smart_convert_currency_unit_conversion_create_admin_page() {
        $this->smart_convert_currency_unit_conversion_options = get_option( 'smart_convert_currency_unit_conversion_option_name', array() ); 
    
    // Sanitize GET parameter. 
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Accessing $_GET for tab navigation (display logic only), no data modification.
    $active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'settings';
    
    // Redirect to onboarding if requested
    if ( $active_tab === 'onboarding' ) {
        $this->render_onboarding_page();
        return;
    }

    $base_url = admin_url('options-general.php?page=smart-convert-currency-unit-conversion');
        
        // START WRAPPER
        ?>
        <div class="wrap smart-convert-currency-unit-conversion-settings-wrapper">
            <?php // translators: English: "Smart Convert – Currency & Unit Conversion". Full official title of the plugin. This short noun phrase belongs to the general settings and shared UI, appearing at the top of admin sections without dynamic placeholders. ?>
            <h2><?php echo esc_html__( 'Smart Convert – Currency & Unit Conversion', 'smart-convert-currency-unit-conversion' ); ?></h2>
            
            <h2 class="nav-tab-wrapper">
                <a href="<?php echo esc_url($base_url); ?>&tab=settings" class="nav-tab <?php echo $active_tab == 'settings' ? 'nav-tab-active' : ''; ?>">
                    <?php // translators: English: "Settings". Usage: Menu tab heading for plugin configuration. It belongs to the general settings and shared UI, appearing across admin screens and frontend outputs. Keep this short noun phrase or sentence concise, with no dynamic placeholders. ?>
                    <?php echo esc_html__( 'Settings', 'smart-convert-currency-unit-conversion' ); ?>
                </a>
                <a href="<?php echo esc_url($base_url); ?>&tab=templates" class="nav-tab <?php echo $active_tab == 'templates' ? 'nav-tab-active' : ''; ?>">
                    <?php // translators: English: "Templates". Usage: Menu heading for creating conversion display formats. It belongs to the general settings and shared UI, appearing across admin screens and frontend outputs. Keep this short noun phrase concise, with no dynamic placeholders. ?>
                    <?php echo esc_html__( 'Templates', 'smart-convert-currency-unit-conversion' ); ?>
                </a>
                <a href="<?php echo esc_url($base_url); ?>&tab=rates" class="nav-tab <?php echo $active_tab == 'rates' ? 'nav-tab-active' : ''; ?>">
                    <?php // translators: English: "Current Rates". Usage: Menu tab heading displaying active exchange rates and update options. It belongs to exchange rate management and may appear across admin screens and frontend outputs. Keep this short noun phrase or sentence concise, with no dynamic placeholders. ?>
                    <?php echo esc_html__( 'Current Rates', 'smart-convert-currency-unit-conversion' ); ?>
                </a>
                <a href="<?php echo esc_url($base_url); ?>&tab=units" class="nav-tab <?php echo $active_tab == 'units' ? 'nav-tab-active' : ''; ?>">
                    <?php // translators: English: "Units". Usage: Name of the plugin administration section for listing and creating custom units. This generic interface text belongs to unit and currency management (defining, editing, or deleting) and may appear in both admin screens and frontend outputs. Variables: No dynamic placeholders. Linguistics: Usually a short noun phrase or sentence. Constraints: No strict length limit; keep it concise and easy to read. ?>
                    <?php echo esc_html__( 'Units', 'smart-convert-currency-unit-conversion' ); ?>
                </a>
                <a href="<?php echo esc_url($base_url); ?>&tab=help" class="nav-tab <?php echo $active_tab == 'help' ? 'nav-tab-active' : ''; ?>">
                    <?php // translators: English: "Help". Usage: Plugin menu tab heading providing instructions and FAQs. It belongs to the general settings and shared UI, appearing across admin screens and frontend outputs depending on the feature. Keep this short noun phrase or sentence concise, with no dynamic placeholders. ?>
                    <?php echo esc_html__( 'Help', 'smart-convert-currency-unit-conversion' ); ?>
                </a>
            </h2>

            <?php if ( $active_tab == 'settings' ) : ?>
                <form method="post" action="options.php">
                    <?php
                        settings_fields( 'smart_convert_currency_unit_conversion_option_group' );
                        do_settings_sections( 'smart-convert-currency-unit-conversion-admin' );
                        submit_button();
                    ?>
                </form>
            
            <?php elseif ( $active_tab == 'templates' ) : ?>
                <?php $this->smart_convert_currency_unit_conversion_templates_page_content(); ?>
            
            <?php elseif ( $active_tab == 'rates' ) : ?>
                <?php $this->currency_converter_rates_page_content(); ?>
            <?php elseif ( $active_tab == 'units' ) : ?>
                <?php $this->smart_convert_currency_unit_conversion_units_page_content(); ?>
            <?php elseif ( $active_tab == 'help' ) : ?>
                <?php $this->currency_converter_help_page_content(); ?>

            <?php endif; ?>
        </div>
        <?php 
    }

    /**
     * Renders the content for the "Templates" tab.
     * * Displays default template selectors, import/export options,
     * the creation form, and lists of existing builtin and custom templates.
     */
    public function smart_convert_currency_unit_conversion_templates_page_content() {
        // Enqueue inline styles for templates page
    wp_register_style( 'smart-convert-currency-unit-conversion-templates-page-inline', false, array(), SMART_CONVERT_VERSION );
    wp_enqueue_style( 'smart-convert-currency-unit-conversion-templates-page-inline' );
    
    $templates_css = "
        .smart-convert-currency-unit-conversion-templates-container { margin-top: 20px; }
        .smart-convert-currency-unit-conversion-template-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }
        .smart-convert-currency-unit-conversion-template-title {
            font-size: 16px;
            font-weight: 600;
            margin: 0;
        }
        .smart-convert-currency-unit-conversion-template-badges {
            display: flex;
            gap: 8px;
        }
        .smart-convert-currency-unit-conversion-template-body {
            margin-bottom: 15px;
        }
        .smart-convert-currency-unit-conversion-template-field {
            margin-bottom: 12px;
        }
        .smart-convert-currency-unit-conversion-template-field label {
            display: block;
            font-weight: 600;
            margin-bottom: 4px;
        }
        .smart-convert-currency-unit-conversion-template-field input[type=\"text\"],
        .smart-convert-currency-unit-conversion-template-field textarea {
            width: 100%;
            max-width: 600px;
        }
        .smart-convert-currency-unit-conversion-template-field textarea {
            font-family: 'Courier New', monospace;
            font-size: 13px;
        }
        .smart-convert-currency-unit-conversion-template-preview-label {
            font-weight: 600;
            margin-bottom: 8px;
            color: #50575e;
        }
        .smart-convert-currency-unit-conversion-template-actions {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }
        .smart-convert-currency-unit-conversion-default-selectors {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 30px;
        }
        @media (max-width: 782px) {
            .smart-convert-currency-unit-conversion-default-selectors {
                grid-template-columns: 1fr;
            }
        }
    ";
    
    wp_add_inline_style('smart-convert-currency-unit-conversion-templates-page-inline', $templates_css);


        // Handle Flash Messages
        $flash = get_transient('smart_convert_currency_unit_conversion_template_flash');
        if ($flash) {
            delete_transient('smart_convert_currency_unit_conversion_template_flash');
            $class = ($flash['status'] === 'success') ? 'notice-success' : 'notice-error';
            echo '<div class="notice ' . esc_attr($class) . ' is-dismissible"><p><strong>' . esc_html($flash['message']) . '</strong></p></div>';
        }
        
        $templates = smart_convert_currency_unit_conversion_get_all_templates();
        $builtin = array_filter($templates, function($t) { return $t['template_type'] === 'builtin'; });
        $custom = array_filter($templates, function($t) { return $t['template_type'] === 'custom'; });
        
        $default_currency_template = smart_convert_currency_unit_conversion_get_default_currency_template();
        $default_units_template = smart_convert_currency_unit_conversion_get_default_units_template();
        
        ?>

        <div class="smart-convert-currency-unit-conversion-templates-container">
            
            <div class="smart-convert-currency-unit-conversion-default-selectors smart-convert-currency-unit-conversion-box-tools">
                <div class="smart-convert-currency-unit-conversion-default-selector smart-convert-currency-unit-conversion-default-no-bottom-margin">
                    <?php // translators: English: "Default Template for Currency Conversions". Usage: Settings section heading for selecting the primary currency display template. This generic interface text belongs to template management and may appear in admin screens or frontend outputs. It contains no dynamic placeholders, usually functions as a short noun phrase or sentence, and should be kept concise and readable. ?>
                    <h3><?php echo esc_html__( 'Default Template for Currency Conversions', 'smart-convert-currency-unit-conversion' ); ?></h3>
                    <?php // translators: English: "This template will be automatically used for all currency conversions unless specified otherwise in the shortcode.". Usage: Explanatory helper text clarifying default template fallback behavior when shortcode output parameters are omitted. Directed at administrators, it appears near form fields in Smart Convert admin screens or block editor controls. It contains no dynamic placeholders, acts as a short phrase or sentence, and can exceed standard label lengths while staying clear. ?>
                    <p class="description"><?php echo esc_html__( 'This template will be automatically used for all currency conversions unless specified otherwise in the shortcode.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                        <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_set_default_template" />
                        <input type="hidden" name="template_type" value="currency" />
                        <?php wp_nonce_field('smart_convert_currency_unit_conversion_set_default_template_action'); ?>
                        <select name="template_id" class="regular-text">
                            <?php foreach ($templates as $t): ?>
                                <option value="<?php echo esc_attr($t['id']); ?>" <?php selected($t['id'], $default_currency_template['id']); ?>>
                                    <?php echo esc_html($t['template_name']); ?>
                                    <?php // translators: English: "System". Badge for built-in templates in selector options. ?>
                                    <?php if ($t['template_type'] === 'builtin') echo ' [' . esc_html__( 'System', 'smart-convert-currency-unit-conversion' ) . ']'; ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <?php
                        // translators: English: "Set as Default". Button text used to make the selected template the default option. This short noun phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders.
                        submit_button( esc_html__( 'Set as Default', 'smart-convert-currency-unit-conversion' ), 'secondary', 'submit', false );
                        ?>
                    </form>
                </div>
                
                <div class="smart-convert-currency-unit-conversion-default-selector smart-convert-currency-unit-conversion-box-tools smart-convert-currency-unit-conversion-default-no-bottom-margin">
                    <?php // translators: English: "Default Template for Unit Conversions". Usage: Settings section heading for selecting the primary unit conversion display template. This generic interface string belongs to unit management and may appear in Smart Convert admin screens or frontend outputs. It lacks dynamic placeholders, typically acts as a short noun phrase or sentence, and should be kept concise and readable without strict length limits. ?>
                    <h3><?php echo esc_html__( 'Default Template for Unit Conversions', 'smart-convert-currency-unit-conversion' ); ?></h3>
                    <?php // translators: English: "The selected template will be used as the default for all unit conversions unless specified otherwise in the shortcode.". Usage: Explanatory helper text clarifying default unit template fallback behavior when shortcode output parameters are omitted. Directed at administrators, it appears near form fields in Smart Convert admin screens or block editor controls. It lacks dynamic placeholders, acts as a short phrase or sentence, and can exceed standard label lengths while staying clear. ?>
                    <p class="description"><?php echo esc_html__( 'The selected template will be used as the default for all unit conversions unless specified otherwise in the shortcode.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                        <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_set_default_template" />
                        <input type="hidden" name="template_type" value="units" />
                        <?php wp_nonce_field('smart_convert_currency_unit_conversion_set_default_template_action'); ?>
                        <select name="template_id" class="regular-text">
                            <?php foreach ($templates as $t): ?>
                                <option value="<?php echo esc_attr($t['id']); ?>" <?php selected($t['id'], $default_units_template['id']); ?>>
                                    <?php echo esc_html($t['template_name']); ?>
                                    <?php // translators: English: "System". Badge for built-in templates in selector options. ?>
                                    <?php if ($t['template_type'] === 'builtin') echo ' [' . esc_html__( 'System', 'smart-convert-currency-unit-conversion' ) . ']'; ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <?php
                        // translators: English: "Set as Default". Button text used to make the selected template the default option. This short noun phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders.
                        submit_button( esc_html__( 'Set as Default', 'smart-convert-currency-unit-conversion' ), 'secondary', 'submit', false );
                        ?>
                    </form>
                </div>
            </div>

            <div class="smart-convert-currency-unit-conversion-import-export smart-convert-currency-unit-conversion-template-card smart-convert-currency-unit-conversion-box-tools">
                <?php // translators: English: "Export and Import Templates". Section heading for exporting and importing templates. This concise noun phrase belongs to template management and may appear in both admin screens and frontend outputs without dynamic placeholders. ?>
                <h3><?php echo esc_html__( 'Export and Import Templates', 'smart-convert-currency-unit-conversion' ); ?></h3>
                
                <div style="margin-bottom: 20px;">
                    <h4>📤 <?php
                    // translators: English: "Export Templates". Section heading for exporting templates into a JSON file. This short noun phrase belongs to template management and appears at the top of Smart Convert admin pages or sections without dynamic placeholders.
                    echo esc_html__( 'Export Templates', 'smart-convert-currency-unit-conversion' ); ?></h4>
                    <p class="description"><?php
                    // translators: English: "You can export all custom templates as a JSON file. This allows you to back them up or easily import them to another WordPress site using the Smart Convert Free plugin.". Explanatory text detailing the export process and its benefits. It acts as a helpful hint for site administrators, located next to or below form fields in the Smart Convert admin screens or block editor controls. The text belongs to template management, uses no dynamic placeholders, and should remain clear and focused.
                    echo esc_html__( 'You can export all custom templates as a JSON file. This allows you to back them up or easily import them to another WordPress site using the Smart Convert Free plugin.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                        <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_export_templates" />
                        <?php wp_nonce_field('smart_convert_currency_unit_conversion_export_templates_action'); ?>
                        <?php // translators: English: "Export All Templates". Button label for exporting templates as JSON. ?>
                        <?php submit_button( esc_html__( 'Export All Templates', 'smart-convert-currency-unit-conversion' ), 'secondary', 'submit', false ); ?>
                    </form>
                </div>
                
                <div>
                    <h4>📥
                        <?php // translators: English: "Import Templates". Section heading for importing templates from JSON. ?>
                        <?php echo esc_html__( 'Import Templates', 'smart-convert-currency-unit-conversion' ); ?>
                    </h4>
                    <p class="description"><?php // translators: English: "Import custom templates from a JSON file exported from another site.". Helper description for template import workflow. ?><?php echo esc_html__( 'Upload a JSON file with templates from this or another website with the Smart Convert Free plugin. Templates with an already existing identifier will be skipped.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data">
                        <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_import_templates" />
                        <?php wp_nonce_field('smart_convert_currency_unit_conversion_import_templates_action'); ?>
                        <input type="file" name="template_file" accept=".json" required />
                        <?php // translators: English: "Import Templates". Button label for importing templates from JSON. ?>
                        <?php submit_button( esc_html__( 'Import Templates', 'smart-convert-currency-unit-conversion' ), 'secondary', 'submit', false ); ?>
                    </form>
                </div>
            </div>

            <div class="smart-convert-currency-unit-conversion-template-card smart-convert-currency-unit-conversion-box-create">
                <h3>
                    <?php // translators: English: "Create Custom Template". Section heading for creating a new custom template. ?>
                    <?php echo esc_html__( 'Create Custom Template', 'smart-convert-currency-unit-conversion' ); ?>
                </h3>
                <?php $this->render_template_form(); ?>
            </div>

                <h3>
                    <?php // translators: English: "Built-in Templates". Section heading listing system templates. ?>
                    <?php echo esc_html__( 'System Templates', 'smart-convert-currency-unit-conversion' ); ?>
                </h3>
            <?php foreach ($builtin as $template): ?>
                <?php $this->render_template_card($template, true); ?>
            <?php endforeach; ?>

            <?php if (!empty($custom)): ?>
                <h3>
                    <?php // translators: English: "Custom Templates". Section heading listing user-created templates. ?>
                    <?php echo esc_html__( 'Custom Templates Overview', 'smart-convert-currency-unit-conversion' ); ?>
                </h3>
                <?php foreach ($custom as $template): ?>
                    <?php $this->render_template_card($template, false); ?>
                <?php endforeach; ?>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * Renders a single template card (Built-in or Custom).
     * * @param array $template The template data array.
     * @param bool $is_builtin Whether the template is a system built-in template.
     */
private function render_template_card($template, $is_builtin = false) {
        // Sanitize GET parameter - using wp_unslash before sanitization
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Accessing $_GET to determine UI state (editing mode), no data modification.
        $get_template_id = isset($_GET['edit_template']) ? absint(wp_unslash($_GET['edit_template'])) : 0;
        $is_editing = ($get_template_id == $template['id']);
        
        $is_default_currency = $template['is_default_currency'] == 1;
        $is_default_units = $template['is_default_units'] == 1;
        
        ?>
        <div class="smart-convert-currency-unit-conversion-template-card <?php echo $is_builtin ? 'builtin' : ''; ?> smart-convert-currency-unit-conversion-box-data">
            <div class="smart-convert-currency-unit-conversion-template-header">
                <h4 class="smart-convert-currency-unit-conversion-template-title">
                    <?php echo esc_html($template['template_name']); ?>
                    <small style="font-weight: normal; color: #646970;">(<?php echo esc_html($template['template_key']); ?>)</small>
                </h4>
                <div class="smart-convert-currency-unit-conversion-template-badges">
                    <?php if ($is_builtin): ?>
                        <span class="smart-convert-currency-unit-conversion-badge builtin">
                            <?php // translators: English: "System". Badge text for built-in template cards. ?>
                            <?php echo esc_html__( 'System', 'smart-convert-currency-unit-conversion' ); ?>
                        </span>
                    <?php endif; ?>
                    <?php if ($is_default_currency): ?>
                        <span class="smart-convert-currency-unit-conversion-badge default"><?php // translators: English: "Default for Currency". Badge indicating default currency template. ?><?php echo esc_html__( 'Default for Currencies', 'smart-convert-currency-unit-conversion' ); ?></span>
                    <?php endif; ?>
                    <?php if ($is_default_units): ?>
                        <span class="smart-convert-currency-unit-conversion-badge default"><?php // translators: English: "Default for Units". Badge indicating default unit template. ?><?php echo esc_html__( 'Default for Units', 'smart-convert-currency-unit-conversion' ); ?></span>
                    <?php endif; ?>
                </div>
            </div>

            <?php if ($is_editing && !$is_builtin): ?>
                <?php $this->render_template_form($template); ?>
            <?php else: ?>
                <div class="smart-convert-currency-unit-conversion-template-body">
                    <?php if (!empty($template['template_description'])): ?>
                        <p class="description"><?php echo esc_html($template['template_description']); ?></p>
                    <?php endif; ?>
                    
                    <div class="smart-convert-currency-unit-conversion-template-field">
                        <label>
                            <?php // translators: English: "Output Template". Field label showing template output format string. ?>
                            <?php echo esc_html__( 'Conversion Display Format (output)', 'smart-convert-currency-unit-conversion' ); ?>
                        </label>
                        <code style="background: #f0f0f1; padding: 4px 8px; display: inline-block;">
                            <?php echo esc_html($template['template_output']); ?>
                        </code>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-template-field">
                        <div class="smart-convert-currency-unit-conversion-template-preview-label">
                            <?php // translators: English: "Preview". Label for rendered template output preview. ?>
                            <?php echo esc_html__( 'Template Preview', 'smart-convert-currency-unit-conversion' ); ?>
                        </div>
                    <div class="smart-convert-currency-unit-conversion-template-preview">
                        <?php 
                            // Determine if this is a Units template (Built-in 'units' OR set as Default Units)
                            $is_units_preview = ($template['template_key'] === 'units' || $template['is_default_units'] == 1);
                            
                            // Pass the flag to the generator
                            // Use wp_kses_post to allow safe HTML in the preview while satisfying the "OutputNotEscaped" check
                            echo wp_kses_post($this->generate_template_preview($template['template_output'], $is_units_preview)); 
                        ?>
                    </div>
                    </div>
                </div>

                <div class="smart-convert-currency-unit-conversion-template-actions">
        <?php if (!$is_builtin): ?>
            <button type="button" 
                    class="button smart-convert-currency-unit-conversion-edit-template-ajax" 
                    data-template-id="<?php echo esc_attr($template['id']); ?>"
                    data-nonce="<?php echo esc_attr(wp_create_nonce('smart_convert_currency_unit_conversion_edit_template_action')); ?>">
                <?php // translators: English: "Edit Template". Action button label in template list. ?>
                <?php echo esc_html( _x( 'Edit Template', 'action.edit.template', 'smart-convert-currency-unit-conversion' ) ); ?>
            </button>
        <?php endif; ?>
        
        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display: inline;">
            <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_duplicate_template" />
            <input type="hidden" name="template_id" value="<?php echo esc_attr($template['id']); ?>" />
            <?php wp_nonce_field('smart_convert_currency_unit_conversion_duplicate_template_action'); ?>
            <button type="submit" class="button">
                <?php // translators: English: "Duplicate". Action button to duplicate a template. ?>
                <?php echo esc_html__( 'Duplicate Template', 'smart-convert-currency-unit-conversion' ); ?>
            </button>
        </form>
        
        <?php if (!$is_builtin && !$is_default_currency && !$is_default_units): ?>
            <button type="button" 
                    class="button button-link-delete smart-convert-currency-unit-conversion-delete-template-ajax"
                    data-template-id="<?php echo esc_attr($template['id']); ?>"
                    data-nonce="<?php echo esc_attr(wp_create_nonce('smart_convert_currency_unit_conversion_delete_template_action')); ?>">
                <?php // translators: English: "Delete Template". Destructive action button label in template list. ?>
                <?php echo esc_html( _x( 'Delete Template', 'action.delete.template', 'smart-convert-currency-unit-conversion' ) ); ?>
            </button>
        <?php endif; ?>
    </div>
            <?php endif; ?>
        </div>
        <?php
    }
    /**
     * Renders the template creation/editing form.
     * * @param array|null $template The template data if editing, or null if creating new.
     */
    private function render_template_form($template = null) {
        $is_edit = ($template !== null);
        $template_id = $is_edit ? $template['id'] : 0;
        $template_key = $is_edit ? $template['template_key'] : '';
        $template_name = $is_edit ? $template['template_name'] : '';
        $template_output = $is_edit ? $template['template_output'] : '';
        $template_description = $is_edit ? $template['template_description'] : '';
        
        ?>
        <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
            <input type="hidden" name="action" value="smart_convert_currency_unit_conversion_save_template" />
            <?php if ($is_edit): ?>
                <input type="hidden" name="template_id" value="<?php echo esc_attr($template_id); ?>" />
            <?php endif; ?>
            <?php wp_nonce_field('smart_convert_currency_unit_conversion_save_template_action'); ?>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Template Key". Field label for the internal template identifier. ?>
                <label for="template_key"><?php echo esc_html( _x( 'Template Identifier', 'label.template.key', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                <input type="text" 
                       name="template_key" 
                       id="template_key" 
                       value="<?php echo esc_attr($template_key); ?>" 
                       class="regular-text" 
                       pattern="[a-z0-9_-]+" 
                       maxlength="100"
                       <?php // translators: English: "e.g. currency_compact". Placeholder example for template key input. ?>
                       placeholder="<?php echo esc_attr__( 'my-template', 'smart-convert-currency-unit-conversion' ); ?>" 
                       required 
                       <?php echo $is_edit ? 'readonly' : ''; ?> />
                <p class="description"><?php // translators: English: "Use only lowercase letters, numbers, hyphen and underscore.". Helper text for template key format. ?><?php echo esc_html__( 'Used to uniquely identify the template and is used for formatting the conversion display (in the output parameter). The identifier may only contain characters a-z, 0-9, hyphen, and underscore. Once set, it is not recommended to change the identifier for backward compatibility reasons. If the identifier is changed, conversions on the website will stop working wherever that template is used.', 'smart-convert-currency-unit-conversion' ); ?></p>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <?php // translators: English: "Template Name". Field label for the human-readable template name. ?>
                <label for="template_name"><?php echo esc_html( _x( 'Template Name', 'label.template.name', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                <input type="text" 
                       name="template_name" 
                       id="template_name" 
                       value="<?php echo esc_attr($template_name); ?>" 
                       class="regular-text" 
                       maxlength="200"
                       <?php // translators: English: "My Compact Output". Placeholder example for template name input. ?>
                       placeholder="<?php echo esc_attr__( 'My Template', 'smart-convert-currency-unit-conversion' ); ?>"                        
                       required />
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <label for="template_output">
                    <?php // translators: English: "Output Template". Field label for template output pattern. ?>
                    <?php echo esc_html__( 'Conversion Display Format (output)', 'smart-convert-currency-unit-conversion' ); ?> *
                </label>
                <textarea name="template_output" 
                          id="template_output" 
                          rows="3" 
                          <?php // translators: English: "%amount% %from% = %result% %to%". Placeholder example for output format. ?>
                          placeholder="<?php echo esc_attr__( '||{TO}##<strong>{FROM}</strong><br><em>{RATE_INFO}</em>##||', 'smart-convert-currency-unit-conversion' ); ?>"                           
                          required><?php echo esc_textarea($template_output); ?></textarea>
                <p class="description"><?php // translators: English: "Available placeholders: %amount%, %from%, %to%, %result%, %rate%, %date%.". Helper text for output placeholders. ?><?php echo esc_html__( 'You can use the macros {FROM}, {TO}, {FROM_VALUE}, {TO_VALUE}, {FROM_CODE}, {TO_CODE}, {FROM_NAME}, {TO_NAME}, {RATE}, {RATE_INFO}. For a tooltip, use ||hover over this part##text inside the tooltip##||. Instructions for using macros and their outputs can be found in the <a href="?page=smart-convert-pro&tab=help">Help</a> section.', 'smart-convert-currency-unit-conversion' ); ?></p>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-field">
                <label for="template_description">
                    <?php // translators: English: "Description". Optional field label for template description. ?>
                    <?php echo esc_html__( 'Template Description (for your internal use)', 'smart-convert-currency-unit-conversion' ); ?>
                </label>
                <textarea name="template_description" 
                          id="template_description" 
                          <?php // translators: English: "Optional notes about this template". Placeholder for optional description field. ?>
                          placeholder="<?php echo esc_attr__( 'Template with original amount hidden in a tooltip and exchange rate information written in italics.', 'smart-convert-currency-unit-conversion' ); ?>"                           
                          rows="2"><?php echo esc_textarea($template_description); ?></textarea>
            </div>
            
            <div class="smart-convert-currency-unit-conversion-template-actions">
                <?php
                // translators: English: "Save Template" and "Create Template". Primary submit labels in template form for edit/create modes.
                submit_button(
                    $is_edit
                        ? esc_html( _x( 'Save Template', 'action.save.template', 'smart-convert-currency-unit-conversion' ) )
                        : esc_html__( 'Create Template', 'smart-convert-currency-unit-conversion' ),
                    'primary', 
                    'submit', 
                    false
                ); ?>
                
                <?php if ($is_edit): ?>
                    <a href="<?php echo esc_url(add_query_arg('tab', 'templates', admin_url('options-general.php?page=smart-convert-currency-unit-conversion'))); ?>" 
                       class="button">
                        <?php // translators: English: "Cancel". Action link label to leave template edit mode. ?>
                        <?php echo esc_html__( 'Cancel Edits', 'smart-convert-currency-unit-conversion' ); ?>
                    </a>
                <?php endif; ?>
            </div>
        </form>
        <?php
    }
/**
     * Generates a live preview of the template output.
     * Uses the plugin's shortcode logic to simulate what the user would see.
     * * @param string $template_output The output format string.
     * @param bool $is_units Whether to simulate a Unit conversion (F->C) or Currency (USD->EUR).
     * @return string HTML for the preview.
     */
    private function generate_template_preview($template_output, $is_units = false) {
        $options = get_option('smart_convert_currency_unit_conversion_option_name');
        
        // Default Logic (Currencies)
        $default_currency = isset($options['smart_convert_currency_unit_conversion_default_currency']) ? strtoupper($options['smart_convert_currency_unit_conversion_default_currency']) : 'USD';
        
        if ($is_units) {
            // === LOGIC FOR UNITS ===
            // Use Temperature (F to C) as the standard preview example for units
            $from = 'F';
            $to = 'C';
            $amount = '100';
            $decimals = '1';
        } else {
            // === LOGIC FOR CURRENCIES ===
            $from = ($default_currency === 'USD') ? 'EUR' : 'USD';
            $to = $default_currency;
            $amount = '100';
            $decimals = '2';
        }
        
        $preview_shortcode_atts = array(
            'amount'   => $amount,
            'from'     => $from,
            'to'       => $to,
            'decimals' => $decimals,
            'output'   => $template_output
        );
        
        if (function_exists('smart_convert_currency_unit_conversion_shortcode')) {
            // Return raw HTML only.
            // Styles are now handled in smart-convert-currency-unit-conversion-admin.css and colors via wp_add_inline_style.
            // This prevents wp_kses_post from stripping the <style> tags in the UI.
            return smart_convert_currency_unit_conversion_shortcode($preview_shortcode_atts);
        }
        
        // translators: English: "Preview unavailable". Fallback text when preview renderer is not available.
        return '<em>' . esc_html__( 'Template preview is not available', 'smart-convert-currency-unit-conversion' ) . '</em>';
    }

    /**
     * POST Handler: Save Template.
     * Fallback for standard form submission to save templates.
     */
    public function smart_convert_currency_unit_conversion_save_template() {
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_key(wp_unslash($_POST['_wpnonce'])), 'smart_convert_currency_unit_conversion_save_template_action')) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_templates';
        
        // Use wp_unslash before sanitization
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        $is_edit = ($template_id > 0);
        
        $template_key = isset($_POST['template_key']) ? sanitize_text_field(wp_unslash($_POST['template_key'])) : '';
        $template_name = isset($_POST['template_name']) ? sanitize_text_field(wp_unslash($_POST['template_name'])) : '';
        // Use wp_kses_post for output field to allow HTML/Safe tags but prevent XSS
        $template_output = isset($_POST['template_output']) ? wp_kses_post(wp_unslash($_POST['template_output'])) : '';
        $template_description = isset($_POST['template_description']) ? sanitize_textarea_field(wp_unslash($_POST['template_description'])) : '';
        
        $template_key = smart_convert_currency_unit_conversion_validate_template_key($template_key);
        if (!$template_key) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                // translators: English: "Invalid template key.". Flash error when key format validation fails.
                'message' => esc_html__( 'Template identifier is invalid. Only characters a-z, 0-9, hyphen, and underscore are allowed.', 'smart-convert-currency-unit-conversion' )
            ), 30);
            wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
            exit;
        }
        
        if (smart_convert_currency_unit_conversion_template_key_exists($template_key, $template_id)) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                // translators: English: "Template key already exists.". Flash error for duplicate template key.
                'message' => esc_html__( 'A template with this identifier already exists, please choose another one.', 'smart-convert-currency-unit-conversion' )
            ), 30);
            wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
            exit;
        }
        
        if (empty($template_name) || empty($template_output)) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                // translators: English: "Please fill in all required fields.". Flash error when required fields are empty.
                'message' => esc_html__( 'You have not filled in all required fields. They must be filled in before the template can be saved.', 'smart-convert-currency-unit-conversion' )
            ), 30);
            wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
            exit;
        }
        
        $now = current_time('mysql');
        
        if ($is_edit) {
            $result = $wpdb->update(
                $table,
                array(
                    'template_name' => $template_name,
                    'template_output' => $template_output,
                    'template_description' => $template_description,
                    'modified_at' => $now
                ),
                array('id' => $template_id),
                array('%s', '%s', '%s', '%s'),
                array('%d')
            );
            
            if ($result === false) {
                set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                    'status' => 'error',
                    // translators: English: "Failed to update template.". Flash error after failed template update.
                    'message' => esc_html__( 'Template update failed.', 'smart-convert-currency-unit-conversion' )
                ), 30);
            } else {
                // Clear cache after update
                wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion_templates');
                
                set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                    'status' => 'success',
                    // translators: English: "Template updated successfully.". Flash success after template update.
                    'message' => esc_html__( 'Template was successfully updated.', 'smart-convert-currency-unit-conversion' )
                ), 30);
            }
        } else {
            $result = $wpdb->insert(
                $table,
                array(
                    'template_key' => $template_key,
                    'template_name' => $template_name,
                    'template_output' => $template_output,
                    'template_description' => $template_description,
                    'template_type' => 'custom',
                    'is_default_currency' => 0,
                    'is_default_units' => 0,
                    'created_at' => $now,
                    'modified_at' => $now
                ),
                array('%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s')
            );
            
            if ($result === false) {
                set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                    'status' => 'error',
                    // translators: English: "Failed to create template.". Flash error after failed template creation.
                    'message' => esc_html__( 'Failed to create new template.', 'smart-convert-currency-unit-conversion' )
                ), 30);
            } else {
                // Clear cache after insert
                wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion_templates');
                
                set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                    'status' => 'success',
                    // translators: English: "Template created successfully.". Flash success after template creation.
                    'message' => esc_html__( 'Template was successfully created.', 'smart-convert-currency-unit-conversion' )
                ), 30);
            }
        }
        
        wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
        exit;
    }

    /**
     * POST Handler: Delete Template.
     */
    public function smart_convert_currency_unit_conversion_delete_template() {
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_key(wp_unslash($_POST['_wpnonce'])), 'smart_convert_currency_unit_conversion_delete_template_action')) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        
        $result = smart_convert_currency_unit_conversion_delete_template($template_id);
        
        if (is_wp_error($result)) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                'message' => esc_html($result->get_error_message())
            ), 30);
        } else {
            // Clear cache after delete
            wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion');
            
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'success',
                // translators: English: "Template deleted successfully.". Flash success after template deletion.
                'message' => esc_html__( 'Template was deleted.', 'smart-convert-currency-unit-conversion' )
            ), 30);
        }
        
        wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
        exit;
    }

    /**
     * POST Handler: Duplicate Template.
     * Creates a copy of an existing template, appending '_copy' to the key.
     */
    public function smart_convert_currency_unit_conversion_duplicate_template() {
        if (!current_user_can('manage_options')) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_key(wp_unslash($_POST['_wpnonce'])), 'smart_convert_currency_unit_conversion_duplicate_template_action')) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_templates';
        
        $template_id = isset($_POST['template_id']) ? absint(wp_unslash($_POST['template_id'])) : 0;
        $original = smart_convert_currency_unit_conversion_get_template_by_id($template_id);
        
        if (!$original) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                // translators: English: "Template not found.". Flash error when requested template does not exist.
                'message' => esc_html__( 'Template not found.', 'smart-convert-currency-unit-conversion' )
            ), 30);
            wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
            exit;
        }
        
        // Generate unique key
        $base_key = $original['template_key'];
        $counter = 1;
        $new_key = $base_key . '_copy';
        
        while (smart_convert_currency_unit_conversion_template_key_exists($new_key)) {
            $counter++;
            $new_key = $base_key . '_copy_' . $counter;
        }
        
        $now = current_time('mysql');
        
        $result = $wpdb->insert(
            $table,
            array(
                'template_key' => $new_key,
                // translators: English: "Copy". Suffix appended to duplicated template name.
                'template_name' => $original['template_name'] . ' (' . esc_html__( 'Copy', 'smart-convert-currency-unit-conversion' ) . ')',
                'template_output' => $original['template_output'],
                'template_description' => $original['template_description'],
                'template_type' => 'custom', 
                'is_default_currency' => 0,
                'is_default_units' => 0,
                'created_at' => $now,
                'modified_at' => $now
            ),
            array('%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s')
        );
        
        if ($result === false) {
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'error',
                // translators: English: "Failed to duplicate template.". Flash error after failed template duplication.
                'message' => esc_html__( 'Failed to create template duplicate.', 'smart-convert-currency-unit-conversion' )
            ), 30);
        } else {
            // Clear cache after duplication
            wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion');
            
            set_transient('smart_convert_currency_unit_conversion_template_flash', array(
                'status' => 'success',
                // translators: English: "Template duplicated successfully.". Flash success after template duplication.
                'message' => esc_html__( 'Template was duplicated.', 'smart-convert-currency-unit-conversion' )
            ), 30);
        }
        
        wp_safe_redirect(admin_url('options-general.php?page=smart-convert-currency-unit-conversion&tab=templates'));
        exit;
    }


/**
     * POST Handler: Set Default Template.
     * Switches the default template for either Currency or Units.
     * Logic ensures only one template is marked as default per type.
     */
    public function smart_convert_currency_unit_conversion_set_default_template() {
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'smart_convert_currency_unit_conversion_set_default_template_action' ) ) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_templates';
        
        // Unslash and sanitize inputs
        $template_id   = isset( $_POST['template_id'] ) ? absint( wp_unslash( $_POST['template_id'] ) ) : 0;
        $template_type = isset( $_POST['template_type'] ) ? sanitize_key( wp_unslash( $_POST['template_type'] ) ) : '';
        
        if ( ! in_array( $template_type, array( 'currency', 'units' ), true ) ) {
            // translators: English: "Invalid template type.". Error shown when template type is not allowed.
            wp_die( esc_html__( 'Template type is invalid.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Whitelist the column name to allow safe interpolation and satisfy static analysis
        $field = ( 'currency' === $template_type ) ? 'is_default_currency' : 'is_default_units';
        
        // Reset all to 0. 
        // Note: Column names ($field) cannot be prepared in $wpdb->prepare, but $field is strictly whitelisted above.
        // We use string interpolation here which is safe due to the logic above.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table/column identifiers are internal and strictly whitelisted.
        $wpdb->query( 'UPDATE `' . esc_sql( $table ) . '` SET `' . esc_sql( $field ) . '` = 0' );
        
        // Set the selected one to 1
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Required update in custom table.
        $result = $wpdb->update(
            $table,
            array( $field => 1 ),
            array( 'id' => $template_id ),
            array( '%d' ),
            array( '%d' )
        );
        
        if ( $result === false ) {
            set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
                'status'  => 'error',
                // translators: English: "Failed to set default template.". Flash error when default update fails.
                'message' => __( 'Failed to set default template.', 'smart-convert-currency-unit-conversion' )
            ), 30 );
        } else {
            // Clear cache after update
            wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion');
            
            set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
                'status'  => 'success',
                // translators: English: "Default template updated.". Flash success after default template update.
                'message' => __( 'Default template has been set.', 'smart-convert-currency-unit-conversion' )
            ), 30 );
        }
        
        wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=templates' ) );
        exit;
    }

    /**
     * POST Handler: Export Templates.
     * Generates a JSON file download of all custom templates.
     */
    public function smart_convert_currency_unit_conversion_export_templates() {
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'smart_convert_currency_unit_conversion_export_templates_action' ) ) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        $templates = smart_convert_currency_unit_conversion_get_all_templates();
        
        // Filter for custom templates only
        $custom_templates = array_filter( $templates, function( $t ) {
            return $t['template_type'] === 'custom';
        } );
        
        $export_data = array(
            'version'     => '1.0',
            'exported_at' => current_time( 'mysql' ),
            'templates'   => array_map( function( $t ) {
                return array(
                    'template_key'         => $t['template_key'],
                    'template_name'        => $t['template_name'],
                    'template_output'      => $t['template_output'],
                    'template_description' => $t['template_description']
                );
            }, $custom_templates )
        );
        
        header( 'Content-Type: application/json' );
        // Use gmdate instead of date to fix restricted function error
        header( 'Content-Disposition: attachment; filename="smart-convert-currency-unit-conversion-templates-' . gmdate( 'Y-m-d' ) . '.json"' );
        header( 'Cache-Control: no-cache, must-revalidate' );
        
        echo wp_json_encode( $export_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );
        exit;
    }

    /**
     * POST Handler: Import Templates.
     * Reads a JSON file upload and inserts templates into the database.
     * Skips templates if a key already exists.
     */
    public function smart_convert_currency_unit_conversion_import_templates() {
        if ( ! current_user_can( 'manage_options' ) ) {
            // translators: English: "You do not have sufficient permissions to access this page.". Error shown when capability check fails.
            wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Verify nonce with strict sanitization and unslashing
        if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'smart_convert_currency_unit_conversion_import_templates_action' ) ) {
            // translators: English: "Security check failed.". Error shown when nonce validation fails.
            wp_die( esc_html__( 'Security check failed. Please try again.', 'smart-convert-currency-unit-conversion' ) );
        }
        
        // Check if file is set and there is no error
        if ( ! isset( $_FILES['template_file'] ) || isset( $_FILES['template_file']['error'] ) && $_FILES['template_file']['error'] !== UPLOAD_ERR_OK ) {
            set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
                'status'  => 'error',
                // translators: English: "Upload failed.". Flash error when template import upload fails.
                'message' => __( 'File upload failed.', 'smart-convert-currency-unit-conversion' )
            ), 30 );
            wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=templates' ) );
            exit;
        }
        
        // Verify tmp_name exists before reading
        if ( ! isset( $_FILES['template_file']['tmp_name'] ) ) {
             set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
                'status'  => 'error',
                // translators: English: "Upload failed.". Flash error when uploaded temporary file is missing.
                'message' => __( 'File upload failed.', 'smart-convert-currency-unit-conversion' )
            ), 30 );
            wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=templates' ) );
            exit;
        }

        // It is a file upload path, so we use file_get_contents directly. 
        // Note: $_FILES['template_file']['tmp_name'] is managed by PHP.
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $file_content = file_get_contents( $_FILES['template_file']['tmp_name'] ); 
        $data = json_decode( $file_content, true );
        
        if ( ! $data || ! isset( $data['templates'] ) || ! is_array( $data['templates'] ) ) {
            set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
                'status'  => 'error',
                // translators: English: "Invalid import file format.". Flash error when imported JSON structure is invalid.
                'message' => __( 'Invalid JSON file format. Either the file failed to upload completely, or the file content is not in the required format.', 'smart-convert-currency-unit-conversion' )
            ), 30 );
            wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=templates' ) );
            exit;
        }
        
        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_templates';
        $now = current_time( 'mysql' );
        
        $imported = 0;
        $skipped  = 0;
        
        foreach ( $data['templates'] as $template ) {
            if ( empty( $template['template_key'] ) || empty( $template['template_name'] ) || empty( $template['template_output'] ) ) {
                $skipped++;
                continue;
            }
            
            $template_key = smart_convert_currency_unit_conversion_validate_template_key( $template['template_key'] );
            if ( ! $template_key ) {
                $skipped++;
                continue;
            }
            
            // Skip if key already exists to prevent overwriting
            if ( smart_convert_currency_unit_conversion_template_key_exists( $template_key ) ) {
                $skipped++;
                continue;
            }
            
            $result = $wpdb->insert(
                $table,
                array(
                    'template_key'         => $template_key,
                    'template_name'        => sanitize_text_field( $template['template_name'] ),
                    'template_output'      => wp_kses_post( $template['template_output'] ),
                    'template_description' => isset( $template['template_description'] ) ? sanitize_textarea_field( $template['template_description'] ) : '',
                    'template_type'        => 'custom',
                    'is_default_currency'  => 0,
                    'is_default_units'     => 0,
                    'created_at'           => $now,
                    'modified_at'          => $now
                ),
                array( '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s' )
            );
            
            if ( $result !== false ) {
                $imported++;
            } else {
                $skipped++;
            }
        }
        
        // Clear cache after bulk import
        if ($imported > 0) {
            wp_cache_delete('smart_convert_currency_unit_conversion_all_templates', 'smart_convert_currency_unit_conversion');
        }
        
        set_transient( 'smart_convert_currency_unit_conversion_template_flash', array(
            'status'  => 'success',
            'message' => sprintf(
                /* translators: 1: number of imported templates, 2: number of skipped templates. */
                __( 'Done! %1$d templates were successfully imported and %2$d were skipped.', 'smart-convert-currency-unit-conversion' ),
                $imported,
                $skipped
            )
        ), 30 );
        
        wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=templates' ) );
        exit;
    }

    public function currency_converter_rates_page_content() {
        // Retrieve status messages (flash messages) stored in a transient (e.g., after a manual update).
        $update_status = get_transient( 'smart_convert_currency_unit_conversion_update_rates_status' );
        
        if ( $update_status ) {
            // Clear the transient immediately after retrieval to ensure the message is shown only once.
            delete_transient( 'smart_convert_currency_unit_conversion_update_rates_status' ); 
            
            $class = ( isset($update_status['status']) && $update_status['status'] === 'success' ) ? 'notice-success' : 'notice-error';
            $message = isset($update_status['message']) ? $update_status['message'] : '';

            // Output the notice. use wp_kses_post() for the message content to allow safe HTML (e.g., links),
            // while ensuring protection against XSS.
            echo '<div class="notice ' . esc_attr( $class ) . ' is-dismissible"><p><strong>' . wp_kses_post( $message ) . '</strong></p></div>';
        }

        global $wpdb;
        $table_name = $wpdb->prefix . 'smart_convert_currency_unit_conversion_currencies';

        // Determine the default currency. If not set in options, default to 'USD'.
        $default_currency = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency'] ) 
                            ? strtoupper( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency'] ) 
                            : 'USD';
        
        // Attempt to get the localized full name of the currency (e.g., "US Dollar").
        $default_currency_name = function_exists( 'smart_convert_currency_unit_conversion_get_unit_name' ) ? smart_convert_currency_unit_conversion_get_unit_name( $default_currency ) : $default_currency;
        
        // Prepare the display string for the default currency header.
        $default_currency_display = esc_html( $default_currency );
        if ( $default_currency_name !== $default_currency && ! empty( $default_currency_name ) ) {
            $default_currency_display .= ' (' . esc_html( $default_currency_name ) . ')';
        }

        // Fetch all stored currency rates from the custom database table.
        // Note: $table_name is derived from $wpdb->prefix and is safe.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is internal (prefix + suffix).
        $results = $wpdb->get_results( "SELECT * FROM $table_name", ARRAY_A );

        if ( empty( $results ) ) {
            // translators: English: "No rate data available.". Empty-state message on rates page.
            echo '<p>' . esc_html__( 'Currency rates have not been downloaded yet, please update them.', 'smart-convert-currency-unit-conversion' ) . '</p>';
            return;
        }

        $currencies_data = [];
        
        // Retrieve the timestamp of the last successful update.
        $last_update_ts = (int) get_option( 'smart_convert_currency_unit_conversion_last_rates_update_time', 0 ); 
        
        // If the option is missing (0), we will attempt to find the most recent timestamp from the table rows.
        $need_to_find_max_ts = ( $last_update_ts === 0 );

        // Process database results to organize rates relative to the default currency.
        foreach ( $results as $row ) {
            $from_raw = isset( $row['from_currency'] ) ? (string) $row['from_currency'] : '';
            $to_raw   = isset( $row['to_currency'] ) ? (string) $row['to_currency'] : '';

            $from = strtoupper( preg_replace( '/[^A-Za-z0-9_-]/', '', trim( $from_raw ) ) );
            $to   = strtoupper( preg_replace( '/[^A-Za-z0-9_-]/', '', trim( $to_raw ) ) );
            if ( $from === '' || $to === '' ) {
                continue;
            }
            $rate = (float) $row['rate'];
            
            // Update the max timestamp if we don't have a global last update time.
            if ( $need_to_find_max_ts ) {
                $updated = strtotime( $row['updated_at'] );
                if ( $updated > $last_update_ts ) {
                    $last_update_ts = $updated;
                }
            }

            // Store direct rates (Default -> Foreign).
            if ( $from === $default_currency && $to !== $default_currency ) {
                if ( ! isset( $currencies_data[$to] ) ) $currencies_data[$to] = [];
                $currencies_data[$to]['rate_to'] = $rate;
            }
            
            // Store inverse rates (Foreign -> Default).
            if ( $to === $default_currency && $from !== $default_currency ) {
                if ( ! isset( $currencies_data[$from] ) ) $currencies_data[$from] = [];
                $currencies_data[$from]['rate_from'] = $rate;
            }
        }

        // Prepare rows for the display table. Calculate missing inverse rates if necessary.
        $po_labels = function_exists( 'smart_convert_currency_unit_conversion_get_unit_catalog_english_map' )
            ? smart_convert_currency_unit_conversion_get_unit_catalog_english_map()
            : array();
        if ( ! is_array( $po_labels ) ) {
            $po_labels = array();
        }
        $fallback_currency_names = array();
        if ( empty( $po_labels ) ) {
            $fallback_currency_names = array(
                'ADA' => 'Cardano (cryptocurrency)', 'AED' => 'United Arab Emirates Dirham', 'AFN' => 'Afghan Afghani', 'ALL' => 'Albanian Lek', 'AMD' => 'Armenian Dram',
                'ANG' => 'Netherlands Antillean Guilder', 'AOA' => 'Angolan Kwanza', 'ARS' => 'Argentine Peso', 'AUD' => 'Australian Dollar', 'AWG' => 'Aruban Florin',
                'AZN' => 'Azerbaijani Manat', 'BAM' => 'Bosnia-Herzegovina Convertible Mark', 'BBD' => 'Barbados Dollar', 'BDT' => 'Bangladeshi Taka', 'BGN' => 'Bulgarian Lev',
                'BHD' => 'Bahraini Dinar', 'BIF' => 'Burundian Franc', 'BMD' => 'Bermudian Dollar', 'BNB' => 'Binance (cryptocurrency)', 'BND' => 'Brunei Dollar',
                'BOB' => 'Bolivian Boliviano', 'BRL' => 'Brazilian Real', 'BSD' => 'Bahamian Dollar', 'BTC' => 'Bitcoin (cryptocurrency)', 'BTN' => 'Bhutanese Ngultrum',
                'BWP' => 'Botswana Pula', 'BYN' => 'Belarusian Ruble', 'BZD' => 'Belize Dollar', 'CAD' => 'Canadian Dollar', 'CDF' => 'Congolese Franc',
                'CHF' => 'Swiss Franc', 'CLP' => 'Chilean Peso', 'CNY' => 'Chinese Yuan', 'COP' => 'Colombian Peso', 'CRC' => 'Costa Rican Colón',
                'CUP' => 'Cuban Peso', 'CVE' => 'Cape Verdean Escudo', 'CZK' => 'Czech Koruna', 'DJF' => 'Djiboutian Franc', 'DKK' => 'Danish Krone',
                'DOGE' => 'DOGE (cryptocurrency)', 'DOP' => 'Dominican Peso', 'DZD' => 'Algerian Dinar', 'EGP' => 'Egyptian Pound', 'ERN' => 'Eritrean nakfa',
                'ETB' => 'Ethiopian Birr', 'ETH' => 'Ethereum (cryptocurrency)', 'EUR' => 'Euro', 'FJD' => 'Fijian Dollar', 'FKP' => 'Falkland Islands pound',
                'GBP' => 'Pound Sterling', 'GEL' => 'Georgian Lari', 'GHS' => 'Ghanaian Cedi', 'GIP' => 'Gibraltar pound', 'GMD' => 'Gambian Dalasi',
                'GNF' => 'Guinean Franc', 'GTQ' => 'Guatemalan Quetzal', 'GYD' => 'Guyanese Dollar', 'HKD' => 'Hong Kong Dollar', 'HNL' => 'Honduran Lempira',
                'HTG' => 'Haitian Gourde', 'HUF' => 'Hungarian Forint', 'IDR' => 'Indonesian Rupiah', 'ILS' => 'Israeli New Shekel', 'INR' => 'Indian Rupee',
                'IQD' => 'Iraqi Dinar', 'IRR' => 'Iranian Rial', 'ISK' => 'Icelandic Króna', 'JMD' => 'Jamaican Dollar', 'JOD' => 'Jordanian Dinar',
                'JPY' => 'Japanese Yen', 'KES' => 'Kenyan Shilling', 'KGS' => 'Kyrgyz som', 'KHR' => 'Cambodian Riel', 'KMF' => 'Comorian Franc',
                'KPW' => 'North Korean won', 'KRW' => 'South Korean Won', 'KWD' => 'Kuwaiti Dinar', 'KYD' => 'Cayman Islands Dollar', 'KZT' => 'Kazakhstani Tenge',
                'LAK' => 'Lao Kip', 'LBP' => 'Lebanese Pound', 'LKR' => 'Sri Lankan Rupee', 'LRD' => 'Liberian Dollar', 'LSL' => 'Lesotho Loti',
                'LYD' => 'Libyan Dinar', 'MAD' => 'Moroccan Dirham', 'MDL' => 'Moldovan Leu', 'MGA' => 'Malagasy Ariary', 'MKD' => 'Macedonian Denar',
                'MMK' => 'Burmese Kyat', 'MNT' => 'Mongolian tögrög', 'MOP' => 'Macanese Pataca', 'MRU' => 'Mauritanian Ouguiya', 'MUR' => 'Mauritian Rupee',
                'MVR' => 'Maldivian Rufiyaa', 'MWK' => 'Malawian Kwacha', 'MXN' => 'Mexican Peso', 'MYR' => 'Malaysian Ringgit', 'MZN' => 'Mozambican Metical',
                'NAD' => 'Namibian Dollar', 'NGN' => 'Nigerian Naira', 'NIO' => 'Nicaraguan Córdoba', 'NOK' => 'Norwegian Krone', 'NPR' => 'Nepalese Rupee',
                'NZD' => 'New Zealand Dollar', 'OMR' => 'Omani Rial', 'PAB' => 'Panamanian Balboa', 'PEN' => 'Peruvian Sol', 'PGK' => 'Papua New Guinean Kina',
                'PHP' => 'Philippine Peso', 'PKR' => 'Pakistani Rupee', 'PLN' => 'Polish Złoty', 'PYG' => 'Paraguayan Guaraní', 'QAR' => 'Qatari Riyal',
                'RON' => 'Romanian Leu', 'RSD' => 'Serbian Dinar', 'RUB' => 'Russian Ruble', 'RWF' => 'Rwandan Franc', 'SAR' => 'Saudi Riyal',
                'SBD' => 'Solomon Islands Dollar', 'SCR' => 'Seychellois Rupee', 'SDG' => 'Sudanese Pound', 'SEK' => 'Swedish Krona', 'SGD' => 'Singapore Dollar',
                'SHP' => 'Saint Helena pound', 'SLE' => 'Sierra Leonean Leone', 'SOL' => 'Solana', 'SOS' => 'Somali Shilling', 'SRD' => 'Surinamese Dollar',
                'SSP' => 'South Sudanese pound', 'STN' => 'São Tomé and Príncipe dobra', 'SVC' => 'Salvadoran colón', 'SYP' => 'Syrian pound', 'SZL' => 'Swazi Lilangeni',
                'THB' => 'Thai Baht', 'TJS' => 'Tajikistani Somoni', 'TMT' => 'Turkmenistan Manat', 'TND' => 'Tunisian Dinar', 'TOP' => 'Tongan Paʻanga',
                'TRX' => 'Tronix (cryptocurrency)', 'TRY' => 'Turkish Lira', 'TTD' => 'Trinidad and Tobago Dollar', 'TWD' => 'New Taiwan Dollar', 'TZS' => 'Tanzanian Shilling',
                'UAH' => 'Ukrainian Hryvnia', 'UGX' => 'Ugandan Shilling', 'USD' => 'United States Dollar', 'USDC' => 'USDC (cryptocurrency)', 'USDT' => 'Tether (cryptocurrency)',
                'UYU' => 'Uruguayan Peso', 'UZS' => 'Uzbekistani Som', 'VED' => 'Venezuelan bolívar', 'VND' => 'Vietnamese Dong', 'VUV' => 'Vanuatu vatu',
                'WST' => 'Samoan tālā', 'XAF' => 'Central African CFA Franc', 'XCD' => 'East Caribbean Dollar', 'XCG' => 'Caribbean guilder', 'XOF' => 'West African CFA Franc',
                'XPF' => 'CFP Franc', 'XRP' => 'XRP (cryptocurrency)', 'YER' => 'Yemeni Rial', 'ZAR' => 'South African Rand', 'ZMW' => 'Zambian Kwacha',
                'ZWG' => 'Zimbabwean ZiG',
            );
            $cached_fallback_currency_names = get_transient( 'smart_convert_currency_unit_conversion_currency_names_fallback' );
            if ( is_array( $cached_fallback_currency_names ) && ! empty( $cached_fallback_currency_names ) ) {
                $fallback_currency_names = array_merge( $fallback_currency_names, $cached_fallback_currency_names );
            } else {
                $response = wp_remote_get(
                    'https://openexchangerates.org/api/currencies.json',
                    array(
                        'timeout' => 5,
                    )
                );
                if ( ! is_wp_error( $response ) ) {
                    $body = wp_remote_retrieve_body( $response );
                    $decoded = json_decode( $body, true );
                    if ( is_array( $decoded ) ) {
                        foreach ( $decoded as $iso_code => $iso_name ) {
                            $iso_code = strtoupper( preg_replace( '/[^A-Za-z0-9_-]/', '', (string) $iso_code ) );
                            if ( $iso_code !== '' && is_string( $iso_name ) && $iso_name !== '' ) {
                                $fallback_currency_names[ $iso_code ] = $iso_name;
                            }
                        }
                    }
                }

                // Manual crypto/custom names used by Smart Convert rates feed.
                $fallback_currency_names['ADA']  = 'Cardano (cryptocurrency)';
                $fallback_currency_names['BNB']  = 'Binance (cryptocurrency)';
                $fallback_currency_names['DOGE'] = 'DOGE (cryptocurrency)';
                $fallback_currency_names['ETH']  = 'Ethereum (cryptocurrency)';
                $fallback_currency_names['SOL']  = 'Solana';
                $fallback_currency_names['TRX']  = 'Tronix (cryptocurrency)';
                $fallback_currency_names['USDC'] = 'USDC (cryptocurrency)';
                $fallback_currency_names['USDT'] = 'Tether (cryptocurrency)';

                if ( ! empty( $fallback_currency_names ) ) {
                    set_transient( 'smart_convert_currency_unit_conversion_currency_names_fallback', $fallback_currency_names, DAY_IN_SECONDS );
                }
            }
        }
        $display_rows = [];
        foreach ( $currencies_data as $code => $data ) {
            $code_upper = strtoupper( preg_replace( '/[^A-Za-z0-9_-]/', '', trim( (string) $code ) ) );
            if ( $code_upper === '' ) {
                continue;
            }
            $name = '';

            $po_key = 'global-unit-' . strtolower( $code_upper );
            $resolver_name = '';
            if ( isset( $po_labels[ $po_key ] ) && $po_labels[ $po_key ] !== '' ) {
                $name = (string) $po_labels[ $po_key ];
            } elseif ( isset( $fallback_currency_names[ $code_upper ] ) && $fallback_currency_names[ $code_upper ] !== '' ) {
                $name = (string) $fallback_currency_names[ $code_upper ];
            } elseif ( function_exists( 'smart_convert_currency_unit_conversion_get_unit_name' ) ) {
                $resolver_name = (string) smart_convert_currency_unit_conversion_get_unit_name( $code_upper );
                $name = $resolver_name;
            }

            if ( $name === '' || strcasecmp( $name, $code_upper ) === 0 ) {
                $name = $code_upper;
            }
            
            $rate_to   = isset( $data['rate_to'] ) ? (float) $data['rate_to'] : null;
            $rate_from = isset( $data['rate_from'] ) ? (float) $data['rate_from'] : null;

            // Calculate reciprocal rates mathematically if one direction is missing but the other exists.
            if ( $rate_to && ! $rate_from && $rate_to > 0 ) {
                $rate_from = 1.0 / $rate_to;
            }
            elseif ( $rate_from && ! $rate_to && $rate_from > 0 ) {
                $rate_to = 1.0 / $rate_from;
            }

            $display_rows[] = [
                'code'      => $code_upper,
                'name'      => $name,
                'rate_to'   => $rate_to,
                'rate_from' => $rate_from,
            ];
        }
        // Sort the list alphabetically by currency name.
        // Use the Internationalization Collator if available for correct language-sensitive sorting.
        usort( $display_rows, function( $a, $b ) {
            if ( class_exists( 'Collator' ) ) {
                $collator = new Collator( get_locale() );
                return $collator->compare( $a['name'], $b['name'] );
            }
            return strcasecmp( $a['name'], $b['name'] );
        } );

        // Format the last update date based on WordPress settings.
        $date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );

        if ( $last_update_ts ) {
            $formatted_date = wp_date( $date_format, $last_update_ts );
        } else {
            // translators: English: "Unknown". Fallback label when the last rates update timestamp is unavailable.
            $formatted_date = __( 'Unknown', 'smart-convert-currency-unit-conversion' );
        }

    ?>
        <div style="margin-top: 20px;">
            
            <div style="display:flex; gap: 15px; margin-bottom: 20px;">
                <div style="display:flex; gap: 15px; margin-bottom: 20px;">
                <button type="button" id="smart-convert-currency-unit-conversion-btn-update-rates" class="button button-primary" data-nonce="<?php echo esc_attr( wp_create_nonce( 'smart_convert_currency_unit_conversion_manual_rates_update_action' ) ); ?>">
                    <span class="dashicons dashicons-update"></span> 
                    <?php // translators: English: "Update Rates". Primary button label to trigger manual currency rates update. ?>
                    <?php echo esc_html__( 'Update Rates', 'smart-convert-currency-unit-conversion' ); ?>
                </button>
            </div>
            </div>

            <p style="font-size: 1.1em; margin-bottom: 15px;">
                <strong>
                    <?php // translators: English: "Last update". Label shown before the timestamp of latest rates sync. ?>
                    <?php echo esc_html__( 'Currency rates were last updated on', 'smart-convert-currency-unit-conversion' ); ?>
                </strong> 
                <?php echo esc_html( $formatted_date ); ?>
                <br>
                <small><?php printf(
                    wp_kses_post(
                        /* translators: %s: default currency display label. */
                        __( 'Rates in the table are relative to the default currency <strong>%s</strong>', 'smart-convert-currency-unit-conversion' )
                    ),
                    esc_html( $default_currency_display ) 
                ); ?></small>
            </p>

            <table class="wp-list-table widefat fixed striped table-view-list smart-convert-currency-unit-conversion-table-rates">
                <thead>
                    <tr>
                        <?php // translators: English: "Code". Currency table column heading for ISO code. ?>
                        <th style="width: 100px;"><?php echo esc_html( _x( 'ISO Code', 'label.currency.iso_code', 'smart-convert-currency-unit-conversion' ) ); ?></th>
                        <th><?php // translators: English: "Currency". Table column heading for currency name. ?><?php echo esc_html__( 'Currency Name', 'smart-convert-currency-unit-conversion' ); ?></th>
                        <th style="text-align: right;">
                            <?php
                            printf(
                                /* translators: %s: default currency code (e.g. USD, EUR). */
                                esc_html__( 'Rate %s → Currency', 'smart-convert-currency-unit-conversion' ),
                                esc_html( $default_currency )
                            );
                            ?>
                        </th>
                        <th style="text-align: right;">
                            <?php
                            printf(
                                /* translators: %s: default currency code (e.g. USD, EUR). */
                                esc_html__( 'Rate Currency → %s', 'smart-convert-currency-unit-conversion' ),
                                esc_html( $default_currency )
                            );
                            ?>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <?php if ( empty( $display_rows ) ): ?>
                        <tr>
                            <td colspan="4">
                                <?php // translators: English: "No currency data available.". Fallback table row text when rates dataset is empty. ?>
                                <?php echo esc_html__( 'No rates were found for the default currency. Please update the rates.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                        </tr>
                    <?php else: ?>
                        <?php foreach ( $display_rows as $row ): ?>
                            <tr>
                                <td><strong><?php echo esc_html( $row['code'] ); ?></strong></td>
                                <td><?php echo esc_html( $row['name'] ); ?></td>
                                <td style="text-align: right;">
                                    <?php 
                                    if ( $row['rate_to'] !== null ) {
                                        // Adjust decimals for very small rates (e.g., crypto) vs standard currencies.
                                        $decimals = ( $row['rate_to'] < 0.01 ) ? 12 : 6;
                                        
                                        // Safe formatted output using printf
                                        printf(
                                            '1 %s = <strong>%s</strong> %s',
                                            esc_html( $default_currency ),
                                            esc_html( number_format_i18n( $row['rate_to'], $decimals ) ),
                                            esc_html( $row['code'] )
                                        );
                                    } else {
                                        echo '<span style="color:#ccc;">-</span>';
                                    }
                                    ?>
                                </td>
                                <td style="text-align: right;">
                                    <?php 
                                    if ( $row['rate_from'] !== null ) {
                                        $decimals = ( $row['rate_from'] < 0.01 ) ? 12 : 6;
                                        printf(
                                            '1 %s = <strong>%s</strong> %s',
                                            esc_html( $row['code'] ),
                                            esc_html( number_format_i18n( $row['rate_from'], $decimals ) ),
                                            esc_html( $default_currency )
                                        );
                                    } else {
                                        echo '<span style="color:#ccc;">-</span>';
                                    }
                                    ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </tbody>
            </table>
        </div>
        <?php
    }

/**
 * Renders the Units Configuration Page (Settings -> Smart Convert – Currency & Unit Conversion -> Units).
 * Handles display of both built-in (default) units and user-defined custom units.
 */
public function smart_convert_currency_unit_conversion_units_page_content() {
    // Display flash messages from unit operations (import/update/save).
    $update_status = get_transient( 'smart_convert_currency_unit_conversion_update_units_status' );
    if ( $update_status ) {
        delete_transient( 'smart_convert_currency_unit_conversion_update_units_status' ); 
        $class = ( $update_status['status'] === 'success' ) ? 'notice-success' : 'notice-error';
        echo '<div class="notice ' . esc_attr( $class ) . ' is-dismissible"><p><strong>' . wp_kses_post( $update_status['message'] ) . '</strong></p></div>';
    }

    global $wpdb;
    $table_name = $wpdb->prefix . 'smart_convert_currency_unit_conversion_units';
    $table_name_escaped = '`' . esc_sql( $table_name ) . '`';
    $dec_sep = isset($this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_decimals']) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_decimals'] : '.';
    $th_sep  = isset($this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_thousands']) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_thousands'] : ',';

    // Fetch ALL unit definitions from the database, sorted by unit code.
    // Using brace syntax for table name to separate it from surrounding query text clearly.
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Admin listing from custom table.
    $results = $wpdb->get_results( "SELECT * FROM {$table_name_escaped} ORDER BY unit_from ASC, unit_to ASC", ARRAY_A );
    
    // Determine last update time from the first row (assuming uniform updates).
    $last_update = (!empty($results)) ? $results[0]['updated_at'] : null;
    // translators: English: "Never". Fallback label when unit database has never been updated.
    $formatted_date = $last_update
        ? wp_date( get_option('date_format') . ' ' . get_option('time_format'), strtotime($last_update) )
        : __(
            // translators: English: "Never". Fallback label when unit database has never been updated.
            'Never',
            'smart-convert-currency-unit-conversion'
        );

    $custom_units = [];
    $default_units = [];
    
    // Separate units into Custom (user-defined) and Default (built-in).
    if (!empty($results)) {
        foreach ($results as $row) {
            if (isset($row['is_custom']) && $row['is_custom'] == 1) {
                $custom_units[] = $row;
            } else {
                $default_units[] = $row;
            }
        }
    }

    ?>
    <div style="margin-top: 20px;">
        
        <div style="display:flex; justify-content: space-between; align-items: center; margin-bottom: 25px; background: #fff; padding: 20px; border-radius: 10px; border: 1px solid #ccd0d4; box-shadow: 0 4px 10px rgba(0,0,0,0.05);">
            <div>
                <h3 style="margin: 0 0 5px 0;">
                    <?php // translators: English: "Units Conversions Database". Section heading for units storage overview. ?>
                    <?php echo esc_html__( 'Unit Conversion Database', 'smart-convert-currency-unit-conversion' ); ?>
                </h3>
                <p class="description" style="margin: 0;">
                    <?php // translators: English: "Last update:". Label shown before units database timestamp. ?><?php echo esc_html__( 'Last updated:', 'smart-convert-currency-unit-conversion' ); ?> <strong><?php echo esc_html($formatted_date); ?></strong>.  
                    <?php 
                    printf(
                        /* translators: %d: number of unit definitions loaded. */
                        esc_html__( 'There are %d unit pairs in the database.', 'smart-convert-currency-unit-conversion' ),
                        count( $results )
                    );
                    ?>
                </p>
            </div>
            
            <button type="button" id="smart-convert-currency-unit-conversion-btn-update-units" class="button button-primary" 
                data-nonce="<?php echo esc_attr(wp_create_nonce('smart_convert_currency_unit_conversion_manual_units_update_action')); ?>"
                data-confirm="<?php
                    // translators: English: "Are you sure you want to update all unit definitions?". Confirmation text before forcing unit database update.
                    echo esc_attr__( 'It is usually not necessary to update the unit database because, unlike currency rates, it does not change. Do you still want to continue?', 'smart-convert-currency-unit-conversion' );
                ?>">
                <span class="dashicons dashicons-download" style="line-height: 1.3;"></span> 
                <?php // translators: English: "Update Unit Database". Primary button label for manual unit definitions refresh. ?>
                <?php echo esc_html__( 'Update Unit Database', 'smart-convert-currency-unit-conversion' ); ?>
            </button>
        </div>

        <div class="smart-convert-currency-unit-conversion-io-actions" style="margin-bottom: 20px; text-align:right;">
            <button type="button" id="smart-convert-currency-unit-conversion-btn-import" class="button button-secondary">
                <span class="dashicons dashicons-upload"></span>
                <?php // translators: English: "Import Custom Units". Button label opening custom unit import panel. ?>
                <?php echo esc_html__( 'Import Custom Units', 'smart-convert-currency-unit-conversion' ); ?>
            </button>
            <button type="button" id="smart-convert-currency-unit-conversion-btn-export" class="button button-secondary" <?php echo empty($custom_units) ? 'disabled' : ''; ?>>
                <span class="dashicons dashicons-download"></span>
                <?php // translators: English: "Export Custom Units". Button label exporting custom units as JSON. ?>
                <?php echo esc_html__( 'Export Custom Units', 'smart-convert-currency-unit-conversion' ); ?>
            </button>
            
            <form id="smart-convert-currency-unit-conversion-import-form" style="display:none; margin-top:10px; background:#fff; padding:15px; border:1px solid #ddd; border-radius:8px; text-align:left;">
                <label style="font-weight:600; display:block; margin-bottom:5px;"><?php // translators: English: "Select JSON file". Label for choosing unit import JSON file. ?><?php echo esc_html__( 'Select JSON file with exported units:', 'smart-convert-currency-unit-conversion' ); ?></label>
                <input type="file" name="import_file" accept=".json" required>
                
                <div style="margin-top:10px;">
                    <label><input type="radio" name="strategy" value="skip" checked> <?php // translators: English: "Skip duplicates". Import strategy option to keep existing entries unchanged. ?><?php echo esc_html__( 'Skip Duplicates', 'smart-convert-currency-unit-conversion' ); ?></label>
                    <label style="margin-left:15px;"><input type="radio" name="strategy" value="overwrite"> <?php // translators: English: "Overwrite duplicates". Import strategy option to update existing entries. ?><?php echo esc_html__( 'Overwrite Duplicates', 'smart-convert-currency-unit-conversion' ); ?></label>
                </div>
                
                <div style="margin-top:15px; text-align:right;">
                    <?php // translators: English: "Cancel". Button label used to close the custom unit import form. ?>
                    <button type="button" class="button" onclick="jQuery('#smart-convert-currency-unit-conversion-import-form').slideUp();"><?php echo esc_html( _x( 'Cancel', 'action.cancel.import', 'smart-convert-currency-unit-conversion' ) ); ?></button>
                    <button type="submit" class="button button-primary"><?php // translators: English: "Import Units". Primary button label to start custom units import. ?><?php echo esc_html__( 'Import Units', 'smart-convert-currency-unit-conversion' ); ?></button>
                </div>
            </form>
        </div>
        
        <?php if (!empty($custom_units)): ?>
            <div id="smart-convert-currency-unit-conversion-custom-list-anchor" class="smart-convert-currency-unit-conversion-template-card" style="margin-bottom: 30px; border-left: 4px solid #FF6B81;">
                <div class="smart-convert-currency-unit-conversion-template-header" style="border-bottom: 1px solid #f0f0f1; padding-bottom: 15px; margin-bottom: 15px;">
                <h3 style="margin: 0; color: #1A2F45;">
                        <span class="dashicons dashicons-admin-tools" style="color:#FF6B81"></span>
                        <?php // translators: English: "Custom Units". Section heading listing user-defined conversion rules. ?>
                        <?php echo esc_html__( 'List of Custom Units', 'smart-convert-currency-unit-conversion' ); ?>
                    </h3>
                </div>
                <table class="wp-list-table widefat fixed striped table-view-list">
                    <thead>
                        <tr>
                            <th style="width: 25%;"><?php echo esc_html( _x( 'From', 'label.table.from_unit', 'smart-convert-currency-unit-conversion' ) ); ?></th>
                            <th style="width: 25%;"><?php echo esc_html( _x( 'To', 'label.table.to_unit', 'smart-convert-currency-unit-conversion' ) ); ?></th>
                            <th style="width: 15%;">
                                <?php // translators: English: "Factor". Column heading for conversion factor value. ?>
                                <?php echo esc_html__( 'Conversion Factor', 'smart-convert-currency-unit-conversion' ); ?>
                            </th>
                            <th style="width: 25%;"><?php // translators: English: "Example". Column heading for rendered conversion preview. ?><?php echo esc_html__( 'Conversion Example', 'smart-convert-currency-unit-conversion' ); ?></th>
                            <th style="width: 10%; text-align:right;"></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($custom_units as $row): 
                            // Formatting the conversion factor and logic preview
                            $factor = (float)$row['factor'];
                            $factor_display = str_replace('.', $dec_sep, rtrim(rtrim(number_format($factor, 8, '.', ''), '0'), '.'));
                            $label_from = !empty($row['unit_from_name']) ? $row['unit_from_name'] : $row['unit_from'];
                            $label_to = !empty($row['unit_to_name']) ? $row['unit_to_name'] : $row['unit_to'];
                            $example_val = (1 * $factor) + (float)$row['offset'];
                            $example_display = number_format($example_val, 4, $dec_sep, $th_sep);
                            
                            $sym_before = !empty($row['symbol_to_before']) ? $row['symbol_to_before'] : '';
                            $sym_after = !empty($row['symbol_to_after']) ? $row['symbol_to_after'] : '';
                            
                            $display_string = $sym_before . $example_display . $sym_after;

                            // --- Source Unit Display Logic (FROM) ---
                            // If specific custom symbols are defined, use them (e.g., "1 Ă˘Â˜â€°").
                            // Otherwise, fallback to the unit code (e.g., "1 unitname").
                            $sym_from_before = !empty($row['symbol_from_before']) ? $row['symbol_from_before'] : '';
                            $sym_from_after  = !empty($row['symbol_from_after']) ? $row['symbol_from_after'] : '';

                            if ( $sym_from_before !== '' || $sym_from_after !== '' ) {
                                // Removed space after '1' because custom symbols might include whitespace (e.g. " Ă˘Â˜Ĺš")
                                $display_from_string = $sym_from_before . '1' . $sym_from_after;
                            } else {
                                $display_from_string = '1 ' . $row['unit_from'];
                            }
                            // --- END FIX ---
                        ?>
                        <tr>
                            <td><strong><?php echo esc_html($label_from); ?></strong> <small style="color:#999">(<?php echo esc_html($row['unit_from']); ?>)</small></td>
                            <td><strong><?php echo esc_html($label_to); ?></strong> <small style="color:#999">(<?php echo esc_html($row['unit_to']); ?>)</small></td>
                            <td><?php echo esc_html($factor_display); ?></td>
                            <td><code><?php echo esc_html($display_from_string); ?> = <strong><?php echo esc_html($display_string); ?></strong></code></td>
                            <td style="text-align:right;">
                                <button type="button" class="button button-small smart-convert-currency-unit-conversion-edit-unit-ajax" 
                                        data-id="<?php echo esc_attr($row['id']); ?>" 
                                        data-nonce="<?php echo esc_attr( wp_create_nonce('smart_convert_currency_unit_conversion_custom_unit_action') ); ?>"
                                        title="<?php echo esc_attr( _x( 'Edit', 'action.edit.custom_unit', 'smart-convert-currency-unit-conversion' ) ); ?>">
                                    <span class="dashicons dashicons-edit"></span>
                                </button>
                                <button type="button" class="button button-small button-link-delete smart-convert-currency-unit-conversion-delete-unit-ajax" 
                                        data-id="<?php echo esc_attr($row['id']); ?>" 
                                        data-nonce="<?php echo esc_attr( wp_create_nonce('smart_convert_currency_unit_conversion_custom_unit_action') ); ?>"
                                        title="<?php
                                            // translators: English: "Delete Unit". Tooltip for deleting a custom unit conversion pair.
                                            echo esc_attr__( 'Delete', 'smart-convert-currency-unit-conversion' );
                                        ?>">
                                    <span class="dashicons dashicons-trash"></span>
                                </button>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>

<div class="smart-convert-currency-unit-conversion-custom-units-card smart-convert-currency-unit-conversion-box-create">
            <h3 id="smart-convert-currency-unit-conversion-form-title" style="margin-top:0; color:#1A2F45;">
                <?php // translators: English: "Add Custom Units". Section heading for creating a custom conversion rule. ?>
                <?php echo esc_html__( 'Add Custom Units', 'smart-convert-currency-unit-conversion' ); ?>
            </h3>
            <p class="description" style="margin-bottom:20px;"><?php // translators: English: "Create your own custom conversion pair and define factor/symbols.". Helper text shown above custom unit form. ?><?php echo esc_html__( 'Here you can add your own units and the conversion between them; you can then use them like any other unit. You can convert between currencies, default units, and any custom units. The formula for converting units in the reverse direction is created automatically.', 'smart-convert-currency-unit-conversion' ); ?></p>
            
            <form id="smart-convert-currency-unit-conversion-add-unit-form" autocomplete="off">
            
            <input type="hidden" name="edit_id" id="smart_convert_currency_unit_conversion_edit_id" value="0">

            <div class="smart-convert-currency-unit-conversion-units-grid">
                
                <div class="smart-convert-currency-unit-conversion-unit-column smart-convert-currency-unit-conversion-unit-column-from">
                    <h4>
                        <span class="dashicons dashicons-arrow-right-alt"></span> 
                        <?php // translators: English: "From". Label for source unit/currency selection in custom unit form. ?>
                        <?php echo esc_html( _x( 'From', 'label.form.source_unit', 'smart-convert-currency-unit-conversion' ) ); ?>
                    </h4>
                    
                    <div class="smart-convert-currency-unit-conversion-mode-toggle">
                        <label><input type="radio" name="mode_from" value="existing" checked> <span><?php // translators: English: "Choose Existing". Option to use already existing source unit code. ?><?php echo esc_html__( 'Use Existing Unit', 'smart-convert-currency-unit-conversion' ); ?></span></label>
                        <label><input type="radio" name="mode_from" value="new"> <span><?php // translators: English: "Create New". Option to create a brand new source unit code. ?><?php echo esc_html__( 'Create New Unit', 'smart-convert-currency-unit-conversion' ); ?></span></label>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-field-existing">
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <label><?php // translators: English: "Select Existing Unit". Label for autocomplete selector in existing-mode. ?><?php echo esc_html__( 'Select Existing Unit', 'smart-convert-currency-unit-conversion' ); ?></label>
                            <input type="text" id="smart_convert_currency_unit_conversion_existing_from_display" class="widefat smart-convert-currency-unit-conversion-autocomplete-input" placeholder="<?php echo esc_attr__( 'Select Existing Unit', 'smart-convert-currency-unit-conversion' ); ?>">
                            <input type="hidden" name="existing_from" id="smart_convert_currency_unit_conversion_existing_from_val">
                        </div>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-field-new" style="display:none;">
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <?php // translators: English: "Unit Name". Label for custom unit name field. ?>
                            <label><?php echo esc_html( _x( 'Unit Name', 'label.unit.name', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                            <input type="text" name="new_from_name" class="widefat smart-convert-currency-unit-conversion-validate-required" placeholder="<?php echo esc_attr__( 'Enter unit name', 'smart-convert-currency-unit-conversion' ); ?>">
                            <p class="description"><?php // translators: English: "Enter a readable unit name (e.g., Meter, Pound).". Helper text for custom unit name input. ?><?php echo esc_html__( 'The name serves to identify the unit and appears in the autosuggest, among other places. You can use any characters, including spaces.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        </div>
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <?php // translators: English: "Unit Code". Label for custom unit code field. ?>
                            <label><?php echo esc_html( _x( 'Unit Code', 'label.unit.code', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                            <input type="text" name="new_from_code" class="widefat smart-convert-currency-unit-conversion-code-input smart-convert-currency-unit-conversion-validate-required" 
                                   placeholder="<?php echo esc_attr__( 'Enter unit code', 'smart-convert-currency-unit-conversion' ); ?>"
                                   maxlength="20" pattern="[a-z0-9]+">
                            <span class="smart-convert-currency-unit-conversion-validation-msg"></span>
                            <p class="description">
                                <?php // translators: English: "Use lowercase code without spaces (e.g., m, kg, cup).". Helper text for custom unit code input. ?>
                                <?php echo esc_html__( 'The unit code serves to identify it in a block or shortcode. The unit code must be unique and may only contain characters a-z and 0-9 without spaces. Once a unit is created, the code cannot be changed, so consider its form carefully.', 'smart-convert-currency-unit-conversion' ); ?>
                            </p>
                        </div>
                        <div class="smart-convert-currency-unit-conversion-input-group">
                            <div style="flex:1">
                                <label>
                                    <?php // translators: English: "Symbol Before". Label for symbol prefix shown before numeric value. ?>
                                    <?php echo esc_html__( 'Symbol Before Numerical Value', 'smart-convert-currency-unit-conversion' ); ?>
                                </label>
                                <input type="text" name="new_from_symbol_before" class="widefat" maxlength="20" placeholder="<?php echo esc_attr__( 'e.g., #, €, $…', 'smart-convert-currency-unit-conversion' ); ?>">
                            </div>
                            <div style="flex:1">
                                <label>
                                    <?php // translators: English: "Symbol After". Label for symbol suffix shown after numeric value. ?>
                                    <?php echo esc_html__( 'Symbol After Numerical Value', 'smart-convert-currency-unit-conversion' ); ?>
                                </label>
                                <input type="text" name="new_from_symbol_after" class="widefat" maxlength="20" placeholder="<?php echo esc_attr__( 'e.g., m., °C, Kč…', 'smart-convert-currency-unit-conversion' ); ?>">
                            </div>
                        </div>
                        <p class="description">
                            <?php // translators: English: "Symbols are optional. You can define prefix/suffix for display formatting.". Helper text for symbol fields. ?>
                            <?php echo esc_html__( 'You can leave both fields empty. A space is not automatically added between the value and the symbol. If you want to separate the number and the symbol with a space, remember to include it in the symbol fields.', 'smart-convert-currency-unit-conversion' ); ?>
                        </p>
                    </div>
                </div>

                <div class="smart-convert-currency-unit-conversion-unit-column smart-convert-currency-unit-conversion-unit-column-to">
                    <h4>
                        <span class="dashicons dashicons-arrow-left-alt"></span> 
                        <?php // translators: English: "To". Label for target unit/currency selection in custom unit form. ?>
                        <?php echo esc_html( _x( 'To', 'label.form.target_unit', 'smart-convert-currency-unit-conversion' ) ); ?>
                    </h4>
                    
                    <div class="smart-convert-currency-unit-conversion-mode-toggle">
                        <label><input type="radio" name="mode_to" value="existing" checked> <span>
                            <?php // translators: English: "Choose Existing". Option to use already existing target unit code. ?>
                            <?php echo esc_html__( 'Use Existing Unit', 'smart-convert-currency-unit-conversion' ); ?>
                        </span></label>
                        <label><input type="radio" name="mode_to" value="new"> <span><?php // translators: English: "Create New". Option to create a brand new target unit code. ?><?php echo esc_html__( 'Create New Unit', 'smart-convert-currency-unit-conversion' ); ?></span></label>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-field-existing">
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <label><?php // translators: English: "Select Existing Unit". Label for autocomplete selector in existing-mode. ?><?php echo esc_html__( 'Select Existing Unit', 'smart-convert-currency-unit-conversion' ); ?></label>
                            <input type="text" id="smart_convert_currency_unit_conversion_existing_to_display" class="widefat smart-convert-currency-unit-conversion-autocomplete-input" placeholder="<?php echo esc_attr__( 'Select Existing Unit', 'smart-convert-currency-unit-conversion' ); ?>">
                            <input type="hidden" name="existing_to" id="smart_convert_currency_unit_conversion_existing_to_val">
                        </div>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-field-new" style="display:none;">
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <?php // translators: English: "Unit Name". Label for custom unit name field. ?>
                            <label><?php echo esc_html( _x( 'Unit Name', 'label.unit.name', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                            <input type="text" name="new_to_name" class="widefat smart-convert-currency-unit-conversion-validate-required" placeholder="<?php echo esc_attr__( 'Enter unit name', 'smart-convert-currency-unit-conversion' ); ?>">
                            <p class="description"><?php // translators: English: "Enter a readable unit name (e.g., Meter, Pound).". Helper text for custom unit name input. ?><?php echo esc_html__( 'The name serves to identify the unit and appears in the autosuggest, among other places. You can use any characters, including spaces.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        </div>
                        <div class="smart-convert-currency-unit-conversion-form-row">
                            <?php // translators: English: "Unit Code". Label for custom unit code field. ?>
                            <label><?php echo esc_html( _x( 'Unit Code', 'label.unit.code', 'smart-convert-currency-unit-conversion' ) ); ?> *</label>
                            <input type="text" name="new_to_code" class="widefat smart-convert-currency-unit-conversion-code-input smart-convert-currency-unit-conversion-validate-required" 
                                   placeholder="<?php echo esc_attr__( 'Enter unit code', 'smart-convert-currency-unit-conversion' ); ?>"
                                   maxlength="20" pattern="[a-z0-9]+">
                            <span class="smart-convert-currency-unit-conversion-validation-msg"></span>
                            <p class="description">
                                <?php // translators: English: "Use lowercase code without spaces (e.g., m, kg, cup).". Helper text for custom unit code input. ?>
                                <?php echo esc_html__( 'The unit code serves to identify it in a block or shortcode. The unit code must be unique and may only contain characters a-z and 0-9 without spaces. Once a unit is created, the code cannot be changed, so consider its form carefully.', 'smart-convert-currency-unit-conversion' ); ?>
                            </p>
                        </div>
                        <div class="smart-convert-currency-unit-conversion-input-group">
                            <div style="flex:1">
                                <label>
                                    <?php // translators: English: "Symbol Before". Label for symbol prefix shown before numeric value. ?>
                                    <?php echo esc_html__( 'Symbol Before Numerical Value', 'smart-convert-currency-unit-conversion' ); ?>
                                </label>
                                <input type="text" name="new_to_symbol_before" class="widefat" maxlength="20" placeholder="<?php echo esc_attr__( 'e.g., #, €, $…', 'smart-convert-currency-unit-conversion' ); ?>">
                            </div>
                            <div style="flex:1">
                                <label>
                                    <?php // translators: English: "Symbol After". Label for symbol suffix shown after numeric value. ?>
                                    <?php echo esc_html__( 'Symbol After Numerical Value', 'smart-convert-currency-unit-conversion' ); ?>
                                </label>
                                <input type="text" name="new_to_symbol_after" class="widefat" maxlength="20" placeholder="<?php echo esc_attr__( 'e.g., m., °C, Kč…', 'smart-convert-currency-unit-conversion' ); ?>">
                            </div>
                        </div>
                        <p class="description">
                            <?php // translators: English: "Symbols are optional. You can define prefix/suffix for display formatting.". Helper text for symbol fields. ?>
                            <?php echo esc_html__( 'You can leave both fields empty. A space is not automatically added between the value and the symbol. If you want to separate the number and the symbol with a space, remember to include it in the symbol fields.', 'smart-convert-currency-unit-conversion' ); ?>
                        </p>
                    </div>
                </div>
            </div>

            <div class="smart-convert-currency-unit-conversion-conversion-equation-card">
                <div class="smart-convert-currency-unit-conversion-equation-label">
                    <?php // translators: English: "Conversion Logic". Label heading for factor-based conversion equation. ?>
                    <?php echo esc_html__( 'Conversion Factor Between Units', 'smart-convert-currency-unit-conversion' ); ?>
                </div>
                
                <div id="smart-convert-currency-unit-conversion-conversion-equation" class="smart-convert-currency-unit-conversion-equation-wrapper">
                    <div class="eq-part eq-left">
                        <span class="preview-wrap">1 Unit</span>
                    </div>
                    <div class="eq-part eq-operator">=</div>
                    <div class="eq-part eq-right">
                        <input type="number" step="0.0000000001" name="factor" id="smart_convert_currency_unit_conversion_factor" value="1.0" class="smart-convert-currency-unit-conversion-factor-input smart-convert-currency-unit-conversion-validate-required">
                        <span class="preview-wrap">Unit</span>
                    </div>
                </div>
                <p class="description" style="text-align:center; margin-top:10px;">
                    <?php // translators: English: "Defines how 1 source unit converts to target unit.". Helper text below conversion equation editor. ?>
                    <?php echo esc_html__( 'Set the conversion ratio between the two units. The conversion factor for the reverse conversion will be generated automatically.', 'smart-convert-currency-unit-conversion' ); ?>
                </p>
            </div>

            <div style="text-align:right; margin-top:20px; display:flex; justify-content:flex-end; gap:10px; align-items:center;">
                <?php // translators: English: "Cancel Edit". Button label for leaving custom-unit edit mode without saving. ?>
                <button type="button" id="smart-convert-currency-unit-conversion-cancel-edit-btn" class="button" style="display:none;"><?php echo esc_html( _x( 'Cancel Edit', 'action.cancel.edit_custom_unit', 'smart-convert-currency-unit-conversion' ) ); ?></button>
                
                <button type="submit" id="smart-convert-currency-unit-conversion-save-unit-btn" class="button button-primary button-large"><?php // translators: English: "Save Custom Unit". Primary button for creating a custom unit mapping. ?><?php echo esc_html( _x( 'Save', 'action.save.custom_unit', 'smart-convert-currency-unit-conversion' ) ); ?></button>
                <span class="spinner" style="float:none;"></span>
            </div>
        </form>
        </div>

        <?php 
        // Categorization and display logic for default units.
        // Units are grouped by physical quantity (Temperature, Length, etc.) for better UX.
        $categories = [
            // translators: English: "Temperature". Category heading for temperature conversions.
            __( 'Temperature', 'smart-convert-currency-unit-conversion' ) => ['C', 'F', 'K', 'R'],
            // translators: English: "Length". Category heading for length/distance conversions.
            __( 'Length', 'smart-convert-currency-unit-conversion' )      => ['m', 'km', 'cm', 'mm', 'mi', 'yd', 'ft', 'in', 'dm'],
            // translators: English: "Weight". Category heading for mass/weight conversions.
            __( 'Weight', 'smart-convert-currency-unit-conversion' )      => ['kg', 'g', 'mg', 'lb', 'oz', 'st', 't'],
            // translators: English: "Speed". Category heading for speed conversions.
            __( 'Speed', 'smart-convert-currency-unit-conversion' )       => ['kph', 'mph', 'kt', 'm/s', 'kn'],
            // translators: English: "Area". Category heading for area conversions.
            __( 'Area', 'smart-convert-currency-unit-conversion' )        => ['sqkm', 'sqmi', 'ha', 'ac', 'sqm', 'sqft', 'sqin', 'sqyd'],
            // translators: English: "Volume". Category heading for volume conversions.
            __( 'Volume', 'smart-convert-currency-unit-conversion' )      => ['l', 'ml', 'gal', 'qt', 'pt', 'cup', 'floz', 'cl', 'dl'],
            // translators: English: "Pressure". Category heading for pressure conversions.
            // translators: English: "Pressure". Category heading for pressure conversions.
            __( 'Pressure', 'smart-convert-currency-unit-conversion' )    => ['bar', 'psi', 'pa', 'hpa', 'atm', 'torr']
        ];

        $grouped_data = [];
        $other_data = [];

        // Sort default units into categories defined above.
        if (!empty($default_units)) {
            foreach ($default_units as $row) {
                $found = false;
                $u_from = strtolower($row['unit_from']);
                foreach ($categories as $cat_name => $units) {
                    if (in_array($u_from, array_map('strtolower', $units))) {
                        $grouped_data[$cat_name][] = $row;
                        $found = true;
                        break;
                    }
                }
                if (!$found) $other_data[] = $row;
            }
        }
        // translators: English: "Other". Category heading for uncategorized unit conversions.
        if (!empty($other_data)) {
            $grouped_data[ __( 'Other / Uncategorized', 'smart-convert-currency-unit-conversion' ) ] = $other_data;
        }
        ?>

        <?php if (empty($default_units)): ?>
            <div class="notice notice-warning inline"><p><?php // translators: English: "No unit definitions found.". Warning shown when default unit list is empty. ?><?php echo esc_html__( 'The default unit and conversion database has not been downloaded yet. Please try updating the database.', 'smart-convert-currency-unit-conversion' ); ?></p></div>
        <?php else: ?>
            <?php foreach ($grouped_data as $category => $rows): ?>
                <div class="smart-convert-currency-unit-conversion-template-card smart-convert-currency-unit-conversion-box-data" style="margin-bottom: 30px;">
                    <div class="smart-convert-currency-unit-conversion-template-header" style="border-bottom: 1px solid #f0f0f1; padding-bottom: 15px; margin-bottom: 15px;">
                        <h3 style="margin: 0; font-size: 1.2em; display: flex; align-items: center; gap: 10px;">
                            <span class="dashicons dashicons-category"></span>
                            <?php echo esc_html($category); ?> 
                            <span class="smart-convert-currency-unit-conversion-badge builtin" style="font-weight: normal; font-size: 0.8em; color:#666;">
                                <?php 
                                // translators: English: "%d conversions". %d: number of conversions in this category.
                                printf(
                                    '%d %s',
                                    count( $rows ),
                                    esc_html__( 'unit pairs', 'smart-convert-currency-unit-conversion' )
                                );
                                ?>
                            </span>
                        </h3>
                    </div>
                    <table class="wp-list-table widefat fixed striped table-view-list">
                        <thead>
                            <tr>
                                <th style="width: 20%;"><?php echo esc_html( _x( 'From', 'label.table.from_unit', 'smart-convert-currency-unit-conversion' ) ); ?></th>
                                <th style="width: 20%;"><?php echo esc_html( _x( 'To', 'label.table.to_unit', 'smart-convert-currency-unit-conversion' ) ); ?></th>
                                <th style="width: 15%;">
                                    <?php // translators: English: "Factor". Column heading for conversion factor. ?>
                                    <?php echo esc_html__( 'Conversion Factor', 'smart-convert-currency-unit-conversion' ); ?>
                                </th>
                                <th style="width: 10%;"><?php // translators: English: "Offset". Column heading for conversion offset value. ?><?php echo esc_html__( 'Offset', 'smart-convert-currency-unit-conversion' ); ?></th>
                                <th style="width: 35%;"><?php // translators: English: "Example". Column heading for rendered conversion example. ?><?php echo esc_html__( 'Conversion Example', 'smart-convert-currency-unit-conversion' ); ?></th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($rows as $row): 
                                $factor = (float)$row['factor'];
                                $offset = (float)$row['offset'];
                                $example_val = (1 * $factor) + $offset;

                                // Attempt to translate unit names.
                                // Replaced generic translation call with core translation helper and added phpcs ignore comment to allow dynamic variable.
                                // We must use a dynamic variable here to translate unit names (like Swiss Franc) based on the user's selection; static strings cannot cover all database-driven options.
                                
                                // 1. UNIT FROM/TO processing
                                $label_from = ! empty( $row['unit_from_name'] ) ? $row['unit_from_name'] : $row['unit_from'];
                                $label_to   = ! empty( $row['unit_to_name'] ) ? $row['unit_to_name'] : $row['unit_to'];

                                // Format numbers for display
                                $factor_display = str_replace('.', $dec_sep, rtrim(rtrim(number_format($factor, 8, '.', ''), '0'), '.'));
                                
                                if ($offset == 0) $offset_display = '<span style="color:#ccc;">0</span>';
                                else $offset_display = str_replace('.', $dec_sep, rtrim(rtrim(number_format($offset, 8, '.', ''), '0'), '.'));

                                $example_display = number_format($example_val, 4, $dec_sep, $th_sep);

                                // Render persisted symbol/unit. Some persisted values are stored as translation msgids (e.g. global-unit-symbol-C).
                                $symbol_after_display = !empty($row['symbol_after']) ? $row['symbol_after'] : $row['unit_to'];
                                if ( is_string( $symbol_after_display ) ) {
                                    $symbol_after_key = trim( (string) $symbol_after_display );
                                } else {
                                    $symbol_after_key = '';
                                }
                                if ( $symbol_after_key !== '' && strpos( $symbol_after_key, 'global-unit-symbol-' ) === 0 ) {
                                    $translated_symbol_after = smart_convert_currency_unit_conversion_translate_global_unit_msgid( $symbol_after_key );
                                    if ( ! empty( $translated_symbol_after ) ) {
                                        // Polish/CS symbol strings often use &nbsp;; convert it to a plain space for admin table rendering.
                                        $translated_symbol_after = str_replace( '&nbsp;', ' ', $translated_symbol_after );
                                        $symbol_after_display    = $translated_symbol_after;
                                    }
                                }
                            ?>
                            <tr>
                                <td>
                                    <?php if($label_from): ?>
                                        <strong><?php echo esc_html($label_from); ?></strong> <span style="color:#888;">(<?php echo esc_html($row['unit_from']); ?>)</span>
                                    <?php else: ?>
                                        <strong><?php echo esc_html($row['unit_from']); ?></strong>
                                    <?php endif; ?>
                                </td>
                                <td>
                                    <?php if($label_to): ?>
                                        <strong><?php echo esc_html($label_to); ?></strong> <span style="color:#888;">(<?php echo esc_html($row['unit_to']); ?>)</span>
                                    <?php else: ?>
                                        <strong><?php echo esc_html($row['unit_to']); ?></strong>
                                    <?php endif; ?>
                                </td>
                                <td><?php echo esc_html($factor_display); ?></td>
                                <td><?php echo wp_kses_post($offset_display); ?></td>
                                <td>
                                    <code style="font-size: 0.9em;">
                                        1 <?php echo esc_html($row['unit_from']); ?> = 
                                        <strong><?php echo esc_html($example_display); ?></strong><?php echo esc_html($symbol_after_display); ?>
                                    </code>
                                </td>
                            </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            <?php endforeach; ?>
        <?php endif; ?>
    </div>
    <?php
}

    /**
     * Renders the Help & Documentation Page content.
     */
    public function currency_converter_help_page_content() {
        ?>
        <div class="smart-convert-currency-unit-conversion-help-container">
            
            <div class="smart-convert-currency-unit-conversion-help-section smart-convert-currency-unit-conversion-box-data">
                <h2>
                    <?php // translators: English: "How the Smart Convert Free shortcode works". Help section heading for shortcode usage. ?>
                    <?php echo esc_html__( 'How the Smart Convert Free shortcode works', 'smart-convert-currency-unit-conversion' ); ?>
                </h2>
                <p><?php // translators: English: "Use the shortcode to render conversions in posts and pages.". Intro text for shortcode help section. ?><?php echo esc_html__( 'The shortcode for inserting a conversion has the following format:', 'smart-convert-currency-unit-conversion' ); ?></p>
                
                <div class="smart-convert-currency-unit-conversion-template-preview" style="padding: 15px; margin: 15px 0;">
                    <code>[smart-convert amount="100" from="USD" to="EUR" decimals="2" output="default"]</code>
                </div>

                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 20px;">
                    <div>
                        <h3>
                            <?php // translators: English: "Mandatory Parameters". Subheading in shortcode docs. ?>
                            <?php echo esc_html__( 'Mandatory shortcode parameters', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <ul style="list-style-type: disc; padding-left: 20px;">
                            <li><strong><code>amount</code></strong> <?php // translators: English: "Numeric value to convert.". Explanation for amount shortcode parameter. ?><?php echo esc_html__( 'The numerical value or amount you want to convert to another value (e.g., 10000). Do not separate the individual digits of the number with anything; you can use a period or comma to separate decimal places.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><strong><code>from</code></strong> <?php // translators: English: "Source currency or unit code.". Explanation for from shortcode parameter. ?><?php echo esc_html__( 'The code of the currency (e.g., USD), unit (e.g., km, C), or custom unit you want to convert to another unit.', 'smart-convert-currency-unit-conversion' ); ?></li>
                        </ul>
                    </div>
                    <div>
                        <h3>
                            <?php // translators: English: "Optional Parameters". Subheading in shortcode docs. ?>
                            <?php echo esc_html__( 'Optional shortcode parameters', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <ul style="list-style-type: disc; padding-left: 20px;">
                            <li><strong><code>to</code></strong> <?php // translators: English: "Target currency or unit code.". Explanation for to shortcode parameter. ?><?php echo esc_html__( 'The code of the currency (e.g. EUR), unit (e.g. cm, F), or custom unit to which you want to convert the numeric value. If a default currency or unit (length, temperature, etc.) is set, the parameter is not required. For custom units, the parameter is always required.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><strong><code>decimals</code></strong> <?php // translators: English: "Number of decimal places in output.". Explanation for decimals shortcode parameter. ?><?php echo esc_html__( 'Number of decimal places to display in the conversion. If the parameter is not filled in, smart rounding (0, 2, or 3 decimal places depending on the value size) will be used.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><strong><code>output</code></strong> <?php // translators: English: "Template key used for output formatting.". Explanation for output shortcode parameter. ?><?php echo esc_html__( 'Format in which the converted amount will be displayed. You can use saved templates or a custom string with macros.', 'smart-convert-currency-unit-conversion' ); ?></li>
                        </ul>
                    </div>
                </div>
            </div>

            <div class="smart-convert-currency-unit-conversion-help-section smart-convert-currency-unit-conversion-box-data">
                <h2>
                    <?php // translators: English: "Output Format Placeholders". Help section heading for output tokens. ?>
                    <?php echo esc_html__( 'Macros for Templates and Conversion Outputs', 'smart-convert-currency-unit-conversion' ); ?>
                </h2>
                <p><?php // translators: English: "Use placeholders to customize rendered conversion text.". Intro text for output placeholders section. ?><?php echo esc_html__( 'You can use the following macros in custom templates and in the "output" parameter. Macros are used to output specific types of data.', 'smart-convert-currency-unit-conversion' ); ?></p>

                <table class="smart-convert-currency-unit-conversion-help-table">
                    <thead>
                        <tr>
                            <th><?php // translators: English: "Placeholder". Help table column heading. ?><?php echo esc_html__( 'Macro', 'smart-convert-currency-unit-conversion' ); ?></th>
                            <th><?php // translators: English: "Meaning". Help table column heading. ?><?php echo esc_html__( 'What gets displayed', 'smart-convert-currency-unit-conversion' ); ?></th>
                            <th><?php // translators: English: "Example". Help table column heading. ?><?php echo esc_html__( 'Example', 'smart-convert-currency-unit-conversion' ); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td><code>{FROM}</code></td>
                            <td>
                                <?php // translators: English: "Formatted source amount with symbol/name.". Placeholder description for {FROM}. ?>
                                <?php echo esc_html__( 'Original amount (from which the conversion is made) with symbol or unit.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>$90</td>
                        </tr>
                        <tr>
                            <td><code>{FROM_CODE}</code></td>
                            <td>
                                <?php // translators: English: "Source unit or currency code.". Placeholder description for {FROM_CODE}. ?>
                                <?php echo esc_html__( 'Code of the currency or unit from which the amount is being converted.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>USD</td>
                        </tr>
                        <tr>
                            <td><code>{FROM_NAME}</code></td>
                            <td>
                                <?php // translators: English: "Localized source unit or currency name.". Placeholder description for {FROM_NAME}. ?>
                                <?php echo esc_html__( 'Name of the currency or unit from which the amount is being converted.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td><?php echo esc_html__( 'Australian Dollar', 'smart-convert-currency-unit-conversion' ); ?></td>
                        </tr>
                        <tr>
                            <td><code>{FROM_VALUE}</code></td>
                            <td>
                                <?php // translators: English: "Raw numeric source value.". Placeholder description for {FROM_VALUE}. ?>
                                <?php echo esc_html__( 'Only the amount (numerical value) from which the conversion is being made.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>90</td>
                        </tr>
                        <tr>
                            <td><code>{TO}</code></td>
                            <td>
                                <?php // translators: English: "Formatted converted value with symbol/name.". Placeholder description for {TO}. ?>
                                <?php echo esc_html__( 'Target amount (to which the conversion is made) with symbol or unit.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>€100</td>
                        </tr>
                        <tr>
                            <td><code>{TO_CODE}</code></td>
                            <td>
                                <?php // translators: English: "Target unit or currency code.". Placeholder description for {TO_CODE}. ?>
                                <?php echo esc_html__( 'Code of the currency or unit to which the amount is being converted.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>EUR</td>
                        </tr>
                        <tr>
                            <td><code>{TO_NAME}</code></td>
                            <td>
                                <?php // translators: English: "Localized target unit or currency name.". Placeholder description for {TO_NAME}. ?>
                                <?php echo esc_html__( 'Name of the currency or unit to which the amount is being converted.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>
                                <?php // translators: English: "Euro". Example localized unit/currency name for {TO_NAME}. ?>
                                <?php echo esc_html__( 'Euro', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                        </tr>
                        <tr>
                            <td><code>{TO_VALUE}</code></td>
                            <td>
                                <?php // translators: English: "Raw numeric converted value.". Placeholder description for {TO_VALUE}. ?>
                                <?php echo esc_html__( 'Only the rounded amount (numerical value) to which the conversion is being made.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>100</td>
                        </tr>
                        <tr>
                            <td><code>{RATE}</code></td>
                            <td>
                                <?php // translators: English: "Calculated conversion rate.". Placeholder description for {RATE}. ?>
                                <?php echo esc_html__( 'The applied exchange rate or conversion factor, displayed to four decimal places without markup (surcharge, if enabled in settings).', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>1.1111</td>
                        </tr>
                        <tr>
                            <td><code>{RATE_INFO}</code></td>
                            <td>
                                <?php // translators: English: "Human-readable rate sentence.". Placeholder description for {RATE_INFO}. ?>
                                <?php echo esc_html__( 'Exchange rate used for the currency pair and the date for which the rate is valid.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                            <td>
                                <?php // translators: English: "1 USD = 0.90 EUR". Example value shown for {RATE_INFO}. ?>
                                <?php echo esc_html__( 'Converted at a rate of 1 EUR = 1.05 USD as of Dec 8, 2025.', 'smart-convert-currency-unit-conversion' ); ?>
                            </td>
                        </tr>
                    </tbody>
                </table>
                
                <h3 style="margin-top: 30px;">
                    <?php // translators: English: "Conversion Bubble". Subheading for tooltip/bubble output format guidance. ?>
                    <?php echo esc_html__( 'How to Display Content in a Tooltip', 'smart-convert-currency-unit-conversion' ); ?>
                </h3>
                <p><?php // translators: English: "Use || and ## markers to define bubble trigger and content.". Helper text explaining bubble syntax. ?><?php echo esc_html__( 'Enclose the text to hover over for the tooltip in ||two vertical bars||. Enclose the text to be displayed inside the tooltip in ##two hashtags##. The content of the ## brackets must always be fully nested within the two vertical bars.', 'smart-convert-currency-unit-conversion' ); ?></p>
                <div class="smart-convert-currency-unit-conversion-template-preview" style="padding: 10px;">
                    <code>output="||{FROM} ({TO})##{TO} {RATE_INFO}##||"</code>
                </div>
            </div>
            
            
            <div class="smart-convert-currency-unit-conversion-help-section smart-convert-currency-unit-conversion-box-data">
                <h2 style="display:flex; align-items:center; gap:10px;">
                    <?php // translators: English: "Automatic Currency Detection (Geolocation)". Help section heading for IP-based currency detection. ?>
                    <?php echo esc_html__( 'How to get an IPinfo.io token for automatic currency determination', 'smart-convert-currency-unit-conversion' ); ?>
                </h2>
                
                <p>
                    <?php // translators: English: "Enable geolocation to detect visitor country and suggest default currency.". Intro text for geolocation feature. ?><?php echo esc_html__( 'For the "Convert to currency based on user location" function, the plugin uses the IPinfo.io service, which helps it detect the relevant country. This service is reliable, fast, and supports HTTPS. A free <strong>API Access Token</strong> is required for it to work.', 'smart-convert-currency-unit-conversion' ); ?>
                </p>

                <div style="background: #f0f6fc; border: 1px solid #cce5ff; border-radius: 8px; padding: 20px; margin-top: 15px;">
                    <h3 style="margin-top:0;"><?php // translators: English: "How it works". Subheading for geolocation workflow explanation. ?><?php echo esc_html__( 'Step-by-step guide', 'smart-convert-currency-unit-conversion' ); ?></h3>
                    
                    <ol style="list-style-type: decimal; padding-left: 20px; line-height: 1.6;">
                        <li style="margin-bottom: 10px;">
                            <?php // translators: English: "Get an API token from ipinfo.io.". Geolocation setup step 1. ?><?php echo esc_html__( 'Go to the registration page <a href="https://ipinfo.io/signup" target="_blank" rel="noopener noreferrer"><strong>ipinfo.io/signup</strong></a>.', 'smart-convert-currency-unit-conversion' ); ?>
                        </li>
                        <li style="margin-bottom: 10px;">
                            <?php // translators: English: "Paste token in plugin settings.". Geolocation setup step 2. ?><?php echo esc_html__( 'Create a user account here; you can use email, Google, or GitHub. Registration is free, and if you choose the Free plan, you won\'t have to enter credit card details.', 'smart-convert-currency-unit-conversion' ); ?>
                        </li>
                        <li style="margin-bottom: 10px;">
                            <?php // translators: English: "Enable auto-currency from visitor IP.". Geolocation setup step 3. ?><?php echo esc_html__( 'After registering and logging into your account, you will be redirected to the Dashboard.', 'smart-convert-currency-unit-conversion' ); ?>
                        </li>
                        <li style="margin-bottom: 10px;">
                            <?php // translators: English: "Plugin resolves visitor country and preferred currency.". Geolocation setup step 4. ?><?php echo esc_html__( 'You will see the required token in the <strong>"Access Token"</strong> section; it is a string of letters and numbers.', 'smart-convert-currency-unit-conversion' ); ?>
                        </li>
                        <li>
                            <?php // translators: English: "Detected currency is used as conversion default.". Geolocation setup step 5. ?><?php echo esc_html__( 'Copy the token and paste it into the <strong>IPinfo.io Access Token</strong> field in this plugin\'s settings.', 'smart-convert-currency-unit-conversion' ); ?>
                        </li>
                    </ol>
                </div>

                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 20px;">
                    <div>
                        <h3>
                            <?php // translators: English: "API Token". Subheading for geolocation API token info. ?>
                            <?php echo esc_html__( 'What an IPinfo.io token looks like', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <p><?php // translators: English: "Your ipinfo.io token authorizes country lookup requests.". Helper text for token usage. ?><?php echo esc_html__( 'The token is a short string of 14 characters, consisting only of lowercase letters and numbers.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <div class="smart-convert-currency-unit-conversion-template-preview" style="padding: 10px; margin-top: 5px; color: #666;">
                            <code>1a2b3c4d5e6f7g</code> <small>(<?php // translators: English: "Example token". Caption for sample geolocation token string. ?><?php echo esc_html__( 'token example', 'smart-convert-currency-unit-conversion' ); ?>)</small>
                        </div>
                    </div>
                    <div>
                        <h3><?php // translators: English: "Rate limits". Subheading describing geolocation API plan limits. ?><?php echo esc_html__( 'Limits of the free token on IPinfo.io', 'smart-convert-currency-unit-conversion' ); ?></h3>
                        <ul style="list-style-type: disc; padding-left: 20px;">
                            <li><strong><?php // translators: English: "Free plan". Label for free tier limitations. ?><?php echo esc_html__( 'Free Plan:', 'smart-convert-currency-unit-conversion' ); ?></strong> <?php // translators: English: "Suitable for small to medium traffic websites.". Hint about free plan usage scope. ?><?php echo esc_html__( '50,000 location lookup requests per month', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><?php // translators: English: "Requests are limited by provider quota.". Geolocation limit bullet point. ?><?php echo esc_html__( 'The free limit is sufficient for most websites with up to 1,500 unique visitors per day.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><?php // translators: English: "Consider paid plan for high traffic sites.". Geolocation limit recommendation. ?><?php echo esc_html__( 'If the limit is exhausted, automatic user country detection will temporarily stop working. Until the monthly limit is reset, the amount will be converted to the default currency.', 'smart-convert-currency-unit-conversion' ); ?></li>
                        </ul>
                    </div>
                </div>
            </div>

            <div class="smart-convert-currency-unit-conversion-help-section smart-convert-currency-unit-conversion-box-data">
                <h2>
                    <?php // translators: English: "Frequently Asked Questions". Heading for FAQ section. ?>
                    <?php echo esc_html__( 'Frequently Asked Questions (FAQ)', 'smart-convert-currency-unit-conversion' ); ?>
                </h2>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary"><?php // translators: English: "How do I insert the converter?". FAQ question heading. ?><?php echo esc_html__( 'Why are my currency rates not updating automatically?', 'smart-convert-currency-unit-conversion' ); ?></summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "Use shortcode or Gutenberg block to insert converter.". FAQ answer paragraph. ?><?php echo esc_html__( 'Currency rates are updated automatically; the frequency of updates is determined by the "Exchange Rate Update Frequency" in the plugin settings. If your rates are not updating automatically, you can try the following:', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <ol>
                            <li><?php // translators: English: "Open editor and insert Smart Convert block.". FAQ answer step. ?><?php echo esc_html__( 'Open the <strong>Current Rates</strong> tab and check the date when the currency rates were last updated.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><?php // translators: English: "Configure amount/from/to/output options.". FAQ answer step. ?><?php echo esc_html__( 'If the date shown is not current, click the <strong>Update Rates</strong> button.', 'smart-convert-currency-unit-conversion' ); ?></li>
                            <li><?php // translators: English: "Publish page to render live conversion.". FAQ answer step. ?><?php echo esc_html__( 'If the problem persists, check if WP-Cron is working in your WordPress installation. For WP-Cron to work, the website must be visited by at least one visitor at the given time.', 'smart-convert-currency-unit-conversion' ); ?></li>
                        </ol>
                    </div>
                </details>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary">
                        <?php // translators: English: "How often are exchange rates updated?". FAQ question heading. ?>
                        <?php echo esc_html__( 'How does automatic currency detection based on user location work?', 'smart-convert-currency-unit-conversion' ); ?>
                    </summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "Rates are refreshed based on update interval setting.". FAQ answer paragraph. ?><?php echo esc_html__( 'If you enable this function in the settings, the plugin will first try to determine the visitor\'s country based on their IP address. The amount will then be converted to the currency of the country the user is from, instead of the default currency specified in the settings. If the "to" parameter is filled in the shortcode, automatic currency determination will not apply.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <p><?php // translators: English: "Manual update is available in Rates tab.". FAQ answer paragraph. ?><?php echo esc_html__( '<strong>Cache Warning: </strong>If you use caching plugins (WP Rocket, Autoptimize, etc.), it may happen that the page is generated in the first visitor\'s currency and this version is cached for all other visitors. For proper functioning with cache, it is necessary to set a cache exception for the relevant pages.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    </div>
                </details>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary"><?php // translators: English: "Can I create custom units?". FAQ question heading. ?><?php echo esc_html__( 'What is markup?', 'smart-convert-currency-unit-conversion' ); ?></summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "Yes, custom units can be added in Units tab.". FAQ answer paragraph. ?><?php echo esc_html__( 'Markup is a percentage surcharge on the official mid-market exchange rate of a currency pair. The purpose of this function is to simulate the actual exchange rate that will be applied when paying by card. When paying by card in a foreign currency, banks and card issuers add a markup to the mid-market rate. The usual markup amount is 1.5 - 4%.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <p><?php // translators: English: "You can also import/export custom units as JSON.". FAQ answer paragraph. ?><?php echo esc_html__( 'You can also import/export custom units as JSON.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    </div>
                </details>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary"><?php // translators: English: "How do I change output format?". FAQ question heading. ?><?php echo esc_html__( 'How can I change the tooltip color?', 'smart-convert-currency-unit-conversion' ); ?></summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "Use template placeholders in Templates tab.". FAQ answer paragraph. ?><?php echo esc_html__( 'You can adjust the tooltip and text color in the plugin settings under <strong>Conversion Display Style</strong>. You can edit the tooltip background color and the text color inside the tooltip.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    </div>
                </details>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary"><?php // translators: English: "Why is conversion not displayed?". FAQ question heading. ?><?php echo esc_html__( 'How to round the converted amount to a whole number?', 'smart-convert-currency-unit-conversion' ); ?></summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "Check required shortcode parameters.". FAQ troubleshooting paragraph. ?><?php echo esc_html__( 'When inserting a conversion, set the number of decimal places to 0, or use the parameter <code>decimals="0"</code> in the shortcode.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <p><?php // translators: English: "Verify source/target code validity.". FAQ troubleshooting paragraph. ?><?php echo esc_html__( 'Example: <code>[smart-convert amount="500" from="EUR" to="USD" decimals="0"]</code>.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <p><?php // translators: English: "Ensure rates/units data was loaded successfully.". FAQ troubleshooting paragraph. ?><?php echo esc_html__( 'If you do not set the number of decimal places, the plugin will use smart rounding. More decimal places will be displayed for smaller values, and high values will be rounded to whole numbers.', 'smart-convert-currency-unit-conversion' ); ?></p>
                    </div>
                </details>

                <details class="smart-convert-currency-unit-conversion-faq-details">
                    <summary class="smart-convert-currency-unit-conversion-faq-summary"><?php // translators: English: "Is geolocation mandatory?". FAQ question heading. ?><?php echo esc_html__( 'Does the plugin support cryptocurrency conversion?', 'smart-convert-currency-unit-conversion' ); ?></summary>
                    <div class="smart-convert-currency-unit-conversion-faq-content">
                        <p><?php // translators: English: "No, plugin works without geolocation token.". FAQ answer paragraph. ?><?php echo esc_html__( 'Yes, the plugin supports all major cryptocurrencies. You can convert, for example, Bitcoin (code <code>BTC</code>), Ethereum (code <code>ETH</code>), Cardano (code <code>ADA</code>), and others. They work just like regular currencies.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <p><?php // translators: English: "Geolocation only enhances automatic default currency selection.". FAQ answer paragraph. ?><?php echo esc_html__( 'Example: <code>[smart-convert amount="1" from="BTC" to="USD"]</code>', 'smart-convert-currency-unit-conversion' ); ?></p>
                    </div>
                </details>
            </div>

            <div class="smart-convert-currency-unit-conversion-help-section smart-convert-currency-unit-conversion-support-grid-wrapper">
                <h2 style="border-bottom:none; margin-bottom:10px;">
                    <?php // translators: English: "Need Help?". Heading for support links section. ?>
                    <?php echo esc_html__( 'Need more help?', 'smart-convert-currency-unit-conversion' ); ?>
                </h2>
                <p class="description" style="margin-bottom: 30px;"><?php // translators: English: "Choose documentation, forum, or bug report channel.". Intro text for support cards. ?><?php echo esc_html__( 'Find answers in our documentation or reach out to the community.', 'smart-convert-currency-unit-conversion' ); ?></p>

                <div class="smart-convert-currency-unit-conversion-support-grid">
                    <div class="smart-convert-currency-unit-conversion-support-card">
                        <div class="smart-convert-currency-unit-conversion-support-icon">
                            <span class="dashicons dashicons-book"></span>
                        </div>
                        <h3>
                            <?php // translators: English: "Documentation". Support card title linking to docs. ?>
                            <?php echo esc_html__( 'Documentation', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <p><?php // translators: English: "Read full setup and usage guides.". Support card description for docs. ?><?php echo esc_html__( 'Everything you need to know about setting up templates, units, and using the shortcodes.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <a href="https://petrnovak.cz/plugins/smart-convert-currency-unit-conversion/documentation/" target="_blank" class="button">
                            <?php // translators: English: "Open Documentation". CTA button text for docs link. ?><?php echo esc_html__( 'Read Documentation', 'smart-convert-currency-unit-conversion' ); ?> <span class="dashicons dashicons-external" style="margin-top:4px;"></span>
                        </a>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-support-card">
                        <div class="smart-convert-currency-unit-conversion-support-icon">
                            <span class="dashicons dashicons-groups"></span>
                        </div>
                        <h3>
                            <?php // translators: English: "Community Forum". Support card title for forum link. ?>
                            <?php echo esc_html__( 'Support Forum', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <p><?php // translators: English: "Ask questions and share solutions with other users.". Support card description for forum. ?><?php echo esc_html__( 'Have a question? Search existing topics or ask the community for advice.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <a href="https://petrnovak.cz/plugins/smart-convert-currency-unit-conversion/forum/" target="_blank" class="button">
                            <?php // translators: English: "Open Forum". CTA button text for forum link. ?><?php echo esc_html__( 'Visit Support Forum', 'smart-convert-currency-unit-conversion' ); ?> <span class="dashicons dashicons-external" style="margin-top:4px;"></span>
                        </a>
                    </div>

                    <div class="smart-convert-currency-unit-conversion-support-card bug-report">
                        <div class="smart-convert-currency-unit-conversion-support-icon error-icon">
                            <span class="dashicons dashicons-warning"></span>
                        </div>
                        <h3>
                            <?php // translators: English: "Report a Bug". Support card title for bug report channel. ?>
                            <?php echo esc_html__( 'Report a Bug', 'smart-convert-currency-unit-conversion' ); ?>
                        </h3>
                        <p><?php // translators: English: "Found an issue? Send bug details and reproduction steps.". Support card description for bug reporting. ?><?php echo esc_html__( 'Found something broken? Let us know so we can fix it in the next update.', 'smart-convert-currency-unit-conversion' ); ?></p>
                        <a href="https://petrnovak.cz/plugins/smart-convert-currency-unit-conversion/report-a-bug/" target="_blank" class="button">
                            <?php // translators: English: "Report Bug". CTA button text for bug report link. ?><?php echo esc_html__( 'Report Issue', 'smart-convert-currency-unit-conversion' ); ?> <span class="dashicons dashicons-external" style="margin-top:4px;"></span>
                        </a>
                    </div>
                </div>
            </div>
            </div> <?php

    }

/**
     * Initializes the settings for the plugin.
     * Registers setting groups, sections, and fields using the WordPress Settings API.
     */
	public function smart_convert_currency_unit_conversion_page_init() {
		// Register the main setting group
		register_setting(
			'smart_convert_currency_unit_conversion_option_group', 
			'smart_convert_currency_unit_conversion_option_name', 
			array( $this, 'smart_convert_currency_unit_conversion_sanitize' ) 
		);

		// --- Section: General Settings ---
		add_settings_section(
			'smart_convert_currency_unit_conversion_section_general', 
			'', 
			array( $this, 'smart_convert_currency_unit_conversion_section_general_info' ), 
			'smart-convert-currency-unit-conversion-admin' 
		);
        add_settings_field(
            'smart_convert_currency_unit_conversion_enable_external_data',
            // translators: English: "Allow rate updates from external source". Settings label for enabling external data access.
            __( 'Allow rate updates from external source', 'smart-convert-currency-unit-conversion' ),
            array( $this, 'smart_convert_currency_unit_conversion_enable_external_data_callback' ),
            'smart-convert-currency-unit-conversion-admin',
            'smart_convert_currency_unit_conversion_section_general'
        );
        add_settings_field(
            'smart_convert_currency_unit_conversion_update_interval',
            // translators: English: "Update Frequency". Settings label for selecting automatic update interval.
            __( 'Exchange Rate Update Frequency', 'smart-convert-currency-unit-conversion' ), // Update Interval (hours)
            array( $this, 'smart_convert_currency_unit_conversion_update_interval_callback' ),
            'smart-convert-currency-unit-conversion-admin',
            'smart_convert_currency_unit_conversion_section_general'
        );
		add_settings_field(
			'smart_convert_currency_unit_conversion_date_format',
            // translators: English: "Date Format". Settings label for conversion date display format.
			__( 'Date Format (<a href="https://wordpress.org/documentation/article/customize-date-and-time-format/" target="_blank">instructions</a>)', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_date_format_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'smart_convert_currency_unit_conversion_section_general'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_spread',
            // translators: English: "Spread". Settings label for bank margin percentage.
			__( 'Markup (Exchange Rate Margin, <a href="?page=smart-convert-currency-unit-conversion&tab=help" target="_blank">help</a>)', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_spread_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'smart_convert_currency_unit_conversion_section_general'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_spread_msg_enable', 
            // translators: English: "Display Spread Information". Settings label for showing spread notice in output. 
			__( 'Show markup amount in exchange rate information.', 'smart-convert-currency-unit-conversion' ), 
			array( $this, 'smart_convert_currency_unit_conversion_spread_msg_enable_callback' ), 
			'smart-convert-currency-unit-conversion-admin', 
			'smart_convert_currency_unit_conversion_section_general' 
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_separator_thousands',
            // translators: English: "Thousands Separator". Settings label for thousands separator character.
			__( 'Thousands Separator', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_separator_thousands_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'smart_convert_currency_unit_conversion_section_general'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_separator_decimals',
            // translators: English: "Decimal Separator". Settings label for decimal separator character.
			__( 'Decimal Separator', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_separator_decimals_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'smart_convert_currency_unit_conversion_section_general'
		);

		// --- Section: Default Units ---
		add_settings_section(
			'currency_converter_section_defaults', 
			'', 
			array( $this, 'currency_converter_section_defaults_info' ), 
			'smart-convert-currency-unit-conversion-admin' 
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_currency',
            // translators: English: "Default Currency". Settings label for fallback default currency code.
			__( 'Currency', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_currency_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

        add_settings_field(
            'auto_currency_from_ip',
            // translators: English: "Detect Currency from Visitor IP". Settings label for geolocation-based default currency.
            __( 'Convert to currency based on user location', 'smart-convert-currency-unit-conversion' ),
            array( $this, 'auto_currency_from_ip_callback' ),
            'smart-convert-currency-unit-conversion-admin',
            'currency_converter_section_defaults'
        );

        add_settings_field(
            'smart_convert_currency_unit_conversion_ipinfo_token',
            // translators: English: "IPinfo API Token". Settings label for geolocation service token.
            __( 'IPinfo.io Access Token', 'smart-convert-currency-unit-conversion' ),
            array( $this, 'smart_convert_currency_unit_conversion_ipinfo_token_callback' ),
            'smart-convert-currency-unit-conversion-admin',
            'currency_converter_section_defaults'
        );

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_temperature',
            // translators: English: "Default Temperature". Settings label for preferred temperature unit.
			__( 'Temperature', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_temperature_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_length_long',
            // translators: English: "Default Long Length Unit". Settings label for long-distance unit preference.
			__( 'Length (Long)', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_length_long_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_length_short',
            // translators: English: "Default Short Length Unit". Settings label for short-distance unit preference.
			__( 'Length (Short)', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_length_short_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_speed',
            // translators: English: "Default Speed Unit". Settings label for speed unit preference.
			__( 'Speed', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_speed_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_distance',
            // translators: English: "Default Distance Unit". Settings label for distance unit preference.
			__( 'Distance', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_distance_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_weight',
            // translators: English: "Default Weight Unit". Settings label for mass/weight unit preference.
			__( 'Weight', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_weight_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_default_area',
            // translators: English: "Default Area Unit". Settings label for area unit preference.
			__( 'Area', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_default_area_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_defaults'
		);

		// --- Section: Appearance ---
		add_settings_section(
			'currency_converter_section_appearance', 
			'', 
			array( $this, 'currency_converter_section_appearance_info' ), 
			'smart-convert-currency-unit-conversion-admin' 
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_bubble_color',
            // translators: English: "Bubble Background Color". Settings label for result bubble background color.
			__( 'Tooltip Background Color', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_bubble_color_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_appearance'
		);

		add_settings_field(
			'smart_convert_currency_unit_conversion_bubble_font',
            // translators: English: "Bubble Text Color". Settings label for result bubble text color.
			__( 'Tooltip Font Color', 'smart-convert-currency-unit-conversion' ),
			array( $this, 'smart_convert_currency_unit_conversion_bubble_font_callback' ),
			'smart-convert-currency-unit-conversion-admin',
			'currency_converter_section_appearance'
		);        
	}

    /**
     * Retrieves all unique currency codes from the database and adds supported ones.
     * Used for autocomplete fields.
     *
     * @return array List of sorted uppercase currency codes.
     */
	private function get_all_currency_codes() {
		global $wpdb;

		$codes = array();

		$table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_currencies';
		// Use prepare for SHOW TABLES to avoid "InterpolatedNotPrepared" warning
		if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) ) === $table ) {
			$table_escaped = '`' . esc_sql( $table ) . '`';
			// Direct interpolation for table name in SELECT is standard as it cannot be bound, 
			// but we ensure $table is safe (prefix + string) above.
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Internal custom table identifiers only.
			$from_codes = $wpdb->get_col( "SELECT DISTINCT from_currency FROM {$table_escaped}" );
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Internal custom table identifiers only.
			$to_codes   = $wpdb->get_col( "SELECT DISTINCT to_currency FROM {$table_escaped}" );
			if ( ! empty( $from_codes ) ) $codes = array_merge( $codes, $from_codes );
			if ( ! empty( $to_codes ) )   $codes = array_merge( $codes, $to_codes );
		}

		$all_supported_currencies = array(
			'ada','aed','afn','all','amd','aoa','ars','aud','awg','azn','bam','bbd','bdt','bgn','bhd','bif','bmd','bnb','bnd','bob','brl','bsd','btc','btn','bwp','byn','bzd','cad','cdf','chf','clp','cny','cop','crc','cup','cve','czk','djf','dkk','doge','dop','dzd','egp','ern','etb','eth','eur','fjd','fkp','gbp','gel','ghs','gip','gmd','gnf','gtq','gyd','hkd','hnl','htg','huf','idr','ils','inr','iqd','irr','isk','jmd','jod','jpy','kes','kgs','khr','kmf','kpw','krw','kwd','kyd','kzt','lak','lbp','lkr','lrd','lsl','lyd','mad','mdl','mga','mkd','mmk','mnt','mop','mru','mur','mvr','mwk','mxn','myr','mzn','nad','ngn','nio','nok','npr','nzd','omr','pab','pen','pgk','php','pkr','pln','pyg','qar','ron','rsd','rub','rwf','sar','sbd','scr','sdg','sek','sgd','shp','sle','sol','sos','srd','ssp','stn','svc','syp','szl','thb','tjs','tmt','tnd','top','trx','try','ttd','twd','tzs','uah','ugx','usd','usdc','usdt','uyu','uzs','ved','vnd','vuv','wst','xaf','xcd','xcg','xof','xpf','xrp','yer','zar','zmw','zwg'
		);

		$codes = array_merge( $codes, $all_supported_currencies );
		$codes = array_map( 'strtoupper', $codes );
		$codes = array_unique( $codes );
		sort( $codes );

		return array_values( $codes );
	}

    /**
     * Sanitizes and validates the settings input before saving to the database.
     * Also handles logic for CRON rescheduling if the update interval changes.
     *
     * @param array $input The raw input array from the settings form.
     * @return array The sanitized array.
     */
public function smart_convert_currency_unit_conversion_sanitize( $input ) {
		$sanitary_values = array();

        // 1. Sanitize the update interval.
        $new_interval = 24;
        if ( isset( $input['smart_convert_currency_unit_conversion_update_interval'] ) ) {
            $new_interval = absint( $input['smart_convert_currency_unit_conversion_update_interval'] );
            if ($new_interval < 1) $new_interval = 24; // Enforce minimum of 1 hour
        }
        $sanitary_values['smart_convert_currency_unit_conversion_update_interval'] = $new_interval;

        // 2. Detect changes to reset the CRON job.
        // Fetch old options to compare the previous interval with the new one.
        $old_options = get_option('smart_convert_currency_unit_conversion_option_name');
        $old_interval = isset($old_options['smart_convert_currency_unit_conversion_update_interval']) ? absint($old_options['smart_convert_currency_unit_conversion_update_interval']) : 24;

        // If the interval has changed, clear the scheduled hook.
        // The watchdog logic in smart-convert-currency-unit-conversion-cron.php (running on 'init') will detect the missing schedule and re-register it with the new frequency.
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Sanitize callback is triggered by Settings API which handles nonce verification.
        if ($old_interval !== $new_interval) {
            wp_clear_scheduled_hook('smart_convert_currency_unit_conversion_update_currency_hook');
        }
        
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Settings API handles nonce verification for inputs.
        $sanitary_values['smart_convert_currency_unit_conversion_enable_external_data'] = isset( $input['smart_convert_currency_unit_conversion_enable_external_data'] ) ? '1' : '0';
		if ( isset( $input['smart_convert_currency_unit_conversion_date_format'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_date_format'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_date_format'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_currency'] ) ) {$sanitary_values['smart_convert_currency_unit_conversion_default_currency'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_currency'] );}
        
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $sanitary_values['auto_currency_from_ip'] = isset( $input['auto_currency_from_ip'] ) ? '1' : '0';
        
        if ( isset( $input['smart_convert_currency_unit_conversion_ipinfo_token'] ) ) {$sanitary_values['smart_convert_currency_unit_conversion_ipinfo_token'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_ipinfo_token'] );}
		if ( isset( $input['smart_convert_currency_unit_conversion_default_temperature'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_temperature'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_temperature'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_length_long'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_length_long'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_length_long'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_length_short'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_length_short'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_length_short'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_speed'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_speed'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_speed'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_distance'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_distance'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_distance'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_weight'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_weight'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_weight'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_default_area'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_default_area'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_default_area'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_spread'] ) ) {
            $clean_spread = str_replace( ',', '.', $input['smart_convert_currency_unit_conversion_spread'] );
            $sanitary_values['smart_convert_currency_unit_conversion_spread'] = sanitize_text_field( $clean_spread );}
        
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
        $sanitary_values['smart_convert_currency_unit_conversion_spread_msg_enable'] = isset( $input['smart_convert_currency_unit_conversion_spread_msg_enable'] ) ? '1' : '0';
		
        if ( isset( $input['smart_convert_currency_unit_conversion_separator_thousands'] ) ) {
            $sanitary_values['smart_convert_currency_unit_conversion_separator_thousands'] = wp_strip_all_tags( $input['smart_convert_currency_unit_conversion_separator_thousands'] );
        }
		if ( isset( $input['smart_convert_currency_unit_conversion_separator_decimals'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_separator_decimals'] = sanitize_text_field( $input['smart_convert_currency_unit_conversion_separator_decimals'] );
        if ( isset( $input['smart_convert_currency_unit_conversion_bubble_color'] ) ) $sanitary_values['smart_convert_currency_unit_conversion_bubble_color'] = sanitize_hex_color( $input['smart_convert_currency_unit_conversion_bubble_color'] );
		if ( isset( $input['smart_convert_currency_unit_conversion_bubble_font'] ) )   $sanitary_values['smart_convert_currency_unit_conversion_bubble_font']   = sanitize_hex_color( $input['smart_convert_currency_unit_conversion_bubble_font'] );
        
		return $sanitary_values;
	}

    // Callbacks for Settings Sections
    public function smart_convert_currency_unit_conversion_section_general_info() {
        // translators: English: "Plugin Settings". Section heading for main plugin options.
		echo '<h2 id="smart-conver-pro-settings">' . esc_html__( 'General Settings', 'smart-convert-currency-unit-conversion' ) . '</h2>';
        // translators: English: "Configure core behavior and update options.". Section description for plugin settings.
		echo '<p class="description">' . esc_html__( 'In this section, you can set default units, number formats, and automatic currency selection based on user location.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}

	public function currency_converter_section_defaults_info() {
        // translators: English: "Default Units and Currency". Section heading for default conversion preferences.
		echo '<h2 id="smart-conver-pro-defaults">' . esc_html__( 'Default Target Units', 'smart-convert-currency-unit-conversion' ) . '</h2>';
        // translators: English: "These defaults are used when shortcode parameters are omitted.". Section description for defaults.
		echo '<p class="description">' . esc_html__( 'In this section, you can set default target units. Values will be converted to these default units if the target unit is not explicitly specified.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}

	public function currency_converter_section_appearance_info() {
        // translators: English: "Output Appearance". Section heading for conversion result styling options.
		echo '<h2 id="smart-conver-pro-appearance">' . esc_html__( 'Conversion Display Style', 'smart-convert-currency-unit-conversion' ) . '</h2>';
        // translators: English: "Customize visual style of conversion output bubble.". Section description for appearance settings.
		echo '<p class="description">' . esc_html__( 'In this section, you can customize the colors of the tooltip containing additional information, which appears in some templates when hovering over the relevant part.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}

    // Callbacks for specific fields
    public function smart_convert_currency_unit_conversion_update_interval_callback() {
        // Defaults to 24 hours if not set
        $val = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_update_interval'] ) ? absint( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_update_interval'] ) : 24;
        if ($val < 1) $val = 24;
        
        // translators: English: "hours". Suffix label for update interval numeric field.
        echo '<input type="number" min="1" max="720" step="1" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_update_interval]" value="' . esc_attr( $val ) . '" class="small-text" disabled /> ' . esc_html__( 'hours', 'smart-convert-currency-unit-conversion' );
        // translators: English: "Set how often rates should be refreshed automatically.". Helper text for update frequency field.
        echo '<p class="description">' . esc_html__( 'How often should the currency rate database be updated? Changes will take effect at the next run.', 'smart-convert-currency-unit-conversion' ) . '</p>';
    }

	public function smart_convert_currency_unit_conversion_default_currency_callback() {
		$saved_code = '';
		if ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency'] ) ) {
			$saved_code = esc_attr( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_currency'] );
		}

		$display_value = $saved_code;

		if ( ! empty( $saved_code ) ) {
			if ( function_exists( 'smart_convert_currency_unit_conversion_get_unit_name' ) ) {
				$unit_name  = smart_convert_currency_unit_conversion_get_unit_name( $saved_code );
				$code_upper = strtoupper( $saved_code );

				if ( ! empty( $unit_name ) && $unit_name !== $code_upper ) {
					$display_value = $code_upper . ' - ' . $unit_name;
				} else {
					$display_value = $code_upper;
				}
			} else {
				$display_value = strtoupper( $saved_code );
			}
		}

		printf(
			'<input type="hidden" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_currency]" id="smart_convert_currency_unit_conversion_default_currency" value="%s" />',
			esc_attr( $saved_code )
		);

		printf(
			'<input class="regular-text" type="text" id="smart_convert_currency_unit_conversion_default_currency_autocomplete" value="%s" placeholder="%s" autocomplete="off" />',
			esc_attr( $display_value ),
            // translators: English: "Default Currency". Placeholder text for default currency autocomplete input.
			esc_attr__( 'Currency', 'smart-convert-currency-unit-conversion' )
		);
	}

    public function auto_currency_from_ip_callback() {
        $checked = isset( $this->smart_convert_currency_unit_conversion_options['auto_currency_from_ip'] ) && $this->smart_convert_currency_unit_conversion_options['auto_currency_from_ip'] == '1' ? 'checked' : '';
        // Escaping $checked for security compliance
        echo '<input type="checkbox" name="smart_convert_currency_unit_conversion_option_name[auto_currency_from_ip]" id="auto_currency_from_ip" value="1" ' . esc_attr( $checked ) . ' />';
        // translators: English: "Automatically detect visitor currency from IP geolocation.". Helper text for auto-currency checkbox.
        echo '<p class="description">' . esc_html__( 'Instead of the selected default currency, the amount will be converted to the currency corresponding to the user\'s location. Geolocation from the IP address is used to determine the user\'s location. If the user\'s location cannot be determined, the amount is converted to the default currency. If the target currency is explicitly specified, the plugin will ignore the user\'s location.', 'smart-convert-currency-unit-conversion' ) . '</p>';
    }

    public function smart_convert_currency_unit_conversion_ipinfo_token_callback() {
        $token = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_ipinfo_token'] ) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_ipinfo_token'] : '';
        
        printf(
            '<input class="regular-text" type="text" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_ipinfo_token]" id="smart_convert_currency_unit_conversion_ipinfo_token" value="%s" placeholder="%s" />',
            esc_attr( $token ),
            // translators: English: "Enter your IPinfo token". Placeholder text for IPinfo API token field.
            esc_attr__( 'Required for Auto-Detect. E.g., 1a2b3c4d5e', 'smart-convert-currency-unit-conversion' )
        );        
        echo '<p class="description">';
        // translators: English: "Token is used only for country lookup to choose default currency.". Helper text for IPinfo token field.
        echo wp_kses_post(
            __( 'Get a free API token by registering at <a href="https://ipinfo.io/signup" target="_blank" rel="noopener noreferrer">IPinfo.io</a>. The Free Plan includes 50,000 requests per month, which is sufficient for most websites. Detailed instructions for obtaining the token can be found in the <a href="?page=smart-convert-pro&tab=help" target="_blank" rel="noopener noreferrer">Help</a> section.', 'smart-convert-currency-unit-conversion' )
        );
        echo '</p>';
    }

	public function smart_convert_currency_unit_conversion_default_temperature_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_temperature]" id="smart_convert_currency_unit_conversion_default_temperature">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_temperature'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_temperature'] === 'C' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>C</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_temperature'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_temperature'] === 'F' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>F</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_length_long_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_length_long]" id="smart_convert_currency_unit_conversion_default_length_long">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_long'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_long'] === 'm' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>m</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_long'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_long'] === 'ft' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>ft</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_length_short_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_length_short]" id="smart_convert_currency_unit_conversion_default_length_short">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_short'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_short'] === 'cm' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>cm</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_short'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_length_short'] === 'in' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>in</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_speed_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_speed]" id="smart_convert_currency_unit_conversion_default_speed">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_speed'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_speed'] === 'kph' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>kph</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_speed'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_speed'] === 'mph' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>mph</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_distance_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_distance]" id="smart_convert_currency_unit_conversion_default_distance">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_distance'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_distance'] === 'km' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>km</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_distance'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_distance'] === 'mi' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>mi</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_weight_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_weight]" id="smart_convert_currency_unit_conversion_default_weight">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_weight'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_weight'] === 'kg' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>kg</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_weight'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_weight'] === 'lb' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>lb</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_default_area_callback() {
		?>
		<select name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_default_area]" id="smart_convert_currency_unit_conversion_default_area">
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_area'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_area'] === 'sqkm' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>sqkm</option>
			<?php $selected = ( isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_area'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_default_area'] === 'sqmi' ) ? 'selected' : ''; ?>
			<option <?php echo esc_attr( $selected ); ?>>sqmi</option>
		</select>
		<?php
	}

	public function smart_convert_currency_unit_conversion_date_format_callback() {
		printf(
			'<input class="regular-text" type="text" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_date_format]" id="smart_convert_currency_unit_conversion_date_format" value="%s" />',
			isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_date_format'] ) ? esc_attr( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_date_format'] ) : ''
		);
	}

	public function smart_convert_currency_unit_conversion_spread_callback() {
		printf(
			'<input class="regular-text" type="text" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_spread]" id="smart_convert_currency_unit_conversion_spread" value="%s" />',
			isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_spread'] ) ? esc_attr( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_spread'] ) : ''
		);
	}
    public function smart_convert_currency_unit_conversion_spread_msg_enable_callback() {
		$checked = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_spread_msg_enable'] ) && $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_spread_msg_enable'] == '1' ? 'checked' : '';
		// Escaping $checked
		echo '<input type="checkbox" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_spread_msg_enable]" id="smart_convert_currency_unit_conversion_spread_msg_enable" value="1" ' . esc_attr( $checked ) . ' />';
        // translators: English: "Show a short notice when spread adjustment is applied to conversion.". Helper text for spread-info checkbox.
		echo '<p class="description">' . esc_html__( 'If the markup value is greater than 0 and this box is checked, the markup amount will be displayed along with the exchange rate information.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}
    public function smart_convert_currency_unit_conversion_separator_thousands_callback() {
        $val = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_thousands'] ) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_thousands'] : '';
        
        // Visual detection of the separator type (Space, NBSP, Character)
        $status_html = '';
        $hex = bin2hex($val); // Convert to HEX for precise character detection (e.g. nbsp)
        
        if ($val === '') {
            // translators: English: "Empty separator". Badge text when thousands separator value is empty.
            $status_html = '<span class="smart-convert-currency-unit-conversion-badge" style="background:#f0f0f1; color:#d63638; border:1px solid #dcdcde;">' . esc_html__( 'None', 'smart-convert-currency-unit-conversion' ) . '</span>';
        } elseif ($val === ' ') {
            // translators: English: "Space separator". Badge text when standard space is used as thousands separator.
            $status_html = '<span class="smart-convert-currency-unit-conversion-badge" style="background:#f0f0f1; color:#2271b1; border:1px solid #dcdcde;">' . esc_html__( 'Space', 'smart-convert-currency-unit-conversion' ) . '</span>';
        } elseif ($hex === 'c2a0') { // UTF-8 code for Non-Breaking Space (NBSP)
            // translators: English: "Non-breaking space separator". Badge text when NBSP is used as thousands separator.
            $status_html = '<span class="smart-convert-currency-unit-conversion-badge" style="background:#e7f5ea; color:#46b450; border:1px solid #c3e6cb;">' . esc_html__( 'Non-Breaking Space (nbsp)', 'smart-convert-currency-unit-conversion' ) . '</span>';
        } else {
            // Other character (dot, comma, etc.)
            // translators: English: "Custom character: %s". Badge text showing active thousands separator character.
            $status_html = '<span class="smart-convert-currency-unit-conversion-badge" style="background:#f0f0f1; color:#1d2327; border:1px solid #dcdcde;">' . sprintf( esc_html__( 'Character "%s"', 'smart-convert-currency-unit-conversion' ), esc_html($val)) . '</span>';
        }

		printf(
			'<input class="regular-text" type="text" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_separator_thousands]" id="smart_convert_currency_unit_conversion_separator_thousands" value="%s" style="width: 50px; text-align: center;" /> %s',
			esc_attr( $val ),
			wp_kses_post( $status_html )
		);
        
        // Helper buttons for invisible characters
        ?>
        <p class="description" style="margin-top: 8px;">
            <?php // translators: English: "Use space or NBSP for locales that group thousands with spaces.". Helper text for thousands separator control. ?>
            <?php echo esc_html__( 'While a normal space allows text wrapping at the end of a line, a non-breaking space prevents it and keeps connected terms or parts of numbers together.', 'smart-convert-currency-unit-conversion' ); ?><br>
            <button type="button" class="button button-small" onclick="document.getElementById('smart_convert_currency_unit_conversion_separator_thousands').value=' '; document.getElementById('smart_convert_currency_unit_conversion_separator_thousands').focus();"><?php // translators: English: "Insert space". Utility button label for separator field. ?><?php echo esc_html__( 'Insert Space', 'smart-convert-currency-unit-conversion' ); ?></button>
            <button type="button" class="button button-small" onclick="document.getElementById('smart_convert_currency_unit_conversion_separator_thousands').value='\u00A0'; document.getElementById('smart_convert_currency_unit_conversion_separator_thousands').focus();"><?php // translators: English: "Insert NBSP". Utility button label for separator field. ?><?php echo esc_html__( 'Insert Non-Breaking Space (nbsp)', 'smart-convert-currency-unit-conversion' ); ?></button>
        </p>
        <?php
	}

	public function smart_convert_currency_unit_conversion_separator_decimals_callback() {
		printf(
			'<input class="regular-text" type="text" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_separator_decimals]" id="smart_convert_currency_unit_conversion_separator_decimals" value="%s" />',
			isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_decimals'] ) ? esc_attr( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_separator_decimals'] ) : ''
		);
	}
    public function smart_convert_currency_unit_conversion_bubble_color_callback() {
		$value = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_bubble_color'] ) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_bubble_color'] : '#1A2F45';
		printf(
			'<input type="color" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_bubble_color]" id="smart_convert_currency_unit_conversion_bubble_color" value="%s" />',
			esc_attr( $value )
		);
        // translators: English: "Select the background color of the conversion result bubble.". Helper text for bubble background color picker.
		echo '<p class="description">' . esc_html__( 'Select a background color from the palette, or enter its code.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}

	public function smart_convert_currency_unit_conversion_bubble_font_callback() {
		$value = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_bubble_font'] ) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_bubble_font'] : '#ffffff';
		printf(
			'<input type="color" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_bubble_font]" id="smart_convert_currency_unit_conversion_bubble_font" value="%s" />',
			esc_attr( $value )
		);
        // translators: English: "Select the text color used inside the conversion result bubble.". Helper text for bubble font color picker.
		echo '<p class="description">' . esc_html__( 'Select a text color from the palette, or enter its code.', 'smart-convert-currency-unit-conversion' ) . '</p>';
	}    



    /**
     * Redirects to the onboarding page after activation if the transient is set.
     */
    public function smart_convert_currency_unit_conversion_welcome_redirect_logic() {
        if ( get_transient( 'smart_convert_currency_unit_conversion_welcome_redirect' ) ) {
            delete_transient( 'smart_convert_currency_unit_conversion_welcome_redirect' );
            
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only redirect guard after activation.
            if ( ! is_network_admin() && ! isset( $_GET['activate-multi'] ) ) {
                wp_safe_redirect( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=onboarding' ) );
                exit;
            }
        }
    }

/**
     * Settings callback for the External Data Checkbox.
     * Renders a checkbox input field indicating if external data connection is enabled.
     */
    public function smart_convert_currency_unit_conversion_enable_external_data_callback() {
        // Retrieve current value
        $val = isset( $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_enable_external_data'] ) ? $this->smart_convert_currency_unit_conversion_options['smart_convert_currency_unit_conversion_enable_external_data'] : '0';
        
        // Render checkbox using WP helper `checked()`.
        // First arg is current value, second is expected checked value.
        // We use printf to safely output the HTML with checked() result.
        ?>
        <input type="checkbox" name="smart_convert_currency_unit_conversion_option_name[smart_convert_currency_unit_conversion_enable_external_data]" id="smart_convert_currency_unit_conversion_enable_external_data" value="1" <?php checked( $val, '1' ); ?> />
        <p class="description">
            <?php // translators: English: "Allow external data access for rates and unit source updates.". Helper text for external-data consent checkbox. ?>
            <?php echo esc_html__( 'To convert currencies using currently valid rates, you must enable data downloading from an external server. If you disable rate downloading, the plugin will still work, but outdated currency rates will be used.', 'smart-convert-currency-unit-conversion' ); ?>
        </p>
        <?php
    }

    /**
     * AJAX Handler: Activates the external connection and performs initial data fetch.
     * Saves the user consent to the database options and triggers data downloads.
     */
    public function ajax_activate_connection() {
        check_ajax_referer( 'smart_convert_currency_unit_conversion_onboarding_nonce' );
        
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }
    
        // 1. Save Consent
        // We must load the full options array, modify a single value, and save it back.
        $options = get_option( 'smart_convert_currency_unit_conversion_option_name', array() );
        
        // Explicitly set the flag to '1'.
        $options['smart_convert_currency_unit_conversion_enable_external_data'] = '1';
        
        update_option( 'smart_convert_currency_unit_conversion_option_name', $options );
    
        // 2. Perform initial data download (now legal as consent is given).
        $units_res = function_exists('smart_convert_currency_unit_conversion_update_units_csv_once') ? smart_convert_currency_unit_conversion_update_units_csv_once( true ) : false;
        $rates_res = function_exists('smart_convert_currency_unit_conversion_update_currency_csv') ? smart_convert_currency_unit_conversion_update_currency_csv() : false;
    
        if ( is_wp_error( $rates_res ) ) {
            // Escaping error message before sending
            wp_send_json_error(
                array(
                    'message' => esc_html( $rates_res->get_error_message() ),
                )
            );
        }
    
        wp_send_json_success();
    }

    /**
     * Adds a "Settings" link to the plugin list row on the Plugins page.
     */
    public function smart_convert_currency_unit_conversion_add_action_links( $links, $file = '' ) {
        // Check if this applies to our specific plugin file.
        if ( $file !== '' && strpos( $file, 'smart-convert-currency-unit-conversion' ) === false && strpos( $file, 'index.php' ) === false ) {
            return $links;
        }
        
        // If utilizing a generic filter without the $file parameter, just add the link.
        // Escaping the URL and the label.
        // translators: English: "Settings". Plugin row action link label in WordPress plugins list.
        $settings_link = '<a href="' . esc_url( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion' ) ) . '">' . esc_html__( 'Settings', 'smart-convert-currency-unit-conversion' ) . '</a>';
        
        // Prepend the settings link to the action array.
        array_unshift( $links, $settings_link );
        
        return $links;
    }
    
    
    /**
     * AJAX: Get Unit Details for Editing
     */
    public function ajax_get_unit_details() {
        check_ajax_referer('smart_convert_currency_unit_conversion_custom_unit_action');
        if (!current_user_can('manage_options')) {
            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        if ( ! isset( $_POST['id'] ) ) {
             wp_send_json_error( array( 'message' => 'Missing ID' ) );
        }

        global $wpdb;
        // Sanitize and unslash input
        $id = absint( wp_unslash( $_POST['id'] ) );
        
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query necessary.
        $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units WHERE id = %d", $id), ARRAY_A);
        
        if (!$row) {
            wp_send_json_error( array( 'message' => 'Unit not found' ) );
        }
        
        wp_send_json_success($row);
    }

    /**
     * AJAX: Export Custom Units to JSON file.
     */
    public function ajax_export_units() {
        check_ajax_referer('smart_convert_currency_unit_conversion_custom_unit_action');
        if (!current_user_can('manage_options')) {
             wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query necessary.
        $units = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}smart_convert_currency_unit_conversion_units WHERE is_custom = 1", ARRAY_A);
        
        if (empty($units)) {
            wp_send_json_error( array( 'message' => __( 'There are no custom units available to export.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        $data = [
            'version' => '1.0',
            'exported_at' => current_time('mysql'),
            'units' => $units
        ];

        // Trigger JSON file download
        // Use gmdate() instead of date() to avoid timezone issues.
        $filename = 'smart-convert-currency-unit-conversion-units-export-' . gmdate('Y-m-d') . '.json';
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        echo wp_json_encode($data, JSON_PRETTY_PRINT);
        exit;
    }

    /**
     * AJAX: Import Custom Units from JSON.
     * Handles file upload, parsing, and insertion into database based on selected strategy (skip/overwrite).
     */
 public function ajax_import_units() {
        // Verify nonce for security
        check_ajax_referer('smart_convert_currency_unit_conversion_custom_unit_action');
        
        if (!current_user_can('manage_options')) {
            wp_send_json_error( array( 'message' => __( 'You do not have permission to perform this action.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        if ( ! isset( $_FILES['import_file'] ) || empty( $_FILES['import_file']['tmp_name'] ) ) {
            wp_send_json_error( array( 'message' => __( 'No file was uploaded.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We sanitize each field immediately below.
        $import_file = wp_unslash( $_FILES['import_file'] );
        $tmp_name    = isset( $import_file['tmp_name'] ) ? sanitize_text_field( $import_file['tmp_name'] ) : '';
        $file_name   = isset( $import_file['name'] ) ? sanitize_file_name( $import_file['name'] ) : '';

        if ( '' === $tmp_name || ! is_uploaded_file( $tmp_name ) ) {
            wp_send_json_error( array( 'message' => __( 'Uploaded file is invalid.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        $filetype = wp_check_filetype_and_ext( $tmp_name, $file_name, array( 'json' => 'application/json' ) );
        if ( empty( $filetype['ext'] ) || 'json' !== strtolower( (string) $filetype['ext'] ) ) {
            wp_send_json_error( array( 'message' => __( 'Only JSON files are allowed.', 'smart-convert-currency-unit-conversion' ) ) );
        }
        
        // Read file content
        $content = file_get_contents( $tmp_name );
        if ( empty( $content ) ) {
             wp_send_json_error( array( 'message' => __( 'You are attempting to upload an invalid JSON file.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        $json = json_decode($content, true);

        if ( ! $json || ! isset( $json['units'] ) || ! is_array( $json['units'] ) ) {
            wp_send_json_error( array( 'message' => __( 'You are attempting to upload an invalid JSON file.', 'smart-convert-currency-unit-conversion' ) ) );
        }

        global $wpdb;
        $table = $wpdb->prefix . 'smart_convert_currency_unit_conversion_units';
        
        // Sanitize and unslash POST data securely
        $strategy = 'skip';
        if ( isset( $_POST['strategy'] ) ) {
            $strategy_input = sanitize_key( wp_unslash( $_POST['strategy'] ) );
            if ( in_array( $strategy_input, array( 'skip', 'overwrite' ), true ) ) {
                $strategy = $strategy_input;
            }
        }

        $imported = 0;
        $skipped = 0;
        $updated = 0;

        foreach ( $json['units'] as $unit ) {
            if ( ! is_array( $unit ) || ! isset( $unit['unit_from'], $unit['unit_to'] ) ) {
                $skipped++;
                continue;
            }
            // Check if exists (matched by unique from/to pair)
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query necessary.
            $existing = $wpdb->get_row( $wpdb->prepare(
                'SELECT id FROM `' . esc_sql( $table ) . '` WHERE unit_from = %s AND unit_to = %s AND is_custom = 1',
                sanitize_text_field( (string) $unit['unit_from'] ),
                sanitize_text_field( (string) $unit['unit_to'] )
            ) );

            $data = [
                'unit_from' => sanitize_text_field( (string) $unit['unit_from'] ),
                'unit_to' => sanitize_text_field( (string) $unit['unit_to'] ),
                'factor' => isset( $unit['factor'] ) ? (float) $unit['factor'] : 0.0,
                'offset' => isset( $unit['offset'] ) ? (float) $unit['offset'] : 0.0,
                'symbol_after' => isset( $unit['symbol_after'] ) ? sanitize_text_field( (string) $unit['symbol_after'] ) : '',
                'unit_from_name' => isset( $unit['unit_from_name'] ) ? sanitize_text_field( (string) $unit['unit_from_name'] ) : '',
                'symbol_from_before' => isset( $unit['symbol_from_before'] ) ? sanitize_text_field( (string) $unit['symbol_from_before'] ) : '',
                'symbol_from_after' => isset( $unit['symbol_from_after'] ) ? sanitize_text_field( (string) $unit['symbol_from_after'] ) : '',
                'unit_to_name' => isset( $unit['unit_to_name'] ) ? sanitize_text_field( (string) $unit['unit_to_name'] ) : '',
                'symbol_to_before' => isset( $unit['symbol_to_before'] ) ? sanitize_text_field( (string) $unit['symbol_to_before'] ) : '',
                'symbol_to_after' => isset( $unit['symbol_to_after'] ) ? sanitize_text_field( (string) $unit['symbol_to_after'] ) : '',
                'is_custom' => 1,
                'updated_at' => current_time( 'mysql' )
            ];
            
            $format = ['%s','%s','%f','%f','%s','%s','%s','%s','%s','%s','%s','%d','%s'];

            if ($existing) {
                if ($strategy === 'overwrite') {
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table update.
                    $wpdb->update($table, $data, ['id' => $existing->id], $format, ['%d']);
                    $updated++;
                } else {
                    $skipped++;
                }
            } else {
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table insert.
                $wpdb->insert($table, $data, $format);
                $imported++;
            }
        }

        wp_send_json_success(
            array(
                'message' => sprintf(
                    /* translators: 1: imported units count, 2: updated units count, 3: skipped units count. */
                    __( 'Done! %1$d units were imported, %2$d were updated, and %3$d were skipped.', 'smart-convert-currency-unit-conversion' ),
                    $imported,
                    $updated,
                    $skipped
                ),
            )
        );
    }
private function render_onboarding_page() {
    ?>
    <div class="wrap smart-convert-currency-unit-conversion-onboarding-body">
        <div class="smart-convert-currency-unit-conversion-onboarding-wrapper">
            <span class="smart-convert-currency-unit-conversion-hero-icon">🚀</span>
            <h1>
                <?php // translators: English: "Let's get this currency party started!". Onboarding page heading shown after activation. ?>
                <?php echo esc_html__( 'Let\'s get this currency party started!', 'smart-convert-currency-unit-conversion' ); ?>
            </h1>
            <p class="smart-convert-currency-unit-conversion-intro-text">
                <?php // translators: English: "To ensure the plugin functions correctly, currency exchange rates and unit conversions need to be downloaded. In order to comply with WordPress.org regulations, your explicit consent for connection to external sources is required.". Onboarding intro paragraph. ?><?php echo esc_html__( 'To ensure the plugin functions correctly, currency exchange rates and unit conversions need to be downloaded. In order to comply with WordPress.org security guidelines, we never download external data without the user\'s explicit consent. Please enable the connection below so we can download the latest currency rates and unit definitions.', 'smart-convert-currency-unit-conversion' ); ?>
            </p>
            
            <div class="smart-convert-currency-unit-conversion-consent-wrapper">
                <input type="checkbox" id="smart-convert-currency-unit-conversion-consent-cb" class="smart-convert-currency-unit-conversion-hidden-cb">
                <label for="smart-convert-currency-unit-conversion-consent-cb" class="smart-convert-currency-unit-conversion-custom-label">
                    <span class="smart-convert-currency-unit-conversion-custom-box"></span>
                    <span class="smart-convert-currency-unit-conversion-checkbox-text">
                        <?php // translators: English: "Allow rate updates from external source". Consent checkbox label on onboarding page. ?>
                        <?php echo esc_html__( 'Allow rate updates from external source', 'smart-convert-currency-unit-conversion' ); ?>
                    </span>
                </label>
            </div>

            <button id="smart-convert-currency-unit-conversion-start-setup" class="smart-convert-currency-unit-conversion-btn-connect" disabled>
                <span class="dashicons dashicons-cloud" style="font-size: 24px; width: 24px; height: 24px;"></span>
                <?php // translators: English: "Connect and Download Current Rates". Primary onboarding button label. ?>
                <?php echo esc_html__( 'Connect and Download Current Rates', 'smart-convert-currency-unit-conversion' ); ?>
            </button>
            
            <div class="smart-convert-currency-unit-conversion-loader">
                <span class="dashicons dashicons-update spin"></span> 
                <span id="smart-convert-currency-unit-conversion-loader-text">
                    <?php // translators: English: "Downloading current currency rates and unit conversions…". Loader text shown during onboarding setup. ?>
                    <?php echo esc_html__( 'Downloading current currency rates and unit conversions…', 'smart-convert-currency-unit-conversion' ); ?>
                </span>
            </div>

            <p class="smart-convert-currency-unit-conversion-legal-small">
                <?php // translators: English: "By clicking the button above, you agree to connect to an external server and download currency rates and unit conversions. You can turn this option off at any time later in the settings. If you revoke consent, it will not be possible to use current currency rates.". Onboarding legal/info note. ?>
                <?php echo esc_html__( 'By clicking the button above, you agree to connect to an external server and download currency rates and unit conversions. You can turn this option off at any time later in the settings. If you revoke consent, it will not be possible to use current currency rates.', 'smart-convert-currency-unit-conversion' ); ?>
            </p>
        </div>
    </div>
    <?php
    
    // Enqueue inline script for onboarding page
    wp_register_script('smart-convert-currency-unit-conversion-onboarding-inline', '', array('jquery'), SMART_CONVERT_VERSION, true);
    wp_enqueue_script('smart-convert-currency-unit-conversion-onboarding-inline');

    $smart_convert_currency_unit_conversion_redirect_url = wp_json_encode( esc_url( admin_url( 'options-general.php?page=smart-convert-currency-unit-conversion&tab=settings' ) ) );    
    $onboarding_js = "
    jQuery(document).ready(function($) {
        $('#smart-convert-currency-unit-conversion-consent-cb').on('change', function() {
            var isChecked = $(this).is(':checked');
            var \$btn = $('#smart-convert-currency-unit-conversion-start-setup');
            if (isChecked) {
                \$btn.prop('disabled', false).removeClass('disabled');
            } else {
                \$btn.prop('disabled', true).addClass('disabled');
            }
        });
        $('#smart-convert-currency-unit-conversion-start-setup').on('click', function(e) {
            e.preventDefault();
            if ($(this).prop('disabled')) return;
            var \$btn = $(this);
            var \$loader = $('.smart-convert-currency-unit-conversion-loader');
            var \$text = $('#smart-convert-currency-unit-conversion-loader-text');
            var \$checkboxRow = $('.smart-convert-currency-unit-conversion-consent-wrapper');
            \$btn.hide();
            \$checkboxRow.hide(); 
            \$loader.show();
            \$text.text('" . esc_js(
                /* translators: English: "Connecting...". Onboarding loader text while API connection is being activated. */
                __( 'Connecting...', 'smart-convert-currency-unit-conversion' )
            ) . "');
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'smart_convert_currency_unit_conversion_activate_connection',
                    _wpnonce: '" . esc_js(wp_create_nonce('smart_convert_currency_unit_conversion_onboarding_nonce')) . "'
                },
                success: function(response) {
                    if(response.success) {
                        \$text.html('<strong>" . esc_js(
                            /* translators: English: "Done! Redirecting you to plugin settings!". Onboarding success text after external source connection. */
                            __( 'Done! Redirecting you to plugin settings!', 'smart-convert-currency-unit-conversion' )
                        ) . "</strong>');
                        setTimeout(function() {
                            window.location.href = " . $smart_convert_currency_unit_conversion_redirect_url . ";
                        }, 1000);
                    } else {
                        \$btn.show();
                        \$checkboxRow.show();
                        \$loader.hide();
                        alert('Error: ' + (response.data || 'Unknown error'));
                    }
                },
                error: function() {
                    \$btn.show();
                    \$checkboxRow.show();
                    \$loader.hide();
                    alert('Connection failed. Please try again.');
                }
            });
        });
    });
    ";
    
    wp_add_inline_script('smart-convert-currency-unit-conversion-onboarding-inline', $onboarding_js);
}

    /**
     * Filter: pre_load_script_translations
     * Force en_US JSON catalog as the single runtime translation source.
     *
     * @param mixed  $translations Default null.
     * @param string $file         The JSON file path (usually null if not found yet).
     * @param string $handle       Script handle.
     * @param string $domain       Text domain.
     * @return mixed JSON content string or null.
     */
   public function smart_convert_currency_unit_conversion_force_json_content_locale( $translations, $file, $handle, $domain ) {
        if ( $domain !== 'smart-convert-currency-unit-conversion' ) return $translations;
        $en_us_path = SMART_CONVERT_PLUGIN_DIR . '/languages/' . $domain . '-en_US-' . $handle . '.json';
        if ( file_exists( $en_us_path ) ) {
            $content = file_get_contents( $en_us_path );
            if ( $content ) {
                return $content;
            }
        }
        return $translations;
    }

    public function smart_convert_currency_unit_conversion_json_translation_file_en_us( $file, $handle, $domain ) {
        if ( $domain !== 'smart-convert-currency-unit-conversion' ) return $file;
        if ( $file && file_exists( $file ) ) return $file;
        $new_file = SMART_CONVERT_PLUGIN_DIR . '/languages/' . $domain . '-en_US-' . $handle . '.json';
        if ( file_exists( $new_file ) ) return $new_file;
        return $file;
    }
    
/**
     * Helper to sanitize unit symbols.
     * Preserves spaces by converting them to Non-Breaking Spaces (NBSP).
     *
     * @param string $input Raw input string from POST.
     * @return string Sanitized string safe for database.
     */
    private function sanitize_unit_symbol( $input ) {
        if ( empty( $input ) ) {
            return '';
        }

        // Define a unique placeholder for spaces.
        // We do this because wp_strip_all_tags() automatically trims whitespace,
        // which would destroy the leading/trailing spaces we need to preserve.
        $space_placeholder = '___WP_SPACE_HOLDER___';

        // 1. Protect spaces by replacing them with the placeholder.
        $protected_input = str_replace( ' ', $space_placeholder, $input );

        // 2. Sanitize the string using the WordPress native function.
        // This satisfies the repository requirement (replacing strip_tags).
        $clean = wp_strip_all_tags( $protected_input );

        // 3. Convert the placeholders to Non-Breaking Spaces (UTF-8 0xC2 0xA0).
        return str_replace( $space_placeholder, "\xC2\xA0", $clean );
    }
        
}