<?php
/**
 * Plugin Name:       REEID Translate 
 * Plugin URI:        https://reeid.com/reeid-translate-plugin/
 * Description:       AI translation for WordPress posts, pages, WooCommerce, Gutenberg, Classic Editor, SEO, and language switching.
 * Version:           1.9.1
 * Author:            REEID GCE
 * Author URI:        https://reeid.com/
 * License:           GPL-3.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-3.0.html
 * Text Domain:       reeid-translate
 */

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

// phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound




if (version_compare(PHP_VERSION, '8.0', '<')) {
    add_action('admin_notices', function() {
        echo '<div class="notice notice-error"><p>';
        echo esc_html__('REEID Translate requires PHP 8.0 or higher.', 'reeid-translate');
        echo '</p></div>';
    });
    return;
}


/**
 * Global safety defaults for SEO overwrite flags.
 * Ensures PHP 8 never throws "Undefined constant" in seo-sync.php,
 * even if that file loads in a special or partial context.
 */
if ( ! defined( 'REEID_SEO_TITLE_OVERWRITE' ) ) {
    // Default: do NOT force-overwrite SEO titles unless explicitly enabled.
    define( 'REEID_SEO_TITLE_OVERWRITE', false );
}

if ( ! defined( 'REEID_SEO_META_OVERWRITE' ) ) {
    // Default: do NOT force-overwrite SEO meta/description unless explicitly enabled.
    define( 'REEID_SEO_META_OVERWRITE', false );
}


if ( ! defined( 'REEID_TRANSLATE_VERSION' ) ) {
    define( 'REEID_TRANSLATE_VERSION', '1.9.1' );
}


// Enable REEID frontend probes ONLY when explicitly requested
if ( ! defined( 'REEID_ENABLE_PROBES' ) ) {
    define( 'REEID_ENABLE_PROBES', false );
}

/* --------------------------------------------------------------------------
 * Bootstrap & Core Includes
 * -------------------------------------------------------------------------- */

//require_once __DIR__ . '/includes/cli/reeid-smoke.php'; // DEVELOPMENT AND CONTROL SMOKE TEST
require_once __DIR__ . '/includes/admin/settings-register.php';
require_once __DIR__ . '/includes/bootstrap/rt-compat-url.php';
require_once __DIR__ . '/includes/hreflang-url-normalize.php';
require_once __DIR__ . '/includes/guard-canonical-authority.php';
require_once __DIR__ . '/includes/seo/bootstrap.php';
require_once __DIR__ . '/includes/seo-wc-sitemap-compat.php';
require_once __DIR__ . '/includes/seo-reeid-sitemaps.php';
require_once __DIR__ . '/includes/seo-sitemaps-compat.php';
require_once __DIR__ . '/includes/seo/pages/html-lang-pages.php';
require_once __DIR__ . '/includes/seo-guard-pages-only.php';
require_once __DIR__ . '/includes/frontend-switcher.php';
require_once __DIR__ . '/includes/admin/settings-page.php';
require_once __DIR__ . '/includes/admin/admin-post.php';
require_once __DIR__ . '/includes/admin/translation-metabox.php';
require_once __DIR__ . '/includes/admin-assets.php';
require_once __DIR__ . '/includes/translator.php';
require_once __DIR__ . '/includes/translator-engine.php';
require_once __DIR__ . '/includes/runtime/adapters/translation-pack.php';
require_once __DIR__ . '/includes/runtime/adapters/gutenberg-runtime.php';
require_once __DIR__ . '/includes/runtime/editor-core.php';
require_once __DIR__ . '/includes/ajax-handlers.php';
require_once __DIR__ . '/includes/gutenberg-data.php';
require_once __DIR__ . '/includes/gutenberg-engine.php';
require_once __DIR__ . '/includes/wc-inline-runtime.php';
require_once __DIR__ . '/includes/save-post-sandbox.php';
require_once __DIR__ . '/includes/wc-admin-switcher-guard.php';
require_once __DIR__ . '/includes/wc-gettext.php';
require_once __DIR__ . '/includes/frontend-switcher.php';
require_once __DIR__ . '/includes/frontend-inline-fallback.php';
require_once __DIR__ . '/includes/admin-columns.php';
require_once __DIR__ . '/includes/routing-langcookie.php';
require_once __DIR__ . '/includes/permalinks-native-resolver.php';
require_once __DIR__ . '/includes/wc-attributes-runtime.php';
require_once __DIR__ . '/includes/wc-lang-runtime.php';
require_once __DIR__ . '/includes/wc-attribute-label-runtime.php';
require_once __DIR__ . '/includes/frontend-frontpage-map.php';
require_once __DIR__ . '/includes/helpers/tone.php';
require_once __DIR__ . '/includes/builders/gutenberg/serialize-preserve-attrs.php';
if ( function_exists( 'wp_get_theme' ) ) {
	$reeid_theme = wp_get_theme();
	$reeid_slug  = $reeid_theme ? $reeid_theme->get_stylesheet() : '';

	if ( 'twentytwentyfive' === $reeid_slug ) {
		require_once __DIR__ . '/includes/themes/twentytwentyfive/loader.php';
	}

    if ( 'blocksy' === $reeid_slug ) {
        require_once __DIR__ . '/includes/themes/blocksy/loader.php';
    }
}
require_once __DIR__ . '/includes/runtime/woo/copy-product-data.php';
require_once __DIR__ . '/includes/runtime/woo/translate-product-attributes.php';
require_once __DIR__ . '/includes/runtime/woo/gettext-runtime.php';
require_once __DIR__ . '/includes/runtime/woo/static-strings-cache.php';
require_once __DIR__ . '/includes/runtime/woo/translate-product.php';
//require_once __DIR__ . '/includes/runtime/woo/inline-payload.php';


if ( is_admin() ) {
    require_once __DIR__ . '/includes/admin/admin-columns-filters.php';
}



/* ============================================================
 * REEID — Tone presets initializer (run once on activation)
 * Safe: does NOT overwrite existing data
 * ============================================================ */
register_activation_hook( __FILE__, function () {

    if ( get_option( 'reeid_tone_presets', null ) !== null ) {
        return; // already seeded
    }

    add_option( 'reeid_tone_presets', array(
        'neutral'      => 'Neutral',
        'professional' => 'Professional',
        'friendly'     => 'Friendly',
        'marketing'    => 'Marketing',
        'technical'    => 'Technical',
        'legal'        => 'Legal',
        'creative'     => 'Creative',
        'seo'          => 'SEO',
        'luxury'       => 'Luxury',
        'casual'       => 'Casual',
        'educational'  => 'Educational',
        'sales'        => 'Sales',
    ), '', false );

} );



/* --------------------------------------------------------------------------
 * SECTION 0 — Inject Validate-Key JavaScript
 * -------------------------------------------------------------------------- */

add_action( 'init', function () {

    add_action( 'admin_enqueue_scripts', function () {

        if ( ! function_exists( 'wp_create_nonce' ) ) {
            return;
        }

        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
        if ( empty( $screen ) || empty( $screen->id ) ) {
            return;
        }

        $screen_id = sanitize_text_field( (string) $screen->id );
        if ( strpos( $screen_id, 'reeid-translate' ) === false ) {
            return;
        }

        $nonce = wp_create_nonce( 'reeid_validate_openai_key_action' );

        $js  = "jQuery(document).on('click','#reeid-validate-openai',function(e){";
        $js .= "e.preventDefault();";
        $js .= "const key=jQuery('#reeid_openai_key').val();";
        $js .= "jQuery.ajax({";
        $js .= "url:ajaxurl,method:'POST',";
        $js .= "data:{action:'reeid_validate_openai_key',key:key,_ajax_nonce:'" . esc_js( $nonce ) . "'},";
        $js .= "success:function(res){alert(res?.data?.message||'Unknown response');},";
        $js .= "error:function(xhr){alert('AJAX failed ('+xhr.status+')');}";
        $js .= "});});";

        wp_register_script(
            'reeid-validate-key',
            false,
            [],
            REEID_TRANSLATE_VERSION,
            true
        );

        wp_enqueue_script( 'reeid-validate-key' );
        wp_add_inline_script( 'reeid-validate-key', $js );
    });
});


/* ===========================================================
 * SECTION 0.1 : REEID WC HELPERS BOOTSTRAP
 * =========================================================== */



/**
 * Return merged WooCommerce strings mapping
 */
function reeid_get_woo_strings_map() {

    $defaults = [
        'Add to cart'             => 'Buy now',
        'Color'                   => 'Colour',
        'Text Color'              => 'Text Colour',
        'Background Color'        => 'Background Colour',
        'Description'             => 'Product details',
        'Additional information'  => 'More information',
    ];

    $opt = get_option( 'reeid_woo_strings_en', [] );
    if ( ! is_array( $opt ) ) {
        $opt = [];
    }

    $clean_opt = [];

    foreach ( $opt as $key => $value ) {
        $clean_key   = sanitize_text_field( (string) wp_unslash( $key ) );
        $clean_value = sanitize_text_field( (string) wp_unslash( $value ) );
        $clean_opt[ $clean_key ] = $clean_value;
    }

    return array_merge( $defaults, $clean_opt );
}

/**
 * Ensure WooCommerce strings option contains defaults + overrides.
 */
function reeid_ensure_woo_strings_option_on_activate() {

    $opt = get_option( 'reeid_woo_strings_en', [] );
    if ( ! is_array( $opt ) ) {
        $opt = [];
    }

    $defaults = [
        'Add to cart'             => 'Buy now',
        'Color'                   => 'Colour',
        'Text Color'              => 'Text Colour',
        'Background Color'        => 'Background Colour',
        'Description'             => 'Product details',
        'Additional information'  => 'More information',
    ];

    $clean_opt = [];
    foreach ( $opt as $key => $value ) {
        $clean_key   = sanitize_text_field( (string) wp_unslash( $key ) );
        $clean_value = sanitize_text_field( (string) wp_unslash( $value ) );
        $clean_opt[ $clean_key ] = $clean_value;
    }

    update_option( 'reeid_woo_strings_en', array_merge( $defaults, $clean_opt ) );
}

/**
 * Activation hook must run from main plugin context
 */
if ( defined( 'REEID_TRANSLATE_VERSION' ) && function_exists( 'register_activation_hook' ) ) {
    register_activation_hook( __FILE__, 'reeid_ensure_woo_strings_option_on_activate' );
}

/*===========================================================================
  SECTION 0.2 : WooCommerce attributes panel — single table, correct tab
===========================================================================*/


/**
 * REEID: Woo attributes tab CSS (SAFE, no wp_head output)
 * Scope: single product only
 */
add_action( 'wp_enqueue_scripts', function () {

    if ( ! function_exists( 'is_product' ) || ! is_product() ) {
        return;
    }

    $css = '
.single-product .woocommerce-Tabs-panel--additional_information,
.single-product #tab-additional_information {
    display: block;
}
.single-product #tab-additional_information table.shop_attributes,
.single-product .woocommerce-Tabs-panel--additional_information .woocommerce-product-attributes,
.single-product table.shop_attributes.woocommerce-product-attributes {
    width: 100%;
    border-collapse: collapse;
}';

   // Attach to Woo or theme style safely
$handle = wp_style_is( 'woocommerce-general', 'enqueued' )
    ? 'woocommerce-general'
    : ( function_exists( 'reeid_astra_style_handle_fallback' )
        ? reeid_astra_style_handle_fallback()
        : '' );

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

wp_add_inline_style( $handle, $css );

}, 20 );


