<?php
/**
 * REEID Translate — Translator Engine Wrappers
 *
 * Contains:
 *  - Section 21: Map-based translation wrapper
 *  - Shared translator helpers used by AJAX handlers, Gutenberg, Classic Editor, and WooCommerce
 */

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


if (! function_exists('reeid_call_translation_engine_for_map')) {
    /**
     * Translate associative map of { key => text } using plugin's engine.
     * Returns same shape array with translated values.
     *
     * @param array  $map         Keys → text/html
     * @param string $target_lang ISO language code
     * @param array  $ctx         Extra context (post_id, tone, prompt, etc.)
     * @return array
     */
    function reeid_call_translation_engine_for_map(array $map, string $target_lang, array $ctx = []): array
    {
        if (empty($map)) {
            return $map;
        }
        if (!function_exists('reeid_translate_map_via_openai')) {
            // Fallback: identity (English stays untranslated)
            if (function_exists('reeid_debug_log')) {
                reeid_debug_log('S17.9/NO_ENGINE', ['map_count' => count($map)]);
            }
            return $map;
        }

        // Delegate to engine
        $result = reeid_translate_map_via_openai($map, $target_lang, $ctx);

        if (empty($result)) {
            // Defensive fallback: return original if translation failed
            if (function_exists('reeid_debug_log')) {
                reeid_debug_log('S17.9/TRANSLATION_FAILED', ['map_count' => count($map)]);
            }
            return $map;
        }

        if (function_exists('reeid_debug_log')) {
            reeid_debug_log('S17.9/TRANSLATED', [
                'orig_count' => count($map),
                'out_count'  => count($result),
                'lang'       => $target_lang
            ]);
        }

        return $result;
    }
}

/*============================================================================================
  SECTION 24: TRANSLATE FUNCTION — OpenAI Wrapper with Collectors (LEGACY, FORCE NATIVE SLUG)
============================================================================================*/

if ( ! function_exists( 'reeid_translate_map_via_openai' ) ) {
    /**
     * Translate associative map of key => text/html using existing single-text translator.
     * Safe fallback implementation for structured builders (SiteOrigin, Woo maps, etc).
     *
     * @param array  $map         Keys => source text/html.
     * @param string $target_lang Target language code.
     * @param array  $ctx         Context: post_id, tone, prompt, editor, mode.
     * @return array
     */
    function reeid_translate_map_via_openai( array $map, string $target_lang, array $ctx = [] ): array {
        if ( empty( $map ) ) {
            return $map;
        }

        $post_id = isset( $ctx['post_id'] ) ? (int) $ctx['post_id'] : 0;
        $tone    = isset( $ctx['tone'] ) && is_string( $ctx['tone'] ) && $ctx['tone'] !== ''
            ? (string) $ctx['tone']
            : 'Neutral';
        $prompt  = isset( $ctx['prompt'] ) && is_string( $ctx['prompt'] )
            ? (string) $ctx['prompt']
            : '';
        $editor  = isset( $ctx['editor'] ) && is_string( $ctx['editor'] ) && $ctx['editor'] !== ''
            ? (string) $ctx['editor']
            : 'classic';

            $system_prompt = function_exists( 'reeid_get_combined_prompt' )
    ? (string) reeid_get_combined_prompt( $post_id, $target_lang, $prompt )
    : (string) $prompt;

        $source_lang = 'en';
        if ( $post_id > 0 ) {
            $meta_lang = (string) get_post_meta( $post_id, '_reeid_translation_lang', true );
            if ( $meta_lang !== '' ) {
                $source_lang = $meta_lang;
            }
        }

        $chunks = function_exists( 'reeid_chunk_translation_map' )
            ? reeid_chunk_translation_map( $map, 4000 )
            : array( $map );

        $out = array();

        foreach ( $chunks as $chunk ) {
            foreach ( $chunk as $k => $v ) {
                if ( ! is_scalar( $v ) ) {
                    $out[ $k ] = $v;
                    continue;
                }

                $src = (string) $v;
                if ( trim( $src ) === '' ) {
                    $out[ $k ] = $src;
                    continue;
                }

                if ( function_exists( 'reeid_translate_html_with_openai' ) ) {
                    $tr = reeid_translate_html_with_openai(
                    $src,
                    $source_lang,
                    $target_lang,
                    $editor,
                    $tone,
                    $system_prompt
                );

                    $out[ $k ] = is_string( $tr ) && $tr !== '' ? $tr : $src;
                } else {
                    $out[ $k ] = $src;
                }
            }
        }

        if ( function_exists( 'reeid_debug_log' ) ) {
            reeid_debug_log(
                'S17.95/MAP_TRANSLATED',
                array(
                    'post_id' => $post_id,
                    'editor'  => $editor,
                    'count'   => count( $map ),
                    'lang'    => $target_lang,
                )
            );
        }

        return $out;
    }
}

    /**
 * Main translation engine with slug generation
 * - SINGLE translation: metabox (or auto) for source; target is func arg.
 * - BULK translation: admin options/ctx drive source/target.
 * - Uses reeid_lang_normalize() (Italian => it-it, Burmese => my-mm).
 */
