<?php
if (! defined('ABSPATH')) {
    exit;
} final class PufferGo_String_Translator
{
    public const NAMESPACE = 'puffergo/v1';

    public const ROUTE = '/translation/translate-strings';

    public static function init(): void
    {
        $self = new self();
        add_action('rest_api_init', array($self, 'register_route'));
        add_action('admin_footer', array($self, 'maybe_render_control'));
    }

    public function register_route(): void
    {
        register_rest_route(self::NAMESPACE, self::ROUTE, array('methods' => 'POST', 'callback' => array($this, 'translate_strings'), 'permission_callback' => array($this, 'check_permission'), 'args' => array('lang' => array('required' => true, 'sanitize_callback' => 'sanitize_text_field', ), ), ));
    }

    public function check_permission(): bool
    {
        return current_user_can('manage_options');
    }

    public function translate_strings(WP_REST_Request $request): WP_REST_Response
    {
        $lang = $request->get_param('lang');

        if (! PufferGo_Polylang::is_active() || ! class_exists('PLL_MO') || ! class_exists('PLL_Admin_Strings')) {
            return $this->error(__('Polylang string translation is not available.', 'puffergo'), 409);
        } $default = PufferGo_Polylang::default_language();
        $language = PufferGo_Polylang::language_object($lang);

        if (null === $language) {
            return $this->error(__('Unknown language.', 'puffergo'), 409);
        } $primary_mo = null;

        if ($lang !== $default) {
            $primary_obj = PufferGo_Polylang::language_object($default);

            if (null !== $primary_obj) {
                $primary_mo = new PLL_MO();
                $primary_mo->import_from_db($primary_obj);
            }
        } $mo = new PLL_MO();
        $mo->import_from_db($language);
        $items = array();
        $entry_map = array();
        $index = 0;
        $strings_param = $request->get_param('strings');
        $source_rows = is_array($strings_param) && ! empty($strings_param) ? array_map(fn ($s) => array('string' => (string) $s), $strings_param) : PLL_Admin_Strings::get_strings();

        foreach ($source_rows as $row) {
            $registered = isset($row['string']) ? (string) $row['string'] : '';

            if ('' === trim($registered)) {
                continue;
            } $substantive = trim(preg_replace('/%[^%]*%/', '', $registered));

            if ('' === $substantive) {
                continue;
            }

if ('' !== trim($mo->translate_if_any($registered))) {
                continue;
            } $primary_translation = $primary_mo ? trim($primary_mo->translate_if_any($registered)) : '';

            if ($primary_mo && '' === $primary_translation) {
                continue;
            } $source = '' !== $primary_translation ? $primary_translation : $registered;
            $id = 's' . $index++;
            $items[] = array('id' => $id, 'text' => $source, 'contentType' => 'meta', );
            $entry_map[ $id ] = $registered;
        } $count = 0;

        if (! empty($items)) {
            try {
                $result = PufferGo_Translation_Client::translate($items, PufferGo_Polylang::locale_for($lang));
            } catch (PufferGo_API_Exception $e) {
                $code = $e->getCode();

                return new WP_REST_Response($e->toArray(), ($code >= 400 && $code < 600) ? $code : 500);
            } catch (Exception $e) {
                $code = $e->getCode();

                return $this->error($e->getMessage(), ($code >= 400 && $code < 600) ? $code : 500);
            } $translations = $result['translations'];

            foreach ($entry_map as $id => $registered) {
                if (! isset($translations[ $id ]) || '' === trim((string) $translations[ $id ])) {
                    continue;
                } $mo->add_entry($mo->make_entry($registered, (string) $translations[ $id ]));
                ++$count;
            }
        } else {
            $result = array('creditsRemaining' => null);
        }

if ($count > 0) {
            $mo->export_to_db($language);
        }

return new WP_REST_Response(array('success' => true, 'count' => $count, 'creditsRemaining' => $result['creditsRemaining'], ), 200);
    }

    private function error(string $message, int $status): WP_REST_Response
    {
        return new WP_REST_Response(array('success' => false, 'message' => $message), $status);
    }

    public function maybe_render_control(): void
    {
        global $pagenow;

        if ('admin.php' !== $pagenow || 'mlang_strings' !== ($_GET['page'] ?? '')) {
            return;
        }

if (! current_user_can('manage_options') || ! PufferGo_Polylang::is_active()) {
            return;
        }

if (! class_exists('PLL_MO') || ! class_exists('PLL_Admin_Strings')) {
            return;
        } $default = PufferGo_Polylang::default_language();
        $languages = PufferGo_Polylang::languages();

        if (count($languages) < 2) {
            return;
        } $all_strings = PLL_Admin_Strings::get_strings();
        $substantive = array_values(array_filter($all_strings, fn ($r) => '' !== trim(preg_replace('/%[^%]*%/', '', $r['string'] ?? ''))));
        $total = count($substantive);
        $progress = array();

        foreach ($languages as $language) {
            $lang_obj = PufferGo_Polylang::language_object($language['slug']);
            $filled = 0;
            $unfilled = array();

            if (null !== $lang_obj) {
                $mo = new PLL_MO();
                $mo->import_from_db($lang_obj);

                foreach ($substantive as $row) {
                    if ('' !== trim($mo->translate_if_any($row['string']))) {
                        ++$filled;
                    } else {
                        $unfilled[] = $row['name'] . ': ' . mb_strimwidth($row['string'], 0, 40, '…');
                    }
                }
            } $progress[] = array('slug' => $language['slug'], 'name' => $language['name'], 'filled' => $filled, 'total' => $total, 'default' => $language['slug'] === $default, 'unfilled' => $unfilled, );
        } $rest_url = esc_url_raw(rest_url(self::NAMESPACE . self::ROUTE));
        $nonce = wp_create_nonce('wp_rest');
        $strings_for_js = array_map(fn ($r) => $r['string'], $substantive); ?>
		<div id="puffergo-st" style="display:none"></div>
		<script>
		( function () {
			var PROGRESS = <?php echo wp_json_encode($progress); ?>;
			var REST     = <?php echo wp_json_encode($rest_url); ?>;
			var NONCE    = <?php echo wp_json_encode($nonce); ?>;
			var STRINGS  = <?php echo wp_json_encode($strings_for_js); ?>;
			var I18N = {
				translate    : <?php echo wp_json_encode(__('AI Translate', 'puffergo')); ?>,
				translating  : <?php echo wp_json_encode(__('Translating…', 'puffergo')); ?>,
				primary      : <?php echo wp_json_encode(__('primary', 'puffergo')); ?>,
				primaryHint  : <?php echo wp_json_encode(__('Tip: Complete the primary language first — other languages will use it as the translation source.', 'puffergo')); ?>,
				errDefault   : <?php echo wp_json_encode(__('Translation failed. Please try again.', 'puffergo')); ?>,
			};

			var panel = document.getElementById( 'puffergo-st' );
			if ( ! panel ) { return; }

			var primaryLang = PROGRESS.find( function ( l ) { return l.default; } );

			function esc( s ) {
				return String( s ).replace( /&/g, '&amp;' ).replace( /</g, '&lt;' ).replace( />/g, '&gt;' ).replace( /"/g, '&quot;' );
			}

			function pct( l ) { return l.total ? Math.round( l.filled / l.total * 100 ) : 100; }

			function translate( lang, btn ) {
				btn.disabled    = true;
				btn.textContent = I18N.translating;

				fetch( REST, {
					method      : 'POST',
					credentials : 'same-origin',
					headers     : { 'Content-Type': 'application/json', 'X-WP-Nonce': NONCE },
					body        : JSON.stringify( { lang: lang, strings: STRINGS } ),
				} ).then( function ( r ) {
					return r.json().then( function ( d ) { return { ok: r.ok, data: d }; } );
				} ).then( function ( res ) {
					if ( res.ok && res.data && res.data.success ) {
						window.location.href = window.location.href;
					} else {
						alert( ( res.data && res.data.message ) ? res.data.message : I18N.errDefault );
						btn.disabled    = false;
						btn.textContent = I18N.translate;
					}
				} ).catch( function () {
					alert( I18N.errDefault );
					btn.disabled    = false;
					btn.textContent = I18N.translate;
				} );
			}

			function render() {
				var primaryDone = ! primaryLang || primaryLang.filled >= primaryLang.total;

				var rows = PROGRESS.map( function ( l ) {
					var p        = pct( l );
					var done     = l.filled >= l.total;
					var blocked  = ! l.default && ! primaryDone;
					var tag      = l.default ? ' <span style="color:#999;font-size:11px">(' + I18N.primary + ')</span>' : '';
					var pct_bar  = '<div style="flex:1;max-width:180px;background:#ddd;border-radius:3px;height:8px">'
						+ '<div style="width:' + p + '%;background:' + ( done ? '#46b450' : '#2271b1' ) + ';height:8px;border-radius:3px;transition:width .3s"></div>'
						+ '</div>';
					var count    = '<span style="font-size:12px;color:#555;min-width:60px">'
						+ l.filled + ' / ' + l.total
						+ ( done ? ' <span style="color:#46b450;font-weight:bold">✓</span>' : '' )
						+ '</span>';
					var btn      = '<button type="button" class="button pg-st-btn" data-lang="' + esc( l.slug ) + '"'
						+ ( blocked ? ' disabled' : '' )
						+ ' style="margin-left:4px">' + I18N.translate + '</button>';
					var missing  = ( ! done && l.unfilled && l.unfilled.length )
						? '<div style="margin:2px 0 4px 140px;font-size:11px;color:#888">'
							+ l.unfilled.map( function ( s ) { return '· ' + esc( s ); } ).join( '<br>' )
							+ '</div>'
						: '';
					return '<div style="display:flex;align-items:center;gap:10px;margin:4px 0">'
						+ '<span style="min-width:130px;font-size:13px">' + esc( l.name ) + tag + '</span>'
						+ pct_bar + count + btn
						+ '</div>' + missing;
				} ).join( '' );

				var hint = primaryDone ? '' : '<p style="margin:8px 0 0;font-size:12px;color:#856404;background:#fff3cd;border:1px solid #ffc107;border-radius:3px;padding:6px 10px">'
					+ I18N.primaryHint + '</p>';

				panel.innerHTML = rows + hint;

				panel.querySelectorAll( '.pg-st-btn' ).forEach( function ( btn ) {
					btn.addEventListener( 'click', function () { translate( btn.dataset.lang, btn ); } );
				} );
			}

			var tablenav = document.querySelector( '#string-translation .tablenav.top' );
			if ( tablenav ) {
				panel.style.cssText = 'background:#fff;border:1px solid #c3c4c7;border-radius:3px;padding:12px 16px;margin:8px 0';
				tablenav.insertAdjacentElement( 'afterend', panel );
			}

			render();
		} )();
		</script>
		<?php
    }
}