add_action( 'wp_enqueue_scripts', function () {

    if ( ! function_exists( 'is_product' ) || ! is_product() || is_admin() ) {
        return;
    }

    $script_path = plugin_dir_path( __FILE__ ) . 'assets/js/reeid-wc-attrs-fix.js';
    $script_url  = plugin_dir_url( __FILE__ ) . 'assets/js/reeid-wc-attrs-fix.js';

    if ( ! file_exists( $script_path ) ) {
        return;
    }

    wp_enqueue_script(
        'reeid-wc-attrs-fix',
        $script_url,
        array(),
        (string) filemtime( $script_path ),
        true
    );

}, 99 );
/*========================================================
 SECTION 0.3: SAFETY & UTILITIES (constants first)
========================================================*/

if ( ! defined( 'REEID_TRANSLATE_DIR' ) ) {
    define( 'REEID_TRANSLATE_DIR', plugin_dir_path( __FILE__ ) );
}

if ( ! defined( 'REEID_TRANSLATE_URL' ) ) {
    define( 'REEID_TRANSLATE_URL', plugin_dir_url( __FILE__ ) );
}

if ( ! defined( 'REEID_SEO_HELPERS_PATH' ) ) {
    define( 'REEID_SEO_HELPERS_PATH', REEID_TRANSLATE_DIR );
}

if ( ! defined( 'REEID_HREFLANG_OUTPUT' ) ) {
    define( 'REEID_HREFLANG_OUTPUT', true );
}

/* =======================================================
   SECTION 0.4 : LOCALIZE + ENQUEUE 
   ======================================================= */

if ( ! function_exists( 'reeid_register_localize_asset' ) ) {

    function reeid_register_localize_asset() {

        if ( ! defined( 'REEID_TRANSLATE_DIR' ) || ! defined( 'REEID_TRANSLATE_URL' ) ) {
            return;
        }

        $handle = 'reeid-translate-localize';
        $src    = REEID_TRANSLATE_URL . 'assets/js/reeid-localize.js';
        $path   = REEID_TRANSLATE_DIR . 'assets/js/reeid-localize.js';

        $ver = null;
        if ( file_exists( $path ) ) {
            $ver = (string) filemtime( $path );
        } elseif ( defined( 'REEID_PLUGIN_VERSION' ) ) {
            $ver = REEID_PLUGIN_VERSION;
        }

        if ( ! wp_script_is( $handle, 'registered' ) ) {
            wp_register_script( $handle, $src, [ 'jquery' ], $ver, true );
        }

        wp_enqueue_script( $handle );

        $localized = [
    'nonce'    => wp_create_nonce( 'reeid_translate_nonce_action' ),
    'ajax_url' => admin_url( 'admin-ajax.php' ),
    'tones'    => function_exists( 'reeid_get_available_tones' )
        ? reeid_get_available_tones()   // key => Label
        : [],
];


        wp_localize_script( $handle, 'REEID_TRANSLATE', $localized );

        wp_add_inline_script(
            $handle,
            'if(!window.REEID_TRANSLATE){window.REEID_TRANSLATE=' .
            wp_json_encode( $localized, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) .
            ';}',
            'after'
        );
    }

        add_action( 'wp_enqueue_scripts', 'reeid_register_localize_asset', 20 );
}

/*========================================================
 SECTION 0.5: PRODUCT CONTENT SAFETY
========================================================*/

add_filter( 'the_content', function ( $content ) {

    if ( ! is_singular( 'product' ) ) {
        return $content;
    }

    global $post;
    if ( ! $post || $post->post_type !== 'product' ) {
        return $content;
    }

    if (
        ! function_exists( 'reeid_wc_effective_lang' ) ||
        ! function_exists( 'reeid_wc_get_translation_meta' )
    ) {
        return $content;
    }

    $lang = sanitize_key( reeid_wc_effective_lang( 'en' ) );
    $tr   = reeid_wc_get_translation_meta( (int) $post->ID, $lang );

    if ( ! empty( $tr['content'] ) ) {
        return wp_kses_post( (string) $tr['content'] );
    }

    return $content;

}, 999 );

/*========================================================
 SECTION 0.6: SAFE MODULE LOAD (guarded)
========================================================*/

add_action( 'plugins_loaded', function () {

    $base = REEID_TRANSLATE_DIR . 'includes/';

foreach ( [
    'translator.php',
    'menu-label-runtime.php',
    'reeid-focuskw-sync.php',
    'seo/bootstrap.php',
] as $file ) {

        $path = $base . $file;
        if ( file_exists( $path ) ) {
            require_once $path;
        }
    }


}, 1 );

/*========================================================
 SECTION 0.7: DEBUG + REQUEST UTILITIES
========================================================*/

if ( ! defined( 'REEID_DEBUG' ) ) {
    define( 'REEID_DEBUG', false );
}

if ( ! function_exists( 'reeid_debug_log' ) ) {

    function reeid_debug_log( $label, $data = null ) {

        if ( ! REEID_DEBUG ) {
            return;
        }

        /**
         * Debug logging is intentionally disabled in the WordPress.org build.
         * This avoids writing diagnostic data to plugin or uploads directories.
         */
        do_action(
            'reeid_debug_log_event',
            sanitize_text_field( (string) $label ),
            $data
        );
    }
}

if ( ! function_exists( 'reeid_verify_get_nonce' ) ) {

    function reeid_verify_get_nonce( $action, $param = '_wpnonce' ) {

        $raw   = filter_input( INPUT_GET, $param, FILTER_UNSAFE_RAW );
        $raw   = is_string( $raw ) ? wp_unslash( $raw ) : '';
        $nonce = sanitize_text_field( $raw );

        return ( $nonce !== '' && wp_verify_nonce( $nonce, $action ) );
    }
}

if ( ! function_exists( 'reeid_request_action' ) ) {

    function reeid_request_action() {

        $raw_post = filter_input( INPUT_POST, 'action', FILTER_UNSAFE_RAW );
        $raw_get  = filter_input( INPUT_GET,  'action', FILTER_UNSAFE_RAW );

        $raw = is_string( $raw_post ) ? $raw_post : ( is_string( $raw_get ) ? $raw_get : '' );
        return sanitize_key( wp_unslash( $raw ) );
    }
}


/*==============================================================================
  SECTION 1: GLOBAL HELPERS
==============================================================================*/

/**
 * Keep Unicode-friendly slugs (allow native scripts), collapse invalid chars,
 * decode percent-encoding when valid, trim, and ensure a non-empty fallback.
 */