if (! function_exists('reeid_translate_via_openai_with_slug')) {
    function reeid_translate_via_openai_with_slug(string $content, string $target_lang, array $ctx = []): array
    {
        $engine_debug = static function ( $label, $data = null ) {
    if ( function_exists( 'reeid_debug_log' ) ) {
        reeid_debug_log( $label, $data );
    }
};
        $post_id  = intval($ctx['post_id'] ?? 0);
        $post     = $post_id ? get_post($post_id) : null;
// Editor + mode
$editor = $post && function_exists( 'reeid_resolve_source_editor' )
    ? reeid_resolve_source_editor( $post )
    : 'classic';
// Free version uses single translation mode only.
$mode = 'single';

        // Read metabox/admin options
        $meta_src = $post ? (string) get_post_meta($post_id, '_reeid_source_lang', true) : '';
        $meta_tgt = $post ? (string) get_post_meta($post_id, '_reeid_target_lang', true) : '';



        // Detection helper
        $detect_lang = static function (string $html): string {
            $probe = trim(wp_strip_all_tags($html));
            $det   = function_exists('reeid_detect_language') ? (string) reeid_detect_language($probe) : '';
            if ($det === '' || strlen($det) > 16) {
                $det = 'en';
            }
            return reeid_lang_normalize($det);
        };

               // Resolve prefs for single translation mode.
        $source_pref = $meta_src !== '' ? strtolower($meta_src) : 'auto';
        $target_pref = $target_lang !== '' ? strtolower($target_lang)
            : ($meta_tgt !== '' ? strtolower($meta_tgt) : '');

        // Normalize to your supported keys (this is where 'it' -> 'it-it', 'my' -> 'my-mm' happens)
        $source_pref = reeid_lang_normalize($source_pref);
        $target_pref = reeid_lang_normalize($target_pref);

        // Final effective languages
        $source_lang = ($source_pref === '' || $source_pref === 'auto') ? $detect_lang($content) : $source_pref;
        $target_lang = $target_pref !== '' ? $target_pref : 'en'; // last resort

            $engine_debug( 'S17_ENTRY', array(
        'mode'    => $mode,
        'editor'  => $editor,
        'post_id' => $post_id,
        'src'     => $source_lang,
        'tgt'     => $target_lang,
    ) );
        // Custom prompt (constraints) from upstream context.
$user_prompt = '';
if ( ! empty( $ctx['prompt'] ) && is_string( $ctx['prompt'] ) ) {
    $user_prompt = trim( (string) $ctx['prompt'] );
}

// Build FULL system prompt (base + constraints). Woo must not send constraints-only.
$system_prompt = function_exists( 'reeid_get_combined_prompt' )
    ? (string) reeid_get_combined_prompt( (int) $post_id, (string) $target_lang, (string) $user_prompt )
    : (string) $user_prompt;

        // No-op if src == tgt
        if ($source_lang === $target_lang) {
            $title = $post ? $post->post_title : 'translation';
            $slug  = reeid_sanitize_native_slug(mb_substr(wp_strip_all_tags($title), 0, 60));
            return ['ok' => true, 'content' => $content, 'slug' => $slug];
        }

        $translated = '';
        $slug       = '';

        try {
            if ($editor === 'gutenberg') {
                // === Collect
                $blocks = parse_blocks($content);
                $map    = reeid_gutenberg_walk_and_collect($blocks);
                $engine_debug( 'S17_GUTENBERG_COLLECTED', array(
                    'count' => count( $map ),
                ) );

                // === Partition
                $map_plain = [];
                $map_html  = [];
                foreach ($map as $k => $v) {
                    if (is_string($v) && strpos($v, '<') !== false && preg_match('/<[^>]+>/', $v)) {
                        $map_html[$k] = $v;
                    } else {
                        $map_plain[$k] = $v;
                    }
                }

                $translated_map = [];

                // === Translate plain-text (whitespace-preserving)
                if (!empty($map_plain)) {
                    $ws_plain       = [];
                    $map_plain_core = [];

                    foreach ($map_plain as $k => $raw) {
                        $raw = (string) $raw;
                        if (preg_match('/^([\x{00A0}\s]*)(.*?)([\x{00A0}\s]*)$/u', $raw, $m)) {
                            $left = $m[1];
                            $core = $m[2];
                            $right = $m[3];
                        } else {
                            $left = $right = '';
                            $core = $raw;
                        }
                        $ws_plain[$k]       = [$left, $right];
                        $map_plain_core[$k] = $core;
                    }

                    $plain_chunks = function_exists('reeid_chunk_translation_map')
                        ? reeid_chunk_translation_map($map_plain_core, 4000)
                        : [$map_plain_core];

                    foreach ($plain_chunks as $chunk) {
                        $has_content = false;
                        foreach ($chunk as $v) {
                            if ($v !== '') {
                                $has_content = true;
                                break;
                            }
                        }
                        if (!$has_content) {
                            foreach ($chunk as $ck => $core_in) {
                                [$l, $r] = $ws_plain[$ck] ?? ['', ''];
                                $translated_map[$ck] = $l . $core_in . $r;
                            }
                            continue;
                        }

                        $prompt  = "Task: Translate all JSON values FROM {$source_lang} TO {$target_lang}. Keep keys EXACTLY unchanged.\n"
                            . "Translate ONLY the values. Do not add/remove keys or change JSON.\n"
                            . "Do not add or remove leading/trailing whitespace in any value.\n"
                            . "Return STRICT JSON only (no comments/markdown).";

                        $json_in = wp_json_encode($chunk, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

                        $json_out = reeid_translate_html_with_openai(
                            $prompt . "\n" . $json_in,
                            $source_lang,
                            $target_lang,
                            'gutenberg',
                            'neutral',
                             $system_prompt
                        );

                        $decoded = null;
                        if (is_string($json_out) && preg_match('/\{.*\}/s', $json_out, $m)) {
                            $clean = function_exists('reeid_json_sanitize_controls_v2')
                                ? reeid_json_sanitize_controls_v2($m[0], $s = [])
                                : $m[0];
                            $decoded = function_exists('reeid_safe_json_decode')
                                ? reeid_safe_json_decode($clean)
                                : json_decode($clean, true);
                        }

                        if (is_array($decoded)) {
                            foreach ($chunk as $ck => $core_in) {
                                $core_out = array_key_exists($ck, $decoded) && is_string($decoded[$ck])
                                    ? (string) $decoded[$ck]
                                    : $core_in;
                                [$l, $r]  = $ws_plain[$ck] ?? ['', ''];
                                $translated_map[$ck] = $l . $core_out . $r;
                            }
                        } else {
                            foreach ($chunk as $ck => $core_in) {
                                [$l, $r] = $ws_plain[$ck] ?? ['', ''];
                                $translated_map[$ck] = $l . $core_in . $r;
                            }
                        }
                    }

                    $engine_debug( 'S17_GUTENBERG_PLAIN_MAP_TRANSLATED' );
                }

// === Translate HTML via OpenAI (preserve tags)
if (!empty($map_html)) {
    foreach ($map_html as $k => $frag) {

        $tr = reeid_translate_html_with_openai(
            $frag,
            $source_lang,
            $target_lang,
            'gutenberg',
            'neutral',
            $system_prompt
        );

        $translated_map[$k] = (is_wp_error($tr) || $tr === '')
            ? $frag
            : (string) $tr;
    }

    $engine_debug( 'S17_GUTENBERG_HTML_SEGMENTS_TRANSLATED' );
}

                // === Rebuild (preserve ALL attrs)
                $translated = reeid_gutenberg_serialize_preserve_attrs(
                    reeid_gutenberg_walk_and_replace($blocks, $translated_map),
                    $translated_map
                );
                                               
            } else {
                // Classic
$out = reeid_translate_html_with_openai($content, $source_lang, $target_lang, 'classic', 'neutral',  $system_prompt);
                if (is_wp_error($out)) $out = $content;
                $out = preg_replace('/<!DOCTYPE.*?<body[^>]*>/is', '', $out);
                $out = preg_replace('/<\/body>\s*<\/html>\s*$/is', '', $out);
                $translated = trim($out);
            }
        } catch (Throwable $e) {
            $engine_debug( 'S17_ERROR', array(
    'message' => $e->getMessage(),
) );
            return ['ok' => false, 'error' => 'engine_failed', 'content' => $content, 'slug' => ''];
        }

                // === Slug generation
        $slug = reeid_build_translated_slug_pack(
            $post,
            $source_lang,
            $target_lang,
            $editor,
            $system_prompt
        );

        $engine_debug( 'S17_SLUG', array(
    'slug' => $slug,
    'len'  => mb_strlen( $translated ),
) );

        return ['ok' => true, 'content' => $translated, 'slug' => $slug];
    }
}
