<?php
/**
 * REEID Translate — AJAX Handlers
 *
 */
$reeid_ver = defined( 'REEID_TRANSLATE_VERSION' ) ? REEID_TRANSLATE_VERSION : 'dev';

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

/**
 * REEID: During AJAX translation, temporarily disable Rank Math analytics hooks.
 * Rank Math analytics tables may be missing and break JSON responses.
 */
if ( wp_doing_ajax() ) {
    add_action( 'init', function () {
        if ( class_exists( '\RankMath\Analytics\Watcher' ) ) {
            remove_action(
                'save_post',
                [ \RankMath\Analytics\Watcher::get(), 'update_post_info' ],
                10
            );
        }
    }, 0 );
}

if ( ! function_exists( 'reeid_get_combined_prompt' ) ) {
    function reeid_get_combined_prompt( $post_id = 0, $target_lang = '' ) {

        $target_lang = is_string( $target_lang ) ? trim( $target_lang ) : '';

/* ------------------------------------------------------------------
 * BASE SYSTEM PROMPT (AUTHORITATIVE)
 * ------------------------------------------------------------------ */
$system =
	"You are a professional human translator and editor for multilingual websites.\n\n" .
	"Your task is to translate content from the SOURCE language into the TARGET language with natural, idiomatic, native-level quality.\n\n" .
	"Core rules (must always be followed):\n" .
	"- Translate meaning, not words.\n" .
	"- Preserve intent, tone, and context.\n" .
	"- Preserve HTML structure and tags exactly.\n" .
	"- Translate text nodes only.\n" .
	"- Preserve placeholder markers themselves (e.g. [[PHO:1]], [[PHC:1]], {{price}}, %s, [shortcode], REEID).\n" .
	"- You MUST translate the human-readable text between formatting markers.\n" .
	"- Do NOT treat text between [[PHO:x]] and [[PHC:x]] as protected.\n" .
	"- Do not add explanations, commentary, labels, or assistant text.\n" .
	"- Do not summarize, expand, or invent content.\n" .
	"- Output only the translated content.\n" .
	"- Respond only in the TARGET language.\n\n" .
	"If a sentence cannot or should not be translated, return it unchanged.";
    
        /* ------------------------------------------------------------------
         * LANGUAGE BINDING (minimal, critical)
         * ------------------------------------------------------------------ */
        if ( $target_lang !== '' ) {
            $system .= "\n\nSOURCE language: auto-detected\nTARGET language: {$target_lang}";
        }



        return trim( $system );
    }
}
    


add_action('wp_ajax_reeid_translate_openai', 'reeid_handle_ajax_translation');




if (! function_exists('reeid_maybe_fix_native_slug_after_update')) {
    function reeid_maybe_fix_native_slug_after_update(int $target_id, string $title_for_slug): void
    {
        $saved = get_post($target_id);
        if (! $saved) {
            return;
        }

        $title_has_non_ascii = (bool) preg_match('/[^\x00-\x7F]/u', (string) $title_for_slug);
        $slug_has_non_ascii  = (bool) preg_match('/[^\x00-\x7F]/u', (string) $saved->post_name);

        if ($title_has_non_ascii && ! $slug_has_non_ascii) {
            $native = function_exists('reeid_sanitize_native_slug')
                ? reeid_sanitize_native_slug($title_for_slug)
                : sanitize_title($title_for_slug);

            $unique = wp_unique_post_slug(
                $native,
                $target_id,
                get_post_status($target_id),
                get_post_type($target_id),
                (int) get_post_field('post_parent', $target_id)
            );

            wp_update_post([
                'ID'        => $target_id,
                'post_name' => $unique ?: $native,
            ]);
        }
    }
}