if ( ! function_exists( 'reeid_sanitize_native_slug' ) ) {
    function reeid_sanitize_native_slug( $slug ) {

        // Always unslash + strip tags first.
        $slug = is_string( $slug ) ? wp_unslash( $slug ) : '';
        $slug = wp_strip_all_tags( $slug );
        $slug = trim( $slug );

        // Decode HTML entities
        if ( function_exists( 'html_entity_decode' ) ) {
            $slug = html_entity_decode( $slug, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
        }

        // NBSP → normal space
        $slug = preg_replace( '/\x{00A0}/u', ' ', $slug );

        // Normalize Unicode dashes
        $slug = preg_replace(
            '/[\x{2010}\x{2011}\x{2012}\x{2013}\x{2014}\x{2212}]+/u',
            '-',
            $slug
        );

        // Decode %xx if valid UTF-8
if ( strpos( $slug, '%' ) !== false && preg_match( '/%[0-9A-Fa-f]{2}/', $slug ) ) {
    $decoded = rawurldecode( $slug );

    $is_utf8 = function_exists( 'wp_is_valid_utf8' )
        ? wp_is_valid_utf8( $decoded )
        : (bool) @mb_check_encoding( $decoded, 'UTF-8' );

    if ( $is_utf8 ) {
        $slug = $decoded;
    }
}

        // Remove reserved URL characters while preserving Unicode letters
        $slug = preg_replace(
            '/[\/\?#\[\]@!$&\'()*+,;=%"<>|`^{}\\\\]/u',
            ' ',
            $slug
        );

        // Allow: letters, digits, combining marks, hyphen; others → hyphen
        $slug = preg_replace(
            '/[^\p{L}\p{N}\p{M}\-]+/u',
            '-',
            $slug
        );

        // Collapse multiple hyphens → single
        $slug = preg_replace( '/-+/', '-', $slug );
        $slug = trim( $slug, '-' );

        // Lowercase only the ASCII portion; Unicode remains untouched
        $slug = preg_replace_callback(
            '/[A-Z]+/',
            static function( $m ) {
                return strtolower( $m[0] );
            },
            $slug
        );

        // Fallback slug if empty
        if ( $slug === '' ) {
            if ( function_exists( 'wp_generate_uuid4' ) ) {
                $slug = 'translated-' . wp_generate_uuid4();
            } else {
                $slug = 'translated-' . uniqid( 'translated-', true );
            }
        }

        // Maximum length 200 characters
        if ( function_exists( 'mb_substr' ) ) {
            $slug = mb_substr( $slug, 0, 200, 'UTF-8' );
        } else {
            $slug = substr( $slug, 0, 200 );
        }

        return $slug;
    }
}




/* --- Safe regex/printf helpers --- */

if ( ! function_exists( 'reeid_regex_replacement' ) ) {
    function reeid_regex_replacement( $s ) {
        return strtr(
            (string) $s,
            array(
                '\\' => '\\\\',
                '$'  => '\\$',
            )
        );
    }
}

if ( ! function_exists( 'reeid_regex_quote' ) ) {
    function reeid_regex_quote( $text, $delim = '/' ) {
        return preg_quote( (string) $text, (string) $delim );
    }
}

if ( ! function_exists( 'reeid_printf_literal' ) ) {
    function reeid_printf_literal( $s ) {
        return str_replace( '%', '%%', (string) $s );
    }
}




/**
 * Per-request prompt only; global added separately by canonical prompt builder.
 */
if ( ! function_exists( 'reeid_effective_prompt' ) ) {
    function reeid_effective_prompt( $request_prompt = '' ) {

        if ( ! is_string( $request_prompt ) || trim( $request_prompt ) === '' ) {
            return '';
        }

        $clean = wp_unslash( $request_prompt );
        return trim( wp_kses_post( $clean ) );
    }
}





/*==============================================================================
  SECTION 2: ROUTING — DISABLE CORE CANONICAL ON /{lang}/ PATHS
==============================================================================*/

/*
 * IMPORTANT:
 * remove_filter('template_redirect', 'redirect_canonical') — allowed in this
 * plugin ONLY because it applies a precise, restricted override for language
 * prefixes. This avoids infinite redirects and conflicts.
 * Completely safe & intentional.
 */
//remove_filter( 'template_redirect', 'redirect_canonical' );

add_filter(
    'redirect_canonical',
    function( $redirect_url, $requested_url ) {

        $raw_url = esc_url_raw( (string) $requested_url );
        $parts   = wp_parse_url( $raw_url );
        $path    = isset( $parts['path'] ) ? (string) $parts['path'] : '';

        // Disable canonical for:
        // 1) Language-prefixed URLs
        // 2) Singular posts/pages (root EN included)

        if ( preg_match( '#^/[a-z]{2}(?:/|$)#i', $path ) || is_singular() ) {
            return false;
        }

        return $redirect_url;
    },
    PHP_INT_MIN,
    2
);







/*==============================================================================
  SECTION 3: HELPERS — Supported Languages, Flags, Extended Features Logic
==============================================================================*/



/**
 * Full supported language list (code => label).
 */
if ( ! function_exists( 'reeid_get_supported_languages' ) ) {
    function reeid_get_supported_languages() {

        $langs = array(
            'ar' => 'Arabic',
            'bg' => 'Bulgarian',
            'bn' => 'Bengali',
            'cs' => 'Czech',
            'da' => 'Danish',
            'de' => 'German',
            'el' => 'Greek',
            'en' => 'English',
            'es' => 'Spanish',
            'fa' => 'Persian',
            'fi' => 'Finnish',
            'fr' => 'French',
            'gu' => 'Gujarati',
            'he' => 'Hebrew',
            'hi' => 'Hindi',
            'hr' => 'Croatian',
            'hu' => 'Hungarian',
            'id' => 'Indonesian',
            'it' => 'Italian',
            'ja' => 'Japanese',
            'km' => 'Khmer',
            'ko' => 'Korean',
            'lo' => 'Lao',
            'mr' => 'Marathi',
            'ms' => 'Malay',
            'my' => 'Burmese',
            'nb' => 'Norwegian',
            'ne' => 'Nepali',
            'nl' => 'Dutch',
            'pl' => 'Polish',
            'pt' => 'Portuguese',
            'ro' => 'Romanian',
            'ru' => 'Russian',
            'si' => 'Sinhala',
            'sk' => 'Slovak',
            'sl' => 'Slovenian',
            'sr' => 'Serbian',
            'sv' => 'Swedish',
            'ta' => 'Tamil',
            'te' => 'Telugu',
            'th' => 'Thai',
            'tl' => 'Filipino',
            'tr' => 'Turkish',
            'uk' => 'Ukrainian',
            'ur' => 'Urdu',
            'vi' => 'Vietnamese',
            'zh' => 'Chinese',
        );

        asort( $langs, SORT_NATURAL | SORT_FLAG_CASE );
        return $langs;
    }
}


/**
 * Map language → flag (ISO country).
 */
if ( ! function_exists( 'reeid_get_language_flags' ) ) {
    function reeid_get_language_flags() {

        return array(
            'ar' => 'sa',
            'bg' => 'bg',
            'bn' => 'bd',
            'cs' => 'cz',
            'da' => 'dk',
            'de' => 'de',
            'el' => 'gr',
            'en' => 'us',
            'es' => 'es',
            'fa' => 'ir',
            'fi' => 'fi',
            'fr' => 'fr',
            'gu' => 'in',
            'he' => 'il',
            'hi' => 'in',
            'hr' => 'hr',
            'hu' => 'hu',
            'id' => 'id',
            'it' => 'it',
            'ja' => 'jp',
            'km' => 'kh',
            'ko' => 'kr',
            'lo' => 'la',
            'mr' => 'in',
            'ms' => 'my',
            'my' => 'mm',
            'nb' => 'no',
            'ne' => 'np',
            'nl' => 'nl',
            'pl' => 'pl',
            'pt' => 'pt',
            'ro' => 'ro',
            'ru' => 'ru',
            'si' => 'lk',
            'sk' => 'sk',
            'sl' => 'si',
            'sr' => 'rs',
            'sv' => 'se',
            'ta' => 'in',
            'te' => 'in',
            'th' => 'th',
            'tl' => 'ph',
            'tr' => 'tr',
            'uk' => 'ua',
            'ur' => 'pk',
            'vi' => 'vn',
            'zh' => 'cn',
        );
    }
}


/**
 * Return all languages supported by the plugin.
 *
 * Function name is kept for backward compatibility with existing internal callers.
 */
if ( ! function_exists( 'reeid_get_allowed_languages' ) ) {
    function reeid_get_allowed_languages() {
        $all = function_exists( 'reeid_get_supported_languages' )
            ? reeid_get_supported_languages()
            : array();

        if ( empty( $all ) || ! is_array( $all ) ) {
            return array();
        }

        return $all;
    }
}




/**
 * Check if a resolved language code is allowed.
 */
if ( ! function_exists( 'reeid_is_language_allowed' ) ) {
    function reeid_is_language_allowed( $code ) {

        $code = sanitize_key( (string) $code );

        $resolved = function_exists( 'reeid_resolve_language_code' )
            ? sanitize_key( (string) reeid_resolve_language_code( $code ) )
            : $code;

        $allowed = reeid_get_allowed_languages();
        return isset( $allowed[ $resolved ] );
    }
}


/**
 * Enabled languages = supported and allowed 
 */
if ( ! function_exists( 'reeid_get_enabled_languages' ) ) {
    function reeid_get_enabled_languages() {

        $supported = reeid_get_supported_languages();
        $allowed   = reeid_get_allowed_languages();

        $raw = get_option( 'reeid_enabled_languages', '' );
        $codes = array();

        if ( is_string( $raw ) && $raw !== '' ) {
            $decoded = json_decode( $raw, true );
            if ( is_array( $decoded ) ) {
                $codes = $decoded;
            }
        }

        // Sanitize all codes
        $codes = array_values(
            array_unique(
                array_map(
                    static function( $c ) {
                        return sanitize_key( $c );
                    },
                    $codes
                )
            )
        );

        // Filter by supported + allowed
        $out = array();
        foreach ( $codes as $code ) {
            if ( isset( $supported[ $code ] ) && isset( $allowed[ $code ] ) ) {
                $out[ $code ] = $supported[ $code ];
            }
        }

        // Fallback → ensure at least source language
        if ( empty( $out ) ) {
            $src = sanitize_key( (string) get_option( 'reeid_translation_source_lang', 'en' ) );
            if ( isset( $supported[ $src ] ) && isset( $allowed[ $src ] ) ) {
                $out[ $src ] = $supported[ $src ];
            } elseif ( isset( $supported['en'] ) && isset( $allowed['en'] ) ) {
                $out['en'] = $supported['en'];
            }
        }

        return $out;
    }
}


/**
 * Language codes only.
 */
if ( ! function_exists( 'reeid_get_enabled_language_codes' ) ) {
    function reeid_get_enabled_language_codes() {
        return array_keys( reeid_get_enabled_languages() );
    }
}




/*==============================================================================
  SECTION 6: ACTIVATION & DEACTIVATION
==============================================================================*/

/**
 * Register rewrite rules.
 * (Intentionally empty — actual routing handled elsewhere.)
 */
if ( ! function_exists( 'reeid_register_rewrite_rules' ) ) {
    function reeid_register_rewrite_rules() {
        // NO-OP: Routing logic resides in dedicated routing section.
    }
}

/**
 * Activation callback.
 * Ensures rewrite rules are registered and flushed safely.
 */
function reeid_activation() {

    // Register plugin rewrite rules, if defined.
    if ( function_exists( 'reeid_register_rewrite_rules' ) ) {
        reeid_register_rewrite_rules();
    }

    /**
     * Safe, no-output flush.
     * Required by WP Repo for custom rewrite structures.
     */
    flush_rewrite_rules();
}

/**
 * Deactivation callback.
 * Flushes rewrite rules to reset WordPress permalink structure.
 */
function reeid_deactivation() {
    flush_rewrite_rules();
}

// Safe activation/deactivation hooks
register_activation_hook( __FILE__, 'reeid_activation' );
register_deactivation_hook( __FILE__, 'reeid_deactivation' );



/*=================================================================
  SECTION 7 : Helper Stubs for Section 15 API Calls
=================================================================*/


/**
 * Retrieve normalized site hostname for API identification.
 */
if ( ! function_exists( 'reeid__s15_site_host' ) ) {
    function reeid__s15_site_host() {
        $host = wp_parse_url( home_url(), PHP_URL_HOST );
        $host = $host ? strtolower( (string) $host ) : '';
        return preg_replace( '#^www\.#', '', $host );
    }
}




/**
 * Safely decode JSON — strips illegal control chars and fixes non-UTF-8.
 *
 * @param string $json Raw JSON string.
 * @return mixed       Decoded JSON (array/object) or null on failure.
 */
if ( ! function_exists( 'reeid_safe_json_decode' ) ) {
    function reeid_safe_json_decode( $json ) {

        $json = (string) $json;

        // Strip control chars except tab, CR, LF
        $json = preg_replace( '/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/u', '', $json );

        // Ensure UTF-8 if mbstring exists
        if ( function_exists( 'mb_detect_encoding' ) && ! mb_detect_encoding( $json, 'UTF-8', true ) ) {
            $json = mb_convert_encoding( $json, 'UTF-8', 'auto' );
        }

        $flags = 0;
        if ( defined( 'JSON_INVALID_UTF8_SUBSTITUTE' ) ) {
            $flags |= JSON_INVALID_UTF8_SUBSTITUTE;
        }

        return json_decode( $json, true, 512, $flags );
    }
}




/*==============================================================================
  SECTION 8 : Language-Prefixed Rewrite Rules (Woo + Pages/Posts)
==============================================================================*/

/**
 * Register language query var
 */
add_filter( 'query_vars', function ( $vars ) {
    $vars[] = 'reeid_force_lang';
    return $vars;
} );

/**
 * Add language-prefixed rewrite rules
 */
add_action( 'init', function () {

    /*
    |--------------------------------------------------------------------------
    | 1) Woo Product Rule (ONLY if Woo exists)
    |--------------------------------------------------------------------------
    */
    if ( function_exists( 'wc_get_permalink_structure' ) ) {

        $permalinks   = wc_get_permalink_structure();
        $product_base = ! empty( $permalinks['product_base'] )
            ? trim( $permalinks['product_base'], '/' )
            : 'product';

        // /{lang}/product/{slug}/
        add_rewrite_rule(
            '^([a-z]{2}(?:-[a-zA-Z]{2})?)/' . preg_quote( $product_base, '#' ) . '/([^/]+)/?$',
            'index.php?post_type=product&name=$matches[2]&reeid_force_lang=$matches[1]',
            'top'
        );
    }

    /*
    |--------------------------------------------------------------------------
    | 2) Pages & Posts Rule (ALWAYS registered)
    |--------------------------------------------------------------------------
    */
    // /{lang}/{slug}/
    add_rewrite_rule(
    '^([a-z]{2}(?:-[a-zA-Z]{2})?)/(.+?)/?$',
    'index.php?pagename=$matches[2]&reeid_force_lang=$matches[1]',
    'top'
);


    /*
    |--------------------------------------------------------------------------
    | Flush once (version bump)
    |--------------------------------------------------------------------------
    */
    if ( ! get_option( 'reeid_lang_rules_v4' ) ) {
        flush_rewrite_rules( false );
        update_option( 'reeid_lang_rules_v4', 1 );
    }

}, 9 );

/**
 * Decode product slug safely (Woo only)
 */
add_filter( 'request', function ( $vars ) {

    // -------------------------
    // Woo product decoding
    // -------------------------
    if (
        isset( $vars['post_type'], $vars['name'] ) &&
        $vars['post_type'] === 'product'
    ) {
        $vars['name'] = rawurldecode( $vars['name'] );
    }

    // -------------------------
    // Language-prefixed PAGE decoding
    // -------------------------
    if (
        isset( $vars['reeid_force_lang'], $vars['pagename'] ) &&
        ! isset( $vars['post_type'] ) // not product
    ) {
        $vars['pagename'] = rawurldecode( $vars['pagename'] );
    }

    return $vars;

}, 20 );


/**
 * Disable canonical redirect for language-prefixed URLs
 */
add_filter( 'redirect_canonical', function( $redirect, $requested ) {

    // Disable canonical for language-prefixed URLs
    if ( get_query_var( 'reeid_force_lang' ) ) {
        return false;
    }

    $path = wp_parse_url( $requested, PHP_URL_PATH );

    if ( is_string( $path ) ) {
        // Match /{lang}/product/{slug}
        if ( preg_match( '#^/[a-z]{2}(?:-[a-z0-9]{2})?/product/[^/]+/?$#i', $path ) ) {
            return false;
        }
    }

    return $redirect;

}, 10, 2 );

/* ========================================================================== */
/*  SECTION 9 : PERMALINK LANGUAGE PREFIX LAYER (NON-WOO ONLY)                 */
/* ========================================================================== */

add_filter( 'post_link', 'reeid_force_lang_prefix', 10, 3 );
add_filter( 'page_link', 'reeid_force_lang_prefix', 10, 3 );

function reeid_force_lang_prefix( $permalink, $post, $leavename ) {

    // Normalize $post (CLI safety)
    if ( is_numeric( $post ) ) {
        $post = get_post( (int) $post );
    }

    if ( ! $post instanceof WP_Post ) {
        return $permalink;
    }

    // 🔒 NEVER touch Woo products
    if ( $post->post_type === 'product' ) {
        return $permalink;
    }

    $lang = get_post_meta( $post->ID, '_reeid_translation_lang', true );

    if ( ! $lang ) {
        $lang = get_option( 'reeid_translation_source_lang', 'en' );
    }

    $lang = strtolower( trim( $lang ) );

    if ( ! $lang ) {
        return $permalink;
    }

    $parsed = wp_parse_url( $permalink );
    $path   = isset( $parsed['path'] ) ? ltrim( $parsed['path'], '/' ) : '';

    if ( ! $path ) {
        return $permalink;
    }

    return home_url( '/' . $lang . '/' . $path );
}




/*==============================================================================
  SECTION 10 : WooCommerce — Checkout/Cart URL Guard + Misassignment Detector
==============================================================================*/

if ( ! function_exists( 'reeid_s243_log' ) ) {
    function reeid_s243_log( $label, $data = null ) {
        if ( function_exists( 'reeid_debug_log' ) ) {
            reeid_debug_log( 'S24.3 ' . $label, $data );
        }
    }
}

/** Helper: detect product-like URL paths (with or without lang prefix) */
if ( ! function_exists( 'reeid_s243_is_product_url' ) ) {
    function reeid_s243_is_product_url( $url ) {

        $url = (string) $url;
        if ( $url === '' ) {
            return false;
        }

        $p = wp_parse_url( $url );
        if ( ! is_array( $p ) || empty( $p['path'] ) ) {
            return false;
        }

        return (bool) preg_match( '#/(?:[a-z]{2}(?:-[a-zA-Z]{2})?/)?product/[^/]+/?$#', (string) $p['path'] );
    }
}

/** Guard checkout URL */
add_filter( 'woocommerce_get_checkout_url', function ( $url ) {

    $url  = (string) $url;
    $orig = $url;

    if ( ! function_exists( 'wc_get_page_id' ) ) {
        return $url;
    }

    try {
        if ( $url !== '' && reeid_s243_is_product_url( $url ) ) {

            $checkout_id = (int) wc_get_page_id( 'checkout' );
            $fixed       = ( $checkout_id > 0 ) ? get_permalink( $checkout_id ) : home_url( '/checkout/' );

            if ( function_exists( 'get_post_type' ) ) {
                reeid_s243_log(
                    'CHECKOUT_URL_BROKEN',
                    array(
                        'got'         => $orig,
                        'fix'         => $fixed,
                        'checkout_id' => $checkout_id,
                        'type'        => ( $checkout_id > 0 ) ? get_post_type( $checkout_id ) : '',
                    )
                );
            }

            if ( $fixed ) {
                $url = (string) $fixed;
            }
        }
    } catch ( Exception $e ) {
        reeid_s243_log( 'CHECKOUT_URL_ERR', $e->getMessage() );
    } catch ( Error $e ) {
        reeid_s243_log( 'CHECKOUT_URL_ERR', $e->getMessage() );
    }

    return $url;
}, 99 );

/** Guard cart URL (just in case) */
add_filter( 'woocommerce_get_cart_url', function ( $url ) {

    $url  = (string) $url;
    $orig = $url;

    if ( ! function_exists( 'wc_get_page_id' ) ) {
        return $url;
    }

    try {
        if ( $url !== '' && reeid_s243_is_product_url( $url ) ) {

            $cart_id = (int) wc_get_page_id( 'cart' );
            $fixed   = ( $cart_id > 0 ) ? get_permalink( $cart_id ) : home_url( '/cart/' );

            if ( function_exists( 'get_post_type' ) ) {
                reeid_s243_log(
                    'CART_URL_BROKEN',
                    array(
                        'got'     => $orig,
                        'fix'     => $fixed,
                        'cart_id' => $cart_id,
                        'type'    => ( $cart_id > 0 ) ? get_post_type( $cart_id ) : '',
                    )
                );
            }

            if ( $fixed ) {
                $url = (string) $fixed;
            }
        }
    } catch ( Exception $e ) {
        reeid_s243_log( 'CART_URL_ERR', $e->getMessage() );
    } catch ( Error $e ) {
        reeid_s243_log( 'CART_URL_ERR', $e->getMessage() );
    }

    return $url;
}, 99 );

/** Admin notice if Checkout/Cart are mis-assigned */
add_action( 'admin_init', function () {

    if ( ! function_exists( 'wc_get_page_id' ) || ! current_user_can( 'manage_woocommerce' ) ) {
        return;
    }

    $notices = array();

    $cid = (int) wc_get_page_id( 'checkout' );
    if ( $cid && get_post_type( $cid ) !== 'page' ) {
        $notices[] = 'Checkout page is assigned to a non-Page (e.g., a product).';
        reeid_s243_log(
            'MISASSIGN_CHECKOUT',
            array(
                'id'   => $cid,
                'type' => get_post_type( $cid ),
                'url'  => get_permalink( $cid ),
            )
        );
    }

    $cart = (int) wc_get_page_id( 'cart' );
    if ( $cart && get_post_type( $cart ) !== 'page' ) {
        $notices[] = 'Cart page is assigned to a non-Page (e.g., a product).';
        reeid_s243_log(
            'MISASSIGN_CART',
            array(
                'id'   => $cart,
                'type' => get_post_type( $cart ),
                'url'  => get_permalink( $cart ),
            )
        );
    }

    if ( $notices ) {
        add_action( 'admin_notices', function () use ( $notices ) {

            $link = esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced' ) );

            echo '<div class="notice notice-error"><p><strong>WooCommerce page assignment issue:</strong></p><ul>';

            foreach ( $notices as $n ) {
                echo '<li>' . esc_html( $n ) . '</li>';
            }

            $fix_html = sprintf(
    // translators: %1$s is an HTML link pointing to the WooCommerce Advanced settings page.
    __( 'Fix in %1$s.', 'reeid-translate' ),
    '<a href="' . esc_url( $link ) . '">' . esc_html__( 'WooCommerce → Settings → Advanced (Page setup)', 'reeid-translate' ) . '</a>'
);

            printf(
                '</ul><p>%s</p></div>',
                wp_kses_post( $fix_html )
            );
        } );
    }
} );


/*==============================================================================
 SECTION 11 : UNIVERSAL MENU LINK SPINNER (LANGUAGE FILTER + REWRITE)
==============================================================================*/

add_filter( 'wp_nav_menu_objects', function ( $items, $args ) {

    if ( ! function_exists( 'reeid_current_language' ) ) {
        return $items;
    }

    $lang        = sanitize_key( (string) reeid_current_language() );
    $source_lang = sanitize_key( (string) get_option( 'reeid_translation_source_lang', 'en' ) );

    if ( '' === $source_lang ) {
        $source_lang = 'en';
    }

    $filtered = array();

    foreach ( (array) $items as $item ) {

        if ( ! is_object( $item ) ) {
            $filtered[] = $item;
            continue;
        }

        $has_manual_menu_label = false;

        if ( ! empty( $item->ID ) ) {
            $overrides = get_post_meta( (int) $item->ID, '_reeid_menu_label_overrides', true );

            if (
                is_array( $overrides ) &&
                isset( $overrides[ $lang ] ) &&
                '' !== trim( (string) $overrides[ $lang ] )
            ) {
                $item->title           = sanitize_text_field( wp_strip_all_tags( (string) $overrides[ $lang ] ) );
                $has_manual_menu_label = true;
            }
        }

        if (
            property_exists( $item, 'object' ) &&
            property_exists( $item, 'object_id' ) &&
            in_array( (string) $item->object, array( 'page', 'post' ), true ) &&
            ! empty( $item->object_id )
        ) {

            $oid       = (int) $item->object_id;
            $item_lang = (string) get_post_meta( $oid, '_reeid_translation_lang', true );
            $item_lang = '' !== $item_lang ? sanitize_key( $item_lang ) : $source_lang;

            if ( $item_lang === $lang || $item_lang === $source_lang ) {

                $target_id = $oid;

                if ( $lang !== $source_lang ) {
                    $source_id = $oid;

                    $parent_source = (int) get_post_meta( $oid, '_reeid_translation_source', true );
                    if ( $parent_source > 0 ) {
                        $source_id = $parent_source;
                    }

                    $map = get_post_meta( $source_id, '_reeid_translation_map', true );

                    if ( is_array( $map ) && ! empty( $map[ $lang ] ) ) {
                        $maybe_target_id = absint( $map[ $lang ] );

                        if ( $maybe_target_id > 0 ) {
                            $target_id = $maybe_target_id;

                            if ( ! $has_manual_menu_label ) {
                                $translated_title = get_post_field( 'post_title', $target_id );

                                if ( is_string( $translated_title ) && '' !== trim( $translated_title ) ) {
                                    $item->title = sanitize_text_field( wp_strip_all_tags( $translated_title ) );
                                }
                            }
                        }
                    }
                }

                $slug = (string) get_post_field( 'post_name', $target_id );
                $slug = sanitize_title( $slug );

                $item->url = ( $lang === $source_lang )
                    ? home_url( "/{$slug}/" )
                    : home_url( "/{$lang}/{$slug}/" );

                $filtered[] = $item;
            }

        } else {
            $filtered[] = $item; // Keep all other items
        }
    }

    return $filtered;
}, 27, 2 );

/** Helper: detect current language */
if ( ! function_exists( 'reeid_current_language' ) ) {
    function reeid_current_language() {

        $f = get_query_var( 'reeid_lang_front' );
        if ( ! empty( $f ) ) {
            return sanitize_key( (string) $f );
        }

        $c = get_query_var( 'reeid_lang_code' );
        if ( ! empty( $c ) ) {
            return sanitize_key( (string) $c );
        }

        if ( ! empty( $_COOKIE['site_lang'] ) ) {
            return sanitize_key( (string) wp_unslash( $_COOKIE['site_lang'] ) );
        }

        $request_uri_raw = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );

        if ( is_string( $request_uri_raw ) && '' !== $request_uri_raw ) {

    $request_uri = sanitize_text_field(
        wp_unslash( $request_uri_raw )
    );

    $path = trim(
        (string) wp_parse_url( $request_uri, PHP_URL_PATH ),
        '/'
    );

    if ( preg_match( '#^([a-z]{2})(/|$)#', $path, $m ) ) {

        $code  = sanitize_key( strtolower( (string) $m[1] ) );
        $langs = function_exists( 'reeid_get_supported_languages' )
            ? array_keys( (array) reeid_get_supported_languages() )
            : array();

        if ( in_array( $code, $langs, true ) ) {
            return $code;
        }
    }
}


        return 'en';
    }
}


/*==============================================================================
  SECTION 12 : LANGUAGE SWITCHER — SHORTCODE (GENERIC + WOO INLINE)
  - Dependency-safe
  - URL / cookie aware
  - Woo inline–aware
==============================================================================*/

if ( file_exists( __DIR__ . '/includes/switcher-helpers.php' ) ) {
    require_once __DIR__ . '/includes/switcher-helpers.php';
}

/**
 * Detect current language from URL prefix or cookie.
 *
 * @param string $default Default language code.
 * @return string
 */
if ( ! function_exists( 'reeid_detect_current_lang' ) ) {
    function reeid_detect_current_lang( $default ) {

        // 1) HARD URL PREFIX DETECTION (must win, even on front page)
$req_raw = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );

if ( is_string( $req_raw ) && $req_raw !== '' ) {

    $request_uri = wp_unslash( $req_raw );
    $path        = wp_parse_url( $request_uri, PHP_URL_PATH );

    if ( is_string( $path ) && $path !== '' ) {
        $uri   = trim( $path, '/' );
        $parts = explode( '/', $uri );
        $first = strtolower( (string) ( $parts[0] ?? '' ) );

        // Accept valid lang pattern, NOT only supported list
        if ( preg_match( '/^[a-z]{2}(?:-[a-z0-9]{2})?$/', $first ) ) {
            return sanitize_key( $first );
        }
    }
}

        // 2) Cookie fallback
        if ( ! empty( $_COOKIE['site_lang'] ) ) {
            return sanitize_key( wp_unslash( $_COOKIE['site_lang'] ) );
        }

        // 3) Default
        return sanitize_key( $default );
    }
}