if (! function_exists('reeid_handle_ajax_translation')) {
    function reeid_handle_ajax_translation(){
  
        $REEID_DRY_RUN = defined('REEID_DRY_RUN') && REEID_DRY_RUN;

    
   

// Validate security nonce first
if (
    ! isset( $_POST['reeid_translate_nonce'] ) ||
    ! wp_verify_nonce(
        sanitize_text_field( wp_unslash( $_POST['reeid_translate_nonce'] ) ),
        'reeid_translate_nonce_action'
    )
) {
    wp_send_json_error( array(
        'error'   => 'invalid_nonce',
        'message' => 'Security check failed.',
    ));
}

// Sanitize all incoming POST variables (sanitize at read time)
$post_id = isset( $_POST['post_id'] )
	? absint( wp_unslash( $_POST['post_id'] ) )
	: 0;

$raw_lang = isset( $_POST['lang'] )
	? sanitize_text_field( wp_unslash( $_POST['lang'] ) )
	: '';

$raw_tone = isset( $_POST['tone'] )
	? sanitize_text_field( wp_unslash( $_POST['tone'] ) )
	: '';

$raw_mode = isset( $_POST['reeid_publish_mode'] )
	? sanitize_text_field( wp_unslash( $_POST['reeid_publish_mode'] ) )
	: '';

$target_lang  = $raw_lang;
$tone         = $raw_tone !== '' ? $raw_tone : 'Neutral';
$publish_mode = $raw_mode !== '' ? $raw_mode : 'publish';


// Normalize language format
$target_lang = strtolower( str_replace( '_', '-', $target_lang ) );
$target_lang = preg_replace( '/[^a-z0-9-]/', '', $target_lang );
$prompt = $system_prompt;


        // Language detector helper (uses plugin’s hreflang helper if present)
        $detect_lang = function ($id) {
            if (function_exists('reeid_post_lang_for_hreflang')) {
                return reeid_post_lang_for_hreflang($id);
            }
            $lang = get_post_meta($id, '_reeid_translation_lang', true);
            if (! $lang) $lang = get_option('reeid_translation_source_lang', 'en');
            return $lang ?: 'en';
        };

        if (! $post_id || ! $target_lang) {
            wp_send_json_error(['error' => 'missing_parameters']);
        }

          $post = get_post($post_id);
          if (! $post) {
              wp_send_json_error(['error' => 'post_not_found']);
          }

          if ( ! current_user_can( 'edit_post', $post_id ) ) {
              wp_send_json_error( array(
                  'error'   => 'forbidden',
                  'message' => 'You are not allowed to translate this content.',
              ) );
          }

          $editor = function_exists('reeid_detect_editor_type') ? reeid_detect_editor_type($post_id) : 'classic';
        if (function_exists('reeid_debug_log')) {
            reeid_debug_log('S18 ENTRY', [
                'post_id'     => $post_id,
                'post_type'   => $post->post_type,
                'editor'      => $editor,
                'target_lang' => $target_lang,
                'mode'        => $publish_mode,
            ]);
        }

        $prompt = isset($prompt) ? trim((string)$prompt) : '';
        if ($prompt !== '') {
            $prompt = "CRITICAL INSTRUCTIONS (enforce strictly):\n" . $prompt;
        }
        if (function_exists('reeid_debug_log')) {
            reeid_debug_log('S18 PROMPT (final)', ['len' => strlen($prompt), 'preview' => mb_substr($prompt, 0, 80, 'UTF-8')]);
        }

        /* >>> DEBUG (optional) — confirm prompt reached S18 */
        if (function_exists('reeid_debug_log')) {
            reeid_debug_log('S18 PROMPT RECEIVED', [
                'len'     => is_string($prompt) ? strlen($prompt) : 0,
                'preview' => is_string($prompt) ? mb_substr($prompt, 0, 120) : '',
                'tone'    => $tone,
            ]);
        }
        /* <<< DEBUG */

        if ($prompt === '' && function_exists('reeid_build_prompt')) {
            $source_lang = (function_exists('reeid_post_lang_for_hreflang'))
                ? (string) reeid_post_lang_for_hreflang($post_id)
                : ((string) get_post_meta($post_id, '_reeid_translation_lang', true));

            if ($source_lang === '') {
                $source_lang = (string) get_option('reeid_translation_source_lang', 'en');
                if ($source_lang === '') $source_lang = 'en';
            }

            $prompt = (string) reeid_build_prompt([
                'source_lang' => $source_lang,
                'target_lang' => $target_lang,
                'tone'        => $tone,
                'context'     => 'single_ajax',
                'post_type'   => $post->post_type,
                'editor'      => $editor,
            ]);
        }


       /* ===========================================================
        WooCommerce products — store inline (no new post)
       =========================================================== */
        if ($post->post_type === 'product') {
            if (function_exists('reeid_debug_log')) {
                reeid_debug_log('S18/WC INLINE START', ['post_id' => $post_id, 'lang' => $target_lang]);
            }

            // Resolve cluster root for products (store on source)
            $src_id = (int) get_post_meta($post_id, '_reeid_translation_source', true);
            if (! $src_id) $src_id = $post_id;

            // Build context for translator
            $ctx = [
                'post_id' => $post_id,
                'tone'    => $tone,
                'prompt'  => $prompt,
                'title'   => $post->post_title,
                'slug'    => $post->post_name,
                'excerpt' => $post->post_excerpt,
                'domain'  => 'woocommerce',
                'entity'  => 'product',
            ];

            // Defaults (source as fallback)
            $title   = (string) $post->post_title;
            $content = (string) $post->post_content;  // long description
            $excerpt = (string) $post->post_excerpt;  // short description
            $slug    = (string) $post->post_name;

            $src_lang = (string) get_option('reeid_translation_source_lang', 'en');
            if ($src_lang === '') $src_lang = 'en';

            // === Collect WooCommerce product attributes for translation ===
            $attributes = [];
            $raw_attrs = get_post_meta($post_id, '_product_attributes', true);
            if (is_array($raw_attrs)) {
                foreach ($raw_attrs as $key => $attr) {
                    if (!empty($attr['name']) && !empty($attr['value'])) {
                        $attributes[$attr['name']] = $attr['value'];
                    }
                }
            }

// ======================================================
// REEID: persist translated attributes per language
// ======================================================
if (!empty($attributes) && is_array($attributes)) {

    $meta_key = '_reeid_wc_tr_' . strtolower($target_lang);
    $payload  = get_post_meta($src_id, $meta_key, true);

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

    $payload['attributes'] = [];

    foreach ($attributes as $label => $value) {
        $payload['attributes'][] = [
            'label' => (string) $label,
            'value' => (string) $value,
        ];
    }

    update_post_meta($src_id, $meta_key, $payload);
}
            // Preferred: map translator if available (bypasses extractor entirely)
if (function_exists('reeid_translate_map_via_openai') && empty($attributes)) {
                    $in = [
                    'title'      => $title,
                    'excerpt'    => $excerpt,
                    'content'    => $content,
                    'slug'       => $slug,
                    'attributes' => $attributes, // <-- Now included
                ];
                $out = (array) reeid_translate_map_via_openai($in, $target_lang, $ctx);
                $title   = is_string($out['title']   ?? '') ? $out['title']   : $title;
                $excerpt = is_string($out['excerpt'] ?? '') ? $out['excerpt'] : $excerpt;
                $content = is_string($out['content'] ?? '') ? $out['content'] : $content;
                $slug    = is_string($out['slug']    ?? '') ? $out['slug']    : $slug;

                if (!empty($out['attributes']) && is_array($out['attributes'])) {
                    $attributes = $out['attributes'];
                }

            } elseif (function_exists('reeid_gutenberg_classic_translate_adapter') || function_exists('reeid_translate_html_with_openai')) {

                // Woo inline product long description: use Woo-specific full HTML translation.
// Do not route Woo product content through Gutenberg/Classic fragment extraction.
if ( function_exists( 'reeid_translate_html_with_openai' ) && trim( (string) $post->post_content ) !== '' ) {
    $content_tr = (string) reeid_translate_html_with_openai(
        (string) $post->post_content,
        isset( $src_lang ) && is_string( $src_lang ) && $src_lang !== '' ? $src_lang : 'en',
        $target_lang,
        'woocommerce_product',
        $tone,
        $prompt
    );

    if ( $content_tr !== '' ) {
        $content = $content_tr;
    }
}

                if (function_exists('reeid_translate_html_with_openai')) {
                    // Note: this helper doesn’t accept $prompt; leave as-is unless you extend its signature
                    $title_tr   = (string) reeid_translate_html_with_openai($post->post_title, 'en', $target_lang, $editor, $tone, $prompt);
                    $excerpt_tr = (string) reeid_translate_html_with_openai($post->post_excerpt, 'en', $target_lang, $editor, $tone, $prompt);

                    if ($title_tr !== '') {
                        $title = $title_tr;
                    }
                    if ($excerpt_tr !== '') {
                        $excerpt = $excerpt_tr;
                    }

                    $slug = function_exists('reeid_sanitize_native_slug') ? reeid_sanitize_native_slug($title) : sanitize_title($title);
                }

                if (!empty($attributes) && function_exists('reeid_translate_html_with_openai')) {
                    $attributes_tr = [];

    foreach ($attributes as $attr_name => $attr_val) {

        // Translate ATTRIBUTE NAME (label)
        $name_tr = (string) reeid_translate_html_with_openai(
            $attr_name,
            $src_lang,
            $target_lang,
            $editor,
            $tone,
            $prompt
        );
        if ($name_tr === '') {
            $name_tr = $attr_name;
        }

        // Translate ATTRIBUTE VALUE
        $value_tr = (string) reeid_translate_html_with_openai(
            $attr_val,
            $src_lang,
            $target_lang,
            $editor,
            $tone,
            $prompt
        );
        if ($value_tr === '') {
            $value_tr = $attr_val;
        }

        // Store translated label + value
        $attributes_tr[$name_tr] = $value_tr;
    }

    // Replace original attributes with translated set
    $attributes = $attributes_tr;
}

            }

            // Store inline translation (no new product post) — ALWAYS on src_id
            if (! function_exists('reeid_wc_store_translation_meta')) {
                if (function_exists('reeid_debug_log')) {
                    reeid_debug_log('S18/WC MISSING STORE FUNCTION', null);
                }
                wp_send_json_error(['error' => 'storage_unavailable']);
            }

            // Sanitize minimally
            $safe_title = trim(wp_strip_all_tags((string) $title));
            $safe_slug  = reeid_sanitize_native_slug($slug ?: $safe_title);
            $payload = [
                'title'      => (string) $safe_title,
                'content'    => (string) wp_kses_post($content),
                'excerpt'    => (string) wp_kses_post($excerpt),
                'slug'       => (string) $safe_slug,
                'updated'    => gmdate('c'),
                'editor'     => $editor,
                'attributes' => $attributes, // Save translated attributes to meta
            ];
           

            $ok = reeid_wc_store_translation_meta($src_id, $target_lang, $payload);

          

            // Update map on the cluster root to point this language to the same product (inline mode)
            $map      = (array) get_post_meta($src_id, '_reeid_translation_map', true);
            $map[$src_lang]    = $src_id;
            $map[$target_lang] = $src_id;
            update_post_meta($src_id, '_reeid_translation_map', $map);

            


            if (function_exists('reeid_debug_log')) {
                reeid_debug_log('S18/WC INLINE STORED', [
                    'post_id' => $post_id,
                    'src_id' => $src_id,
                    'lang' => $target_lang,
                    'ok' => $ok,
                    'lens' => [
                        'title' => strlen($payload['title']),
                        'excerpt' => strlen($payload['excerpt']),
                        'content' => strlen($payload['content']),
                        'attributes' => is_array($payload['attributes']) ? count($payload['attributes']) : 0,
                    ],
                ]);
            }

           $__reeid_response = [
    'ok'               => (bool) $ok,
    'action'           => 'stored_inline',
    'post_id'          => $src_id,
    'lang'             => $target_lang,
    'inline'           => true,
    'collected_count'  => 0,
    'translated_count' => 0,
];



if ( function_exists( 'reeid_prepare_menu_label_translations_for_lang' ) ) {
	reeid_prepare_menu_label_translations_for_lang( $target_lang );
}

wp_send_json_success( $__reeid_response );
}

 /*===========================================================
            DEFAULT PATH (Pages/Posts/etc.)
=========================================================== */
$src_id = $post_id;
$map    = (array) get_post_meta($src_id, '_reeid_translation_map', true);
$default_source_lang       = get_option('reeid_translation_source_lang', 'en');
$map[$default_source_lang] = $src_id;

$target_id = isset($map[$target_lang]) ? (int) $map[$target_lang] : 0;
$action    = 'updated';

/*
 * HARD VALIDATION:
 * Ensure target actually belongs to this source.
 * Prevent orphaned / stale ID reuse.
 */
if ($target_id) {
    $check_source = (int) get_post_meta($target_id, '_reeid_translation_source', true);

    if ($check_source !== (int) $src_id) {
        $target_id = 0; // force recreation
    }
}

if (! $target_id || ! get_post_status($target_id)) {


    // Determine canonical source post and type (defensive).
    $source_id   = isset($src_id) && $src_id ? (int) $src_id : (int) ($post->ID ?? 0);
    $source_type = $source_id ? get_post_type($source_id) : ($post->post_type ?? '');

    // If the source is a WooCommerce product or variation, do NOT create a new post.
    // Instead use inline-storage: point $target_id to the original product and mark action.
    if (in_array($source_type, array('product', 'product_variation'), true)) {
        $target_id = $source_id;
        $action    = 'stored_inline';
        // Optional downstream flag (harmless if unused)
        $reeid_translation_inline_mode = true;
    } else {

    // -------------------------------------------------------
    // HARD REUSE CHECK (prevents duplicate slug creation)
    // -------------------------------------------------------
   global $wpdb;

$cache_key = 'reeid_existing_' . sanitize_key( (string) $post->post_type ) . '_' . (int) $src_id . '_' . sanitize_key( (string) $target_lang );
$existing_id = wp_cache_get( $cache_key, 'reeid_translate' );

if ( false === $existing_id ) {

	// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
	$existing_id = (int) $wpdb->get_var(
		$wpdb->prepare(
			"SELECT p.ID
			 FROM {$wpdb->posts} p
			 INNER JOIN {$wpdb->postmeta} m1 ON p.ID = m1.post_id
			 INNER JOIN {$wpdb->postmeta} m2 ON p.ID = m2.post_id
			 WHERE p.post_type = %s
			   AND p.post_status NOT IN ('trash','auto-draft')
			   AND m1.meta_key = '_reeid_translation_source'
			   AND m1.meta_value = %d
			   AND m2.meta_key = '_reeid_translation_lang'
			   AND m2.meta_value = %s
			 LIMIT 1",
			$post->post_type,
			$src_id,
			$target_lang
		)
	);

	wp_cache_set( $cache_key, $existing_id, 'reeid_translate', 300 );
}

    if ( $existing_id ) {
        $target_id = $existing_id;
        $action    = 'updated';
    } else {

        // Create only if truly not existing
        $target_id = wp_insert_post(array(
            'post_type'   => $post->post_type,
            'post_status' => 'draft',
            'post_title'  => $post->post_title,
            'post_author' => $post->post_author,
        ), true);

        $action = 'created';

        if (is_wp_error($target_id)) {
            wp_send_json_error(array(
                'error'  => 'create_failed',
                'detail' => $target_id->get_error_message()
            ));
        }
    }
}

}

$collected_count  = 0;
$translated_count = 0;
$translated_slug  = '';

// Keep these visible for the SEO tail-section
$result     = null;
$title_tr   = '';
$excerpt_tr = '';

{

    // Gutenberg/Classic path
    $en_lines   = function_exists('reeid_extract_text_lines') ? reeid_extract_text_lines($post->post_content) : [];

    // IMPORTANT: pass $tone and RAW $prompt (merging happens inside helpers)
    $content_pack = function_exists('reeid_gutenberg_classic_translate_adapter')
    ? reeid_gutenberg_classic_translate_adapter($post->post_content, $target_lang, $tone, $prompt)
    : ['content' => ''];

$content_tr = is_string($content_pack['content'] ?? '') ? $content_pack['content'] : '';

    // Titles / excerpts via short-text helper — now supports $prompt
    $title_tr   = function_exists('reeid_translate_html_with_openai')
        ? reeid_translate_html_with_openai($post->post_title,   'en', $target_lang, $editor, $tone, $prompt)
        : '';
    $excerpt_tr = function_exists('reeid_translate_html_with_openai')
        ? reeid_translate_html_with_openai($post->post_excerpt, 'en', $target_lang, $editor, $tone, $prompt)
        : '';

    $ar_lines = [];
    if (is_string($content_tr) && $content_tr !== '' && $en_lines && function_exists('reeid_extract_text_lines')) {
        $ar_lines = reeid_extract_text_lines($content_tr);
    }

    $collected_count  = is_array($en_lines) ? count($en_lines) : 0;
    $translated_count = is_array($ar_lines) ? count($ar_lines) : 0;

    // Slug handling (Gutenberg/Classic)
    $translated_slug = '';
    if (is_string($title_tr) && $title_tr !== '') {
        $translated_slug = reeid_sanitize_native_slug($title_tr);
    }
    if ($translated_slug === '') {
        $translated_slug = reeid_sanitize_native_slug($post->post_title);
    }

    $translated_slug = wp_unique_post_slug(
        $translated_slug,
        $target_id,
        $publish_mode === 'publish' ? 'publish' : 'draft',
        $post->post_type,
        $post->post_parent
    );

    

   // Save
$new_post = [
    'ID'           => $target_id,
    'post_title'   => ($title_tr !== '' ? $title_tr : $post->post_title),
    'post_status'  => $publish_mode,
    'post_type'    => $post->post_type,
    'post_name'    => $translated_slug,
    'post_author'  => $post->post_author,
    'post_excerpt' => ($excerpt_tr !== '' ? $excerpt_tr : $post->post_excerpt),
];

// === Force this exact slug at save time (Gutenberg/Classic scope only) ===
$reeid_slug_to_force = $new_post['post_name'];



$reeid_cb_insert = static function ($data, $postarr) use (&$reeid_slug_to_force) {
    if (is_string($reeid_slug_to_force) && $reeid_slug_to_force !== '') {
        $data['post_name'] = $reeid_slug_to_force;
    }
    return $data;
};


add_filter('wp_insert_post_data', $reeid_cb_insert, PHP_INT_MAX, 2);

$target_id = function_exists('reeid_safe_wp_update_post')
    ? reeid_safe_wp_update_post($new_post, true)
    : wp_update_post($new_post, true);


remove_filter('wp_insert_post_data', $reeid_cb_insert, PHP_INT_MAX);
unset($reeid_slug_to_force, $reeid_cb_insert);

    if (is_wp_error($target_id)) {
        wp_send_json_error(['error' => 'update_failed', 'detail' => $target_id->get_error_message()]);
    }


    // Commit translated content if available
    if (isset($content_tr)) {
        $clean = is_string($content_tr) ? trim($content_tr) : '';
        if ($clean !== '') {
            if (function_exists('reeid_safe_wp_update_post')) {
                reeid_safe_wp_update_post(['ID' => $target_id, 'post_content' => $clean]);
            } else {
                wp_update_post(['ID' => $target_id, 'post_content' => $clean]);
            }
            delete_post_meta($target_id, '_reeid_translated_content_' . $target_lang);
        } else {
            update_post_meta($target_id, '_reeid_translated_content_' . $target_lang, $content_tr);
        }
    }

    // --- Guard: if translated title is native but saved slug is ASCII, fix immediately
    $title_for_slug = ($title_tr !== '' ? $title_tr : $post->post_title);
    $saved = get_post($target_id);
    if ($saved && isset($saved->post_name)) {
        $title_has_non_ascii = (bool) preg_match('/[^\x00-\x7F]/u', (string) $title_for_slug);
                reeid_maybe_fix_native_slug_after_update($target_id, $title_for_slug);
    }
}

// === REEID: Atomic translation network write (FIX hreflang symmetry) ===

// Resolve TRUE source (never assume current post)
$true_source = (int) get_post_meta($src_id, '_reeid_translation_source', true);
if (! $true_source) {
    $true_source = (int) $src_id;
}

// Ensure SOURCE declares its own language (hreflang self-return)
if (! get_post_meta($true_source, '_reeid_translation_lang', true)) {
    update_post_meta(
        $true_source,
        '_reeid_translation_lang',
        get_option('reeid_translation_source_lang', 'en')
    );
}

// Mark NEW translated post
update_post_meta($target_id, '_reeid_translation_lang', $target_lang);
update_post_meta($target_id, '_reeid_translation_source', $true_source);

// Rebuild translation map on SOURCE (overwrite, not merge)
$map = get_post_meta($true_source, '_reeid_translation_map', true);
if (! is_array($map)) {
    $map = [];
}

$map[$target_lang] = $target_id;

// Ensure SOURCE self-entry exists
$source_lang = get_post_meta($true_source, '_reeid_translation_lang', true)
    ?: get_option('reeid_translation_source_lang', 'en');

$map[$source_lang] = $true_source;

update_post_meta($true_source, '_reeid_translation_map', $map);
// === REEID: propagate full translation map to ALL nodes (hreflang symmetry) ===
foreach ( $map as $lang_code => $post_id_in_map ) {
    if ( (int) $post_id_in_map <= 0 ) {
        continue;
    }

    if ( $REEID_DRY_RUN ) {
        continue;
    }

    update_post_meta( (int) $post_id_in_map, '_reeid_translation_map', $map );
}
// === REEID: Mirror SOURCE translation map onto TARGET (hreflang symmetry) ===
if ( empty( $REEID_DRY_RUN ) ) {
    update_post_meta( $target_id, '_reeid_translation_map', $map );
} else {
}



// === END REEID FIX ===



// === END REEID FIX ===


if (function_exists('reeid_clone_seo_meta')) {
    reeid_clone_seo_meta($src_id, $target_id, $target_lang);
}

// === Write translated SEO meta (title + description) — single place ===
if ( ! wp_doing_ajax() && function_exists('reeid_write_title_all_plugins') ) {
      // Resolve langs
    $src_lang = $detect_lang($src_id);
    $tgt_lang = $target_lang;

    // Final title for target
       $final_title = (string)($title_tr !== '' ? $title_tr : $post->post_title);
    $final_title_trim = trim((string)$final_title);
    if ($final_title_trim !== '' && stripos($final_title_trim, 'INVALID LANGUAGE PAIR') === false) {
        reeid_safe_write_title_all_plugins($target_id, $final_title_trim);
    } else {
        if (function_exists('reeid_debug_log')) {
            reeid_debug_log('S18/SEO_SKIPPED_TITLE', [
                'post_id' => $target_id,
                'preview' => mb_substr($final_title_trim, 0, 80, 'UTF-8'),
            ]);
        }
    }
}

if (function_exists('reeid_write_description_all_plugins')) {
    // Always derive description from SOURCE (avoid double-translating target excerpts)
    $src_desc = '';
    if (function_exists('reeid_read_canonical_description')) {
        $src_desc = (string) reeid_read_canonical_description($src_id);
    } else {
        $src_desc = wp_strip_all_tags(get_post_field('post_excerpt', $src_id) ?: get_post_field('post_content', $src_id));
    }
    $src_desc = trim(preg_replace('/\s+/', ' ', (string)$src_desc));

    if ($src_desc !== '') {
        $src_lang = $detect_lang($src_id);
        $tgt_lang = $target_lang;

        $desc_tr = $src_desc;
        if ($src_lang && $tgt_lang && strcasecmp($src_lang, $tgt_lang) !== 0 && function_exists('reeid_translate_short_text')) {
            $desc_tr = (string) reeid_translate_short_text($src_desc, $src_lang, $tgt_lang, $tone);
            reeid_harden_invalid_lang_pair($desc_tr);
            $desc_tr_trim = trim($desc_tr);
            if ($desc_tr_trim !== '' && stripos($desc_tr_trim, 'INVALID LANGUAGE PAIR') === false) {
                reeid_write_description_all_plugins($target_id, $desc_tr_trim);
            } else {
                if (function_exists('reeid_debug_log')) {
                    reeid_debug_log('S18/SEO_SKIPPED_DESC', [
                        'post_id' => $target_id,
                        'preview' => mb_substr($desc_tr_trim, 0, 160, 'UTF-8'),
                    ]);
                }
            }
        }
    }

    if (get_post_type($target_id) === 'product' && class_exists('WC_Product') && function_exists('reeid_translate_product_attributes')) {
        $src_product = wc_get_product($src_id);
        $dst_product = wc_get_product($target_id);
        $src_lang = $default_source_lang;
        $dst_lang = $target_lang;
        if ($src_product && $dst_product) {
            if (empty($tone)) $tone = 'neutral';
            reeid_translate_product_attributes($src_product, $dst_product, $src_lang, $dst_lang, $tone);
        }
    }


if ( function_exists( 'reeid_prepare_menu_label_translations_for_lang' ) ) {
	reeid_prepare_menu_label_translations_for_lang( $target_lang );
}

    wp_send_json_success([
        'ok'               => true,
        'action'           => $action,
        'post_id'          => $target_id,
        'lang'             => $target_lang,
        'slug'             => $translated_slug,
        'collected_count'  => $collected_count,
        'translated_count' => $translated_count,
    ]);
}




if (isset($__reeid_response)) {
    wp_send_json_success($__reeid_response);
}

wp_send_json_success([
    'ok' => false,
    'error' => 'No response generated',
]);

    }}

 


   /* ========================================================================
   Generates nonce only when WordPress admin is fully loaded
   and injects the inline JS via admin_enqueue_scripts.
========================================================================*/
if ( ! function_exists( 'reeid_admin_validate_key_script' ) ) {
    function reeid_admin_validate_key_script( $hook ) {

        // Only on our settings page (best-effort).
        if ( 'settings_page_reeid-translate-settings' !== $hook ) {
            return;
        }

        // Ensure pluggable is available.
        if ( ! function_exists( 'wp_create_nonce' ) ) {
            return;
        }

        $nonce = wp_create_nonce( 'reeid_translate_nonce_action' );
        

        // Build inline JS without HEREDOC — required for WP.org repo.
        $js  = "jQuery(function(){";
        $js .= "var statusBox=document.getElementById('reeid_openai_key_status');";
        $js .= "var btn=document.getElementById('reeid_validate_openai_key');";
        $js .= "if(btn){btn.addEventListener('click',function(e){";
        $js .= "e.preventDefault();";
        $js .= "if(statusBox){statusBox.innerHTML='⏳ Validating...';}";
        $js .= "var keyEl=document.getElementById('reeid_openai_api_key');";
        $js .= "var key=keyEl?keyEl.value:'';";
        $js .= "fetch(ajaxurl,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},";
        $js .= "body:new URLSearchParams({";
        $js .= "action:'reeid_validate_openai_key',";
        $js .= "key:key,";
        $js .= "_wpnonce:'" . esc_js( $nonce ) . "',";
        $js .= "_ajax_nonce:'" . esc_js( $nonce ) . "'";
        $js .= "})";
        $js .= "}).then(function(res){return res.json();})";
        $js .= ".then(function(data){";
        $js .= "if(statusBox){";
        $js .= "if(data && data.success){";
        $js .= "statusBox.innerHTML='<span style=\"color:green;font-weight:bold;\">✔ Valid API Key</span>';";
        $js .= "}else{";
        $js .= "statusBox.innerHTML='<span style=\"color:red;font-weight:bold;\">❌ Invalid API Key</span>';";
        $js .= "}";
        $js .= "}";
        $js .= "}).catch(function(){";
        $js .= "if(statusBox){statusBox.innerHTML='<span style=\"color:red;\">❌ AJAX failed</span>';}";
        $js .= "});";
        $js .= "});}";
        $js .= "});";

        // Register an inert script handle and attach inline JS.
        wp_register_script( 'reeid-validate-key', false, array(), REEID_TRANSLATE_VERSION, true );
        wp_enqueue_script( 'reeid-validate-key' );
        wp_add_inline_script( 'reeid-validate-key', $js );

      
    }
    add_action( 'admin_enqueue_scripts', 'reeid_admin_validate_key_script', 20 );
}