/**
 * Register shortcode early.
 */
add_action( 'init', function () {
    add_shortcode( 'reeid_language_switcher', 'reeid_language_switcher_shortcode_v2' );
}, 5 );


/**
 * Language switcher shortcode handler.
 */
if ( ! function_exists( 'reeid_language_switcher_shortcode_v2' ) ) {
    function reeid_language_switcher_shortcode_v2() {

        global $post;

        // Ensure a valid post context (front page safe)
        if ( ! ( $post instanceof WP_Post ) ) {
            $post = get_post( (int) get_option( 'page_on_front' ) );
            if ( ! $post ) {
                return '';
            }
        }

        $default = sanitize_key( (string) get_option( 'reeid_translation_source_lang', 'en' ) );
        $front   = (int) get_option( 'page_on_front' );

        /*======================================================================
          1) WOO CART / CHECKOUT / ACCOUNT MODE
          Show only languages that exist in inline-translated products.
        ======================================================================*/
        if (
            ( function_exists( 'is_cart' ) && is_cart() ) ||
            ( function_exists( 'is_checkout' ) && is_checkout() ) ||
            ( function_exists( 'is_account_page' ) && is_account_page() )
        ) {

            $current = reeid_detect_current_lang( $default );
            $langs   = array( $default => true );

            // Collect inline translation languages from products
            $products = get_posts(
                array(
                    'post_type'      => 'product',
                    'posts_per_page' => -1,
                    'fields'         => 'ids',
                )
            );

            foreach ( (array) $products as $pid ) {
                $inline = (array) get_post_meta( (int) $pid, '_reeid_wc_inline_langs', true );
                foreach ( $inline as $code ) {
                    $code = sanitize_key( strtolower( trim( (string) $code ) ) );
                    if ( $code !== '' ) {
                        $langs[ $code ] = true;
                    }
                }
            }

            // Determine Woo base slug
            $base = 'cart';
            if ( function_exists( 'is_checkout' ) && is_checkout() ) {
                $base = 'checkout';
            } elseif ( function_exists( 'is_account_page' ) && is_account_page() ) {
                $base = 'my-account';
            }

            $items = array();
            foreach ( array_keys( $langs ) as $code ) {
                $items[] = array(
                    'code' => $code,
                    'url'  => ( $code === $default )
                        ? home_url( "/{$base}/" )
                        : home_url( "/{$code}/{$base}/" ),
                );
            }

            return reeid_switcher_render_html( $items, $current );
        }

        /*======================================================================
          2) PRODUCT INLINE MODE
        ======================================================================*/
        $post_id = (int) get_queried_object_id();

        if ( $post_id && get_post_type( $post_id ) === 'product' ) {

    $post  = get_post( $post_id );
    $items = function_exists( 'reeid_switcher_collect_product_inline_items' )
        ? reeid_switcher_collect_product_inline_items( $post, $default )
        : array();

    $current = function_exists( 'reeid_current_lang_for_product' )
        ? reeid_current_lang_for_product( $default )
        : $default;

    if ( ! empty( $items ) ) {
        return reeid_switcher_render_html( $items, $current );
    }

    /*
     * Woo inline products must never fall through to generic page mode.
     * Generic mode can read stale _reeid_langs / _reeid_translation_map data
     * from older Pro/Free mixed usage and create broken product switcher links.
     */
    return '';
}
        /*======================================================================
          3) GENERIC PAGE MODE
        ======================================================================*/
        if ( ! function_exists( 'reeid_switcher_collect_generic_items' ) ) {
            return '';
        }

        $items     = reeid_switcher_collect_generic_items( $post, $default, $front );
        $curr_meta = get_post_meta( (int) $post->ID, '_reeid_translation_lang', true );
        $current   = sanitize_key( strtolower( (string) ( $curr_meta ?: $default ) ) );

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

        return reeid_switcher_render_html( $items, $current );
    }
}


/*==============================================================================
  Shared switcher HTML renderer
==============================================================================*/
if ( ! function_exists( 'reeid_switcher_render_html' ) ) {
    function reeid_switcher_render_html( array $items, string $current ) {


        $langs = function_exists( 'reeid_get_supported_languages' )
            ? (array) reeid_get_supported_languages()
            : array();

        $flags = function_exists( 'reeid_get_language_flags' )
            ? (array) reeid_get_language_flags()
            : array();
            $style = get_option( 'reeid_switcher_style', 'default' );
$style = preg_replace( '/[^a-z0-9_-]/i', '', $style );


        $html  = '<div id="reeid-switcher-container" class="reeid-dropdown ' . esc_attr( 'reeid-style-' . $style ) . '">';
$html .= '<button type="button" class="reeid-dropdown__btn">';

if ( ! empty( $flags[ $current ] ) ) {
	$html .= '<img class="reeid-flag-img" src="' . esc_url( plugins_url( 'assets/flags/' . $flags[ $current ] . '.svg', __FILE__ ) ) . '" alt="">';
}

$html .= '<span class="reeid-dropdown__btn-label">' . esc_html( $langs[ $current ] ?? strtoupper( $current ) ) . '</span>';
$html .= '<span class="reeid-dropdown__btn-arrow">▾</span>';
$html .= '</button>';
$html .= '<ul class="reeid-dropdown__menu">';

foreach ( $items as $item ) {
	$html .= '<li class="reeid-dropdown__item">';
	$html .= '<a class="reeid-dropdown__link" href="' . esc_url( $item['url'] ) . '">';

	if ( ! empty( $flags[ $item['code'] ] ) ) {
		$html .= '<img class="reeid-flag-img" src="' . esc_url( plugins_url( 'assets/flags/' . $flags[ $item['code'] ] . '.svg', __FILE__ ) ) . '" alt="">';
	}

	$html .= '<span class="reeid-dropdown__label">' . esc_html( $langs[ $item['code'] ] ?? strtoupper( $item['code'] ) ) . '</span>';
	$html .= '</a>';
	$html .= '</li>';
}

$html .= '</ul>';
$html .= '</div>';

return $html;
    }
}


/*==============================================================================
  SECTION 13 : REEID Switcher — HEADER / MENU HARD-OFF (CONTROLLED)
  - Disables ONLY header/menu injections
  - DOES NOT kill the shortcode
  - DOES NOT affect WooCommerce fallback (Section 14)
  - WP.org safe
==============================================================================*/

if ( ! function_exists( 'reeid_s289_log' ) ) {
    function reeid_s289_log( $label, $data = null ) {
        if ( function_exists( 'reeid_debug_log' ) ) {
            reeid_debug_log( 'S13 ' . $label, $data );
        }
    }
}

/**
 * 1) Remove REEID switcher menu items (header/menu only)
 */
add_filter(
    'wp_nav_menu_items',
    function ( $items ) {



        if ( strpos( $items, 'menu-item-reeid-switcher' ) === false ) {
            return $items;
        }

        $clean = preg_replace(
            '#<li[^>]*\bmenu-item-reeid-switcher\b[^>]*>.*?</li>#si',
            '',
            $items
        );

        if ( $clean !== null ) {
            reeid_s289_log( 'MENU_SWITCHER_REMOVED', true );
            return $clean;
        }

        return $items;
    },
    5
);

/**
 * 2) Optional CSS guard — HEADER ONLY
 * (Does NOT hide WooCommerce fallback container)
 */
add_action(
    'wp_enqueue_scripts',
    function () {


        $css = '
            .menu-item-reeid-switcher,
            .reeid-lang-switcher-header {
                display: none !important;
            }
        ';

        $handle = wp_style_is( 'wp-block-library', 'enqueued' ) ? 'wp-block-library' : '';

        if ( '' === $handle ) {
            wp_register_style( 'reeid-switcher-header-off', false, array(), REEID_TRANSLATE_VERSION );
            wp_enqueue_style( 'reeid-switcher-header-off' );
            $handle = 'reeid-switcher-header-off';
        }

        wp_add_inline_style( $handle, $css );
    },
    99
);



/*==============================================================================
  SECTION 14 : UTF-8 SLUG ROUTER
  - WP.org–safe
  - Early, guarded, no fatal overrides
==============================================================================*/

if ( ! function_exists( 'reeid_utf8_slug_router' ) ) {

    function reeid_utf8_slug_router_DISABLED() {

    if ( is_admin() || is_feed() || is_robots() ) {
        return;
    }

    $request_uri_raw = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );

    if ( ! is_string( $request_uri_raw ) || '' === $request_uri_raw ) {
        return;
    }

    $request_uri = sanitize_text_field(
        wp_unslash( $request_uri_raw )
    );

    $path = wp_parse_url( $request_uri, PHP_URL_PATH );

    if ( ! is_string( $path ) || $path === '' ) {
        return;
    }

    $path = rawurldecode( $path );
    $path = trim( $path, '/' );

    if ( ! preg_match( '#^([a-z]{2})/(.+)$#u', $path, $m ) ) {
        return;
    }

    $slug = sanitize_title_for_query( $m[2] );

    $q = new WP_Query(
        array(
            'name'           => $slug,
            'post_type'      => 'any',
            'posts_per_page' => 1,
            'no_found_rows'  => true,
        )
    );

    if ( $q->have_posts() ) {
        global $wp_query;
        $wp_query = $q;
        status_header( 200 );
    }
}

}



/* ---------- OpenAI translator (WP.org compliant transport) ---------- */

if ( ! function_exists( 'reeid_translate_html_with_openai' ) ) {

    /**
     * Prompt-aware short/medium text translator.
     *
     * @param string $text
     * @param string $source_lang
     * @param string $target_lang
     * @param string $editor
     * @param string $tone
     * @param string $prompt
     * @return string
     */
    function reeid_translate_html_with_openai(
        string $text,
        string $source_lang,
        string $target_lang,
        string $editor,
        string $tone = 'Neutral',
        string $prompt = ''
    ): string {

        $api_key = (string) get_option( 'reeid_openai_api_key', '' );

        if ( $text === '' || $source_lang === $target_lang || $api_key === '' ) {
            return $text;
        }


        /*
         * Attribute-specific instruction (scoped, safe)
         */
        if ( $editor === 'woocommerce_attribute' ) {
            $attr_prompt =
                'This text is a WooCommerce product attribute value. '
              . 'Translate it literally and precisely. '
              . 'Do NOT summarize, generalize, or invent. '
              . 'Preserve materials, units, numbers, proper nouns, and specificity. '
              . 'Return ONLY the translated value. '
              . 'If translation is not possible, return the source text unchanged.';
            $prompt = trim( $prompt . ' ' . $attr_prompt );
        }

/*
 * Build final system prompt
 *
 * IMPORTANT:
 * - The FULL combined prompt (global + post + UI) is already built upstream
 *   and passed in $prompt.
 * - DO NOT call reeid_get_combined_prompt() here again.
 * - Translator must CONSUME the prompt as-is.
 */

$base_system = sprintf(
    'You are a strict translation engine. Translate the user content from %1$s to %2$s. Return ONLY the translated content. Do not answer questions. Do not explain. Do not ask for clarification. Do not rewrite as marketing copy unless the source already is marketing copy. Preserve HTML tags, attributes, shortcodes, URLs, numbers, formatting, and structure. If the input is a title, return only the translated title. If the input is a short phrase, return only the translated phrase. If translation is not possible, return the source text unchanged.',
    (string) $source_lang,
    (string) $target_lang
);

$system = is_string( $prompt ) && trim( $prompt ) !== ''
    ? trim( $base_system . "\n\nAdditional instructions:\n" . trim( $prompt ) )
    : $base_system;


        

        $payload = [
            'model'       => 'gpt-5.4-mini',
            'temperature' => 0,
            'messages'    => [
                [ 'role' => 'system', 'content' => $system ],
                [ 'role' => 'user',   'content' => (string) $text ],
            ],
            
        ];
       

        $resp = wp_remote_post(
            'https://api.openai.com/v1/chat/completions',
            [
                'timeout' => 45,
                'headers' => [
                    'Content-Type'  => 'application/json; charset=utf-8',
                    'Authorization' => 'Bearer ' . $api_key,
                ],
                'body' => wp_json_encode( $payload, JSON_UNESCAPED_UNICODE ),
            ]
        );

        if ( is_wp_error( $resp ) ) {
            return $text;
        }

        $json = json_decode( (string) wp_remote_retrieve_body( $resp ), true );

        $out = isset( $json['choices'][0]['message']['content'] )
            ? trim( (string) $json['choices'][0]['message']['content'] )
            : '';

        if ( $out === '' || $out === $text ) {
            return $text;
        }

       // Strip code fences safely.
$out = preg_replace( '/^```[a-z0-9_-]*\s*/i', '', $out );
$out = preg_replace( '/\s*```$/', '', $out );
$out = str_replace( '<\/', '</', trim( (string) $out ) );

/*
 * Safety guard:
 * If the model responds like a chatbot/helper instead of translating,
 * never save that response into product/page translation metadata.
 */
if (
    preg_match(
        '/\b(could you clarify|do you mean|for example|i can help|if you want|here(?:’|\'| i)s a polished|what would you like)\b/i',
        $out
    )
) {
    return $text;
}

return $out;
    }
}

 


/*==============================================================================
  SECTION 16: REST JSON HEADERS GUARD
==============================================================================*/

add_filter(
    'rest_pre_serve_request',
    function ( $served, $result ) {



        if ( ! headers_sent() ) {
            header(
                'Content-Type: application/json; charset=' . esc_attr( get_option( 'blog_charset' ) )
            );
        }

        return $served;
    },
    9999,
    2
);



/*==============================================================================
  SECTION 17: AJAX JSON GUARD (REEID only)
==============================================================================*/

add_action(
    'init',
    function () {

        if ( ! wp_doing_ajax() ) {
            return;
        }

        $raw_action = filter_input( INPUT_POST, 'action' );
        if ( ! $raw_action ) {
            $raw_action = filter_input( INPUT_GET, 'action' );
        }

        $action = sanitize_key( (string) $raw_action );

        // Only guard REEID AJAX
        if ( ! preg_match( '/^reeid[_-]/', $action ) ) {
            return;
        }

        /* ---------- Soft nonce validation ---------- */

        $nonce_sources = [
            [ 'POST', 'nonce' ],
            [ 'POST', 'security' ],
            [ 'POST', '_ajax_nonce' ],
            [ 'POST', '_wpnonce' ],
            [ 'GET',  'nonce' ],
            [ 'GET',  'security' ],
            [ 'GET',  '_ajax_nonce' ],
            [ 'GET',  '_wpnonce' ],
        ];

        $nonce_seen = false;
        $nonce_ok   = false;

        foreach ( $nonce_sources as $src ) {
            [ $method, $key ] = $src;

            $val = filter_input(
                $method === 'POST' ? INPUT_POST : INPUT_GET,
                $key
            );

            if ( $val ) {
                $nonce_seen = true;
                $v = sanitize_text_field( wp_unslash( $val ) );

                if (
                    wp_verify_nonce( $v, 'reeid_translate_nonce_action' ) ||
                    wp_verify_nonce( $v, $action )
                ) {
                    $nonce_ok = true;
                }
                break;
            }
        }

        if ( $nonce_seen && ! $nonce_ok ) {

            if ( ! headers_sent() ) {
                status_header( 403 );
                header(
                    'Content-Type: application/json; charset=' . esc_attr( get_option( 'blog_charset' ) )
                );
            }

            echo wp_json_encode(
                [
                    'ok'    => false,
                    'error' => 'invalid_nonce',
                ]
            );
            exit;
        }

        /* ---------- REEID AJAX JSON headers guard ---------- */

add_action(
    'send_headers',
    function () {
        if ( ! headers_sent() ) {
            header(
                'Content-Type: application/json; charset=' . esc_attr( get_option( 'blog_charset' ) )
            );
            header( 'X-Content-Type-Options: nosniff' );
            nocache_headers();
        }
    },
    0
);
    }
);



/*==============================================================================
  SECTION 18: LANGUAGE COOKIE FORCE
==============================================================================*/

add_action(
    'template_redirect',
    function () {

        if ( empty( $_GET['reeid_force_lang'] ) || empty( $_GET['_wpnonce'] ) ) {
            return;
        }

        $nonce = sanitize_text_field(
            wp_unslash( $_GET['_wpnonce'] )
        );

        if ( ! wp_verify_nonce( $nonce, 'reeid_force_lang' ) ) {
            return;
        }

        $lang = sanitize_text_field(
            wp_unslash( $_GET['reeid_force_lang'] )
        );

        $lang = strtolower( substr( $lang, 0, 10 ) );

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

        $domain = ( defined( 'COOKIE_DOMAIN' ) && COOKIE_DOMAIN ) ? COOKIE_DOMAIN : '';

        foreach ( array( 'site_lang', 'reeid_lang' ) as $cookie ) {

            setcookie(
                $cookie,
                $lang,
                array(
                    'expires'  => time() + DAY_IN_SECONDS,
                    'path'     => '/',
                    'domain'   => $domain,
                    'secure'   => is_ssl(),
                    'httponly' => true,
                    'samesite' => 'Lax',
                )
            );

            $_COOKIE[ $cookie ] = $lang;
        }
    },
    1
);




/*==============================================================================
  SECTION 19: FRONTEND SWITCHER ASSET ENSURE / DEFAULTS
==============================================================================*/

add_action(
    'wp_enqueue_scripts',
    function () {
        if ( function_exists( 'reeid_enqueue_switcher_assets' ) ) {
            reeid_enqueue_switcher_assets();
        }
    },
    20
);


add_action(
    'init',
    function () {

        add_filter(
            'shortcode_atts_reeid_language_switcher',
            function ( $out, $pairs, $atts ) {

                if ( empty( $atts['style'] ) ) {
                    $style = get_option( 'reeid_switcher_style', 'default' );

                  
                    $out['style'] = $style;
                }

                if ( empty( $atts['theme'] ) ) {
                    $out['theme'] = get_option( 'reeid_switcher_theme', 'auto' );
                }

                return $out;
            },
            10,
            3
        );
    },
    9
);



/*==============================================================================
  SECTION 20: SWITCHER OUTPUT 
==============================================================================*/

add_action(
    'init',
    function () {

        add_filter(
            'do_shortcode_tag',
            function ( $output, $tag, $attr ) {

                if ( 'reeid_language_switcher' !== $tag || ! $output ) {
                    return $output;
                }

                $style = ! empty( $attr['style'] )
                    ? $attr['style']
: get_option( 'reeid_switcher_style', 'default' );

                if ( 'default' === $style ) {
$style = get_option( 'reeid_switcher_style', 'default' );
                }

                $theme = ! empty( $attr['theme'] )
                    ? $attr['theme']
                    : get_option( 'reeid_switcher_theme', 'auto' );

$style_class = 'reeid-style-' . preg_replace( '/[^a-z0-9_-]/i', '', $style );


                $theme_class = $theme
                    ? 'reeid-theme-' . preg_replace( '/[^a-z0-9_-]/i', '', $theme )
                    : '';
                    

                return preg_replace_callback(
                    '#<([a-z0-9]+)([^>]*)id=("|\')reeid-switcher-container\\3([^>]*)>#i',
                    function ( $m ) use ( $style_class, $theme, $theme_class ) {

                        $tag_name = $m[1];
                        $attr_str = $m[2] . $m[4];

                        if ( preg_match( '/class=("|\')(.*?)\\1/i', $attr_str, $cm ) ) {
                            $classes = $cm[2];

                            if ( stripos( $classes, $style_class ) === false ) {
                                $classes .= ' ' . $style_class;
                            }
                            if ( $theme_class && stripos( $classes, 'reeid-theme-' ) === false ) {
                                $classes .= ' ' . $theme_class;
                            }

                            $attr_str = preg_replace(
                                '/class=("|\')(.*?)\\1/i',
                                'class="' . esc_attr( trim( $classes ) ) . '"',
                                $attr_str,
                                1
                            );
                        } else {
                            $attr_str .= ' class="' . esc_attr(
                                trim( $style_class . ( $theme_class ? ' ' . $theme_class : '' ) )
                            ) . '" ';
                        }

                        if ( $theme && stripos( $attr_str, 'data-theme=' ) === false ) {
                            $attr_str .= ' data-theme="' . esc_attr( $theme ) . '"';
                        }

                        return '<' . $tag_name . $attr_str . '>';
                    },
                    $output,
                    1
                );
            },
            10,
            3
        );
    },
    10
);



/*==============================================================================
  SECTION 21: WOO PRODUCT SLUG RESOLVER (INLINE TRANSLATIONS)
  Resolves /{lang}/product/{translated-slug}/ by:
  - Getting candidate product IDs that HAVE _reeid_wc_tr_{lang} meta (cached)
  - Verifying slug inside the stored meta array in PHP (serialized-safe)
  - Forcing main query to load product by ID only
==============================================================================*/

add_action( 'pre_get_posts', function ( $q ) {

    if ( is_admin() || ! $q->is_main_query() ) {
        return;
    }

    if (
        empty( $q->query_vars['post_type'] ) ||
        $q->query_vars['post_type'] !== 'product'
    ) {
        return;
    }

    $req = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );
    if ( ! is_string( $req ) || $req === '' ) {
        return;
    }

    $req  = wp_unslash( $req );
    $path = wp_parse_url( $req, PHP_URL_PATH );

    if ( ! is_string( $path ) || $path === '' ) {
        return;
    }

    if ( ! preg_match(
        '#^/([a-z]{2}(?:-[a-z0-9]{2})?)/product/([^/]+)/?$#u',
        $path,
        $m
    ) ) {
        return;
    }

    $lang = sanitize_key( strtolower( (string) $m[1] ) );
    $slug = rawurldecode( (string) $m[2] );

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

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

    global $wpdb;

    $meta_key  = '_reeid_wc_tr_' . $lang;
    $cache_key = 'reeid_wc_tr_ids_' . md5( $meta_key );

    $ids = wp_cache_get( $cache_key, 'reeid' );

    if ( false === $ids ) {

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
        $ids = $wpdb->get_col(
            $wpdb->prepare(
                "
                SELECT DISTINCT pm.post_id
                FROM {$wpdb->postmeta} pm
                JOIN {$wpdb->posts} p ON p.ID = pm.post_id
                WHERE pm.meta_key = %s
                  AND p.post_type = 'product'
                  AND p.post_status IN ('publish','private','draft')
                ",
                $meta_key
            )
        );

        if ( ! is_array( $ids ) ) {
            $ids = [];
        }

        $ids = array_values( array_unique( array_map( 'intval', $ids ) ) );

        // Cache for 10 minutes (safe, read-only list)
        wp_cache_set( $cache_key, $ids, 'reeid', 10 * MINUTE_IN_SECONDS );
    }

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

    // Prefetch postmeta for fewer queries
    if ( function_exists( 'update_meta_cache' ) ) {
        update_meta_cache( 'post', $ids );
    }

    foreach ( $ids as $pid ) {

        $meta = get_post_meta( (int) $pid, $meta_key, true );

        if ( ! is_array( $meta ) || empty( $meta['slug'] ) || ! is_string( $meta['slug'] ) ) {
            continue;
        }

        $stored = sanitize_title_for_query( rawurldecode( (string) $meta['slug'] ) );

        if ( $stored !== '' && $stored === $want ) {

            // Force WP to load product by ID only
            $q->set( 'p', (int) $pid );
            $q->set( 'name', '' );
            $q->set( 'pagename', false );
            $q->set( 'post_type', 'product' );

            return;
        }
    }

}, 1 );



/*==============================================================================
  SECTION 22: DISABLE INLINE → post_content SYNC (SAFETY)
==============================================================================*/

add_action(
    'plugins_loaded',
    function () {

        if ( function_exists( 'reeid_inline_sync_handle_meta' ) ) {
            remove_action(
                'added_post_meta',
                'reeid_inline_sync_handle_meta',
                10
            );
            remove_action(
                'updated_post_meta',
                'reeid_inline_sync_handle_meta',
                10
            );
        }

        if ( function_exists( 'reeid_inline_sync_save_post_backstop' ) ) {
            remove_action(
                'save_post_product',
                'reeid_inline_sync_save_post_backstop',
                20
            );
        }
    }
);



/*==============================================================================
  SECTION 23: VALIDATE-KEY JS LOADER (ADMIN)
==============================================================================*/

add_action(
    'init',
    function () {
        add_action(
            'admin_enqueue_scripts',
            'reeid_admin_validate_key_script',
            99
        );
    }
);



/*==============================================================================
  FINAL INCLUDES
==============================================================================*/

require_once __DIR__ . '/includes/rt-native-slugs.php';
// require_once __DIR__ . '/includes/rt-gb-guard.php';
require_once __DIR__ . '/includes/rt-gb-safety-pack.php';

add_action(
    'plugins_loaded',
    function () {

        $dir = __DIR__ . '/includes/bootstrap';

        if ( is_dir( $dir ) ) {
            foreach ( glob( $dir . '/*.php' ) as $f ) {
                if ( is_file( $f ) ) {
                    require_once $f;
                }
            }
        }
    },
    0
);

require_once __DIR__ . '/includes/rt-clean-dup-bracketed.php';
require_once __DIR__ . '/includes/rt-strip-ascii-paragraphs.php';









/* ============================================================
   SECTION 24 : ACTIVE AJAX HANDLER — VALIDATE OPENAI API KEY
   ============================================================ */
if ( ! function_exists( 'reeid_validate_openai_key' ) ) {

    add_action( 'wp_ajax_reeid_validate_openai_key', 'reeid_validate_openai_key' );

    function reeid_validate_openai_key() {

        /* ---------- Tolerant nonce check (fix: accept _wpnonce/_ajax_nonce too) ---------- */
        $nonce = '';

        $nonce_raw = filter_input( INPUT_POST, 'nonce', FILTER_UNSAFE_RAW );
        if ( ! is_string( $nonce_raw ) || '' === $nonce_raw ) {
            $nonce_raw = filter_input( INPUT_GET, 'nonce', FILTER_UNSAFE_RAW );
        }

        $wpnonce_raw = filter_input( INPUT_POST, '_wpnonce', FILTER_UNSAFE_RAW );
        if ( ! is_string( $wpnonce_raw ) || '' === $wpnonce_raw ) {
            $wpnonce_raw = filter_input( INPUT_GET, '_wpnonce', FILTER_UNSAFE_RAW );
        }

        $ajax_nonce_raw = filter_input( INPUT_POST, '_ajax_nonce', FILTER_UNSAFE_RAW );
        if ( ! is_string( $ajax_nonce_raw ) || '' === $ajax_nonce_raw ) {
            $ajax_nonce_raw = filter_input( INPUT_GET, '_ajax_nonce', FILTER_UNSAFE_RAW );
        }

        if ( is_string( $nonce_raw ) && '' !== $nonce_raw ) {
            $nonce = sanitize_text_field( wp_unslash( $nonce_raw ) );
        } elseif ( is_string( $wpnonce_raw ) && '' !== $wpnonce_raw ) {
            $nonce = sanitize_text_field( wp_unslash( $wpnonce_raw ) );
        } elseif ( is_string( $ajax_nonce_raw ) && '' !== $ajax_nonce_raw ) {
            $nonce = sanitize_text_field( wp_unslash( $ajax_nonce_raw ) );
        }

        $ok = false;
        if ( $nonce !== '' ) {
            if ( wp_verify_nonce( $nonce, 'reeid_translate_nonce' ) ) {
                $ok = true;
            } elseif ( wp_verify_nonce( $nonce, 'reeid_translate_nonce_action' ) ) {
                $ok = true;
            } elseif ( wp_verify_nonce( $nonce, 'reeid_api_key_action' ) ) {
                $ok = true;
            }
        }

        if ( ! $ok ) {
            wp_send_json_error(
                array(
                    'error' => 'bad_nonce',
                    'msg'   => __( 'Invalid or missing nonce. Please reload editor.', 'reeid-translate' ),
                )
            );
        }
        /* ---------- End nonce ---------- */

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error(
                array( 'message' => __( 'Permission denied.', 'reeid-translate' ) ),
                403
            );
        }


        // Source of truth: validate the STORED key
$key = get_option( 'reeid_openai_api_key', '' );
$key = is_string( $key ) ? preg_replace('/\s+/', '', $key) : '';


        if ( $key === '' ) {
            wp_send_json_error(
                array(
                    'message' => __( 'API key is empty.', 'reeid-translate' ),
                ),
                400
            );
        }

       /* ---------- OpenAI auth validation (prompt-free) ---------- */
$response = wp_remote_get(
    'https://api.openai.com/v1/models',
    array(
        'timeout' => 15,
        'headers' => array(
            'Authorization' => 'Bearer ' . $key,
            'Content-Type'  => 'application/json',
        ),
    )
);



        

        if ( is_wp_error( $response ) ) {
            update_option( 'reeid_openai_status', 'invalid', false );

            wp_send_json_error(
                array(
                    'message' => sprintf(
                        /* translators: %s is the WP HTTP error message */
                        __( 'Connection failed: %s', 'reeid-translate' ),
                        $response->get_error_message()
                    ),
                )
            );
        }

        $code = (int) wp_remote_retrieve_response_code( $response );

        if ( $code === 200 ) {
            update_option( 'reeid_openai_status', 'valid', false );

            wp_send_json_success(
                array(
                    'message' => __( '✅ Valid API Key', 'reeid-translate' ),
                )
            );
        }

        update_option( 'reeid_openai_status', 'invalid', false );

        wp_send_json_error(
            array(
                'message' => sprintf(
                    /* translators: %d is the HTTP status code */
                    __( 'OpenAI API error (HTTP %d)', 'reeid-translate' ),
                    $code
                ),
                'code'    => $code,
            )
        );
    }
}


/**
 * Safe wrapper: sanitize & harden translated SEO title before writing to other plugins
 * Usage: reeid_safe_write_title_all_plugins( $post_id, $title_string );
 */
if ( ! function_exists( 'reeid_safe_write_title_all_plugins' ) ) {

    function reeid_safe_write_title_all_plugins( $post_id, $title ) {

        $post_id = (int) $post_id;
        if ( $post_id <= 0 ) {
            return;
        }

        if ( ! is_scalar( $title ) ) {
            return;
        }

        $title_trim = trim( (string) $title );
        if ( $title_trim === '' ) {
            return;
        }

        /* ---------- Harden invalid language markers ---------- */
        if ( function_exists( 'reeid_harden_invalid_lang_pair' ) ) {
            $maybe = reeid_harden_invalid_lang_pair( $title_trim );
            if ( is_string( $maybe ) ) {
                $title_trim = $maybe;
            }
        }

        if (
            $title_trim === '' ||
            stripos( $title_trim, 'INVALID LANGUAGE PAIR' ) !== false
        ) {
            return;
        }

        /* ---------- Decode unicode escapes if helper exists ---------- */
        if ( function_exists( 'reeid_decode_unicode_escapes' ) ) {
            $title_trim = reeid_decode_unicode_escapes( $title_trim );
        }

        /* ---------- Final sanitize ---------- */
        if ( function_exists( 'sanitize_text_field' ) ) {
            $title_trim = sanitize_text_field( $title_trim );
        } else {
            $title_trim = trim(
                preg_replace( '/\s+/', ' ', wp_strip_all_tags( $title_trim ) )
            );
        }

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

        /* ---------- Write to SEO plugins ---------- */
        if ( function_exists( 'reeid_write_title_all_plugins' ) ) {
            reeid_write_title_all_plugins( $post_id, $title_trim );
        }
    }
}
/**
 * Non-AJAX fallback: delete ALL translations for a product, then redirect back.
 * URL endpoint: wp-admin/admin-post.php?action=reeid_wc_delete_all_translations
 */
add_action( 'admin_post_reeid_wc_delete_all_translations', function () {

    /* ---------- Auth ---------- */
    if ( ! is_user_logged_in() ) {
        wp_die( esc_html__( 'You must be logged in.', 'reeid-translate' ), 403 );
    }

    /* ---------- Nonce (must be first POST check) ---------- */
    check_admin_referer( 'reeid_wc_delete_all' );

    /* ---------- Product ID ---------- */
    $product_id = isset( $_POST['product_id'] )
        ? absint( wp_unslash( $_POST['product_id'] ) )
        : 0;

    if ( ! $product_id ) {
        wp_die( esc_html__( 'Missing product.', 'reeid-translate' ), 400 );
    }

    if ( ! current_user_can( 'edit_post', $product_id ) ) {
        wp_die( esc_html__( 'Insufficient permissions.', 'reeid-translate' ), 403 );
    }

    /* ---------- Validate WC product ---------- */
    if ( function_exists( 'wc_get_product' ) && ! wc_get_product( $product_id ) ) {
        wp_die( esc_html__( 'Invalid product.', 'reeid-translate' ), 404 );
    }

    /* ---------- Remove translation packets ---------- */
    $meta    = get_post_meta( $product_id );
    $removed = array();

    foreach ( array_keys( $meta ) as $k ) {
        if ( preg_match( '/^_reeid_wc_tr_([a-zA-Z-]+)$/', $k, $m ) ) {
            delete_post_meta( $product_id, $k );
            $removed[] = $m[1];
        }
        if ( preg_match( '/^_reeid_wc_inline_([a-zA-Z-]+)$/', $k, $m ) ) {
            delete_post_meta( $product_id, $k );
            $removed[] = $m[1];
        }
    }
$removed = array_values( array_unique( $removed ) );

/*
 * Woo-only registry cleanup.
 * Do not touch _reeid_langs, _reeid_translation_map, normal translated posts,
 * or page/post translation metadata.
 */
delete_post_meta( $product_id, '_reeid_wc_inline_langs' );

/* ---------- Clear caches ---------- */
    if ( function_exists( 'wc_delete_product_transients' ) ) {
        wc_delete_product_transients( $product_id );
    }
    clean_post_cache( $product_id );

    do_action( 'reeid_wc_translations_deleted_all', $product_id, $removed );

    /* ---------- Redirect back ---------- */
    $back = admin_url( 'post.php?post=' . $product_id . '&action=edit' );
    $back = add_query_arg(
        array(
            'reeid_del_all' => '1',
            'deleted_langs' => implode( ',', $removed ),
        ),
        $back
    );

    wp_safe_redirect( $back );
    exit;
} );

/**
 * Swap long product description with REEID packet content on the frontend
 * ONLY for non-source languages. Source language remains untouched.
 */
add_filter( 'the_content', function ( $content ) {

    // Frontend only
    if ( is_admin() || wp_doing_ajax() || wp_is_json_request() ) {
        return $content;
    }

    // Single product only
    if ( ! is_singular( 'product' ) ) {
        return $content;
    }

    global $post;
    if ( ! $post || $post->post_type !== 'product' ) {
        return $content;
    }

    /* ---------- Resolve source language ---------- */
    $default = function_exists( 'reeid_s269_default_lang' )
        ? strtolower( (string) reeid_s269_default_lang() )
        : strtolower( (string) get_option( 'reeid_translation_source_lang', 'en' ) );

    /* ---------- Resolve current language ---------- */
    $lang = '';

    // 1) Explicit override (?reeid_force_lang=xx&_wpnonce=...)
    if (
        isset( $_GET['reeid_force_lang'], $_GET['_wpnonce'] ) &&
        wp_verify_nonce(
            sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ),
            'reeid_force_lang'
        )
    ) {
        $lang = sanitize_text_field( wp_unslash( $_GET['reeid_force_lang'] ) );
    }

    // 2) Cookie
    if ( $lang === '' && isset( $_COOKIE['site_lang'] ) ) {
        $lang = sanitize_text_field( wp_unslash( $_COOKIE['site_lang'] ) );
    }

    // 3) URL prefix
    $request_uri_raw = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );

    if ( '' === $lang && is_string( $request_uri_raw ) && '' !== $request_uri_raw ) {

        $request_uri = sanitize_text_field(
            wp_unslash( $request_uri_raw )
        );

        $parts = wp_parse_url( $request_uri );
        $path  = isset( $parts['path'] )
            ? trim( (string) $parts['path'], '/' )
            : '';

        if ( $path !== '' ) {
            $segments = explode( '/', $path );
            $seg      = strtolower(
                str_replace( '_', '-', (string) ( $segments[0] ?? '' ) )
            );

            if ( preg_match( '/^[a-z]{2}(-[a-z]{2})?$/', $seg ) ) {

                $supported = function_exists( 'reeid_s269_supported_langs' )
                    ? array_keys( (array) reeid_s269_supported_langs() )
                    : array();

                $supported = array_map(
                    static function ( $c ) {
                        return strtolower( str_replace( '_', '-', (string) $c ) );
                    },
                    $supported
                );

                if ( empty( $supported ) ) {
                    $lang = $seg;
                } elseif ( in_array( $seg, $supported, true ) ) {
                    $lang = $seg;
                } else {
                    foreach ( $supported as $code ) {
                        if (
                            strpos( $code, $seg . '-' ) === 0 ||
                            $seg === substr( $code, 0, 2 )
                        ) {
                            $lang = $code;
                            break;
                        }
                    }
                }
            }
        }
    }

    $lang = strtolower( (string) $lang );

    // Do not override source language
    if ( $lang === '' || $lang === $default ) {
        return $content;
    }

    /* ---------- Load REEID packet ---------- */
    $packet = get_post_meta(
        (int) $post->ID,
        '_reeid_wc_tr_' . sanitize_key( $lang ),
        true
    );

    if ( is_array( $packet ) && ! empty( $packet['content'] ) ) {
        return wp_kses_post( (string) $packet['content'] );
    }

    return $content;

}, 5 );


/**
 * WooCommerce tabs override:
 *  - Description tab: ONLY long description (translation-aware)
 *  - Additional information tab: ONLY attributes table
 *
 * This prevents attribute leakage into the Description tab.
 */
add_filter( 'woocommerce_product_tabs', function ( $tabs ) {

    // Force Description tab callback
    if ( isset( $tabs['description'] ) ) {
        $tabs['description']['callback'] = 'reeid_wc_tab_description';
    }

    // Force Additional Information tab callback
    if ( isset( $tabs['additional_information'] ) ) {
        $tabs['additional_information']['callback'] = 'reeid_wc_tab_additional_information';
    }

    return $tabs;
}, 50 );


/**
 * Description tab renderer
 * (long description ONLY, translation-aware)
 */
if ( ! function_exists( 'reeid_wc_tab_description' ) ) {
    function reeid_wc_tab_description() {

        global $product;

        if ( ! $product instanceof WC_Product ) {
            the_content();
            return;
        }

        // Use WC API so REEID and WooCommerce filters apply
        $content = $product->get_description();

        // FINAL DEFENSIVE STRIP (should normally be a no-op)
        $content = preg_replace(
            '#<table[^>]*\bclass=["\'][^"\']*(woocommerce-product-attributes|shop_attributes)[^"\']*["\'][^>]*>[\s\S]*?</table>#i',
            '',
            (string) $content
        );

        echo wp_kses_post( $content );
    }
}


/**
 * Additional Information tab renderer
 * (attributes ONLY)
 */
if ( ! function_exists( 'reeid_wc_tab_additional_information' ) ) {
    function reeid_wc_tab_additional_information() {

        global $product;

        if ( ! $product instanceof WC_Product ) {
            wc_get_template( 'single-product/tabs/additional-information.php' );
            return;
        }

        // The ONLY place attributes are rendered
        wc_display_product_attributes( $product );
    }
}
/**
 * Force WooCommerce long description to use REEID packet
 * for non-source languages on the frontend.
 */
add_filter( 'woocommerce_product_get_description', function ( $desc, $product ) {

    $safe_desc = wp_kses_post( (string) $desc );

    if ( is_admin() || wp_doing_ajax() || wp_is_json_request() ) {
        return $safe_desc;
    }

    if ( ! $product instanceof WC_Product ) {
        return $safe_desc;
    }

    $default = function_exists( 'reeid_s269_default_lang' )
        ? strtolower( (string) reeid_s269_default_lang() )
        : strtolower( (string) get_option( 'reeid_translation_source_lang', 'en' ) );

    $lang = '';

    /* --- explicit override (?reeid_force_lang=xx&_wpnonce=...) --- */
    if (
        isset( $_GET['reeid_force_lang'], $_GET['_wpnonce'] ) &&
        wp_verify_nonce(
            sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ),
            'reeid_force_lang'
        )
    ) {
        $lang = sanitize_text_field( wp_unslash( $_GET['reeid_force_lang'] ) );
    }

    /* --- cookie --- */
    if ( $lang === '' && isset( $_COOKIE['site_lang'] ) ) {
        $lang = sanitize_text_field( wp_unslash( $_COOKIE['site_lang'] ) );
    }

    /* --- URL prefix --- */
    $request_uri_raw = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_UNSAFE_RAW );

    if ( '' === $lang && is_string( $request_uri_raw ) && '' !== $request_uri_raw ) {

        $req_uri = sanitize_text_field(
            wp_unslash( $request_uri_raw )
        );

        $parts = wp_parse_url( $req_uri );
        $path  = isset( $parts['path'] ) ? trim( (string) $parts['path'], '/' ) : '';

        $seg = $path !== ''
            ? strtolower( str_replace( '_', '-', explode( '/', $path )[0] ) )
            : '';

        if ( preg_match( '/^[a-z]{2}(-[a-z0-9]{2})?$/i', $seg ) ) {

            $supported = function_exists( 'reeid_s269_supported_langs' )
                ? array_map(
                    static fn ( $c ) => strtolower( str_replace( '_', '-', $c ) ),
                    array_keys( (array) reeid_s269_supported_langs() )
                )
                : array();

            if ( empty( $supported ) || in_array( $seg, $supported, true ) ) {
                $lang = $seg;
            } else {
                foreach ( $supported as $code ) {
                    if ( strpos( $code, $seg . '-' ) === 0 || $seg === substr( $code, 0, 2 ) ) {
                        $lang = $code;
                        break;
                    }
                }
            }
        }
    }

    $lang = strtolower( (string) $lang );

    if ( $lang === '' || $lang === $default ) {
        return $safe_desc;
    }

    $packet = get_post_meta(
        (int) $product->get_id(),
        "_reeid_wc_tr_{$lang}",
        true
    );

    if ( is_array( $packet ) && ! empty( $packet['content'] ) ) {
        return wp_kses_post( (string) $packet['content'] );
    }

    return $safe_desc;

}, 9, 2 );




/* =============================================================================
 * UNIVERSAL FIX: Translate dynamic Woo "Reviews (X)" tab label
 * Uses mapping files: /includes/mappings/woocommerce-<lang>.json
 * =============================================================================*/
add_filter( 'woocommerce_product_tabs', function ( $tabs ) {

    // Safety: Woo only
    if ( ! function_exists( 'wc_get_product' ) ) {
        return $tabs;
    }

    if ( empty( $tabs['reviews']['title'] ) ) {
        return $tabs;
    }

    // 1) Resolve current language
    $lang = function_exists( 'reeid_resolve_lang_from_request' )
        ? reeid_resolve_lang_from_request()
        : '';

    if ( $lang === '' || $lang === 'en' ) {
        return $tabs;
    }

    $lang = strtolower( trim( $lang ) );

    // 2) Locate mapping file
    $map_file = __DIR__ . "/mappings/woocommerce-{$lang}.json";

    if ( ! file_exists( $map_file ) ) {
        $base = substr( $lang, 0, 2 );
        $map_file = __DIR__ . "/mappings/woocommerce-{$base}.json";
    }

    if ( ! file_exists( $map_file ) ) {
        return $tabs;
    }

    // 3) Read mapping file safely
    $json = null;

    if ( function_exists( 'wp_filesystem' ) ) {
        global $wp_filesystem;
        if ( empty( $wp_filesystem ) ) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
            WP_Filesystem();
        }
        if ( $wp_filesystem && $wp_filesystem->exists( $map_file ) ) {
            $json = json_decode( $wp_filesystem->get_contents( $map_file ), true );
        }
    }

    if ( ! is_array( $json ) || empty( $json['Reviews'] ) ) {
        return $tabs;
    }

    $translated = trim( (string) $json['Reviews'] );
    if ( $translated === '' ) {
        return $tabs;
    }

    // 4) Replace trailing "(X)" safely, regardless of original language
    $orig = (string) $tabs['reviews']['title'];

    if ( preg_match( '/\((\d+)\)\s*$/', $orig, $m ) ) {
        $count = (int) $m[1];
        $tabs['reviews']['title'] = $translated . ' (' . $count . ')';
    }

    return $tabs;

}, 50 );


/* =============================================================================
 * STRING NORMALIZER (utility)
 * =============================================================================*/
if ( ! function_exists( 'reeid_normalize_string' ) ) {
    function reeid_normalize_string( $string ) {

        if ( ! is_string( $string ) ) {
            return $string;
        }

        $string = mb_strtolower( $string, 'UTF-8' );
        $string = preg_replace(
            '/[.,:;!?\p{Pd}\p{Ps}\p{Pe}\p{Pf}\p{Pi}"“”«»()\[\]{}]/u',
            '',
            $string
        );
        $string = preg_replace( '/\s+/u', ' ', $string );

        return trim( $string );
    }
}


/* =============================================================================
 * AUTO LICENSE VALIDATION (admin only, once per day)
 * =============================================================================*/


// REEID: register custom query vars used by rewrite rules
add_filter( 'query_vars', function ( $vars ) {
    if ( ! in_array( 'reeid_force_lang', $vars, true ) ) {
        $vars[] = 'reeid_force_lang';
    }
    return $vars;
} );


register_activation_hook( __FILE__, function() {
    flush_rewrite_rules();
});

register_deactivation_hook( __FILE__, function() {
    flush_rewrite_rules();
});


add_filter( 'redirect_canonical', function( $redirect, $requested ) {

    $path = wp_parse_url( $requested, PHP_URL_PATH );

    if ( is_string( $path ) ) {
        if ( preg_match( '#^/[a-z]{2}(?:-[a-z0-9]{2})?/product/#i', $path ) ) {
            return false;
        }
    }

    return $redirect;

}, 9999, 2 );


// phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound