/**
 * LangForge Admin JavaScript
 */

(function($) {
    'use strict';

    var LF_Admin = {
 // true after a successful QA Check render until the user
        // saves / dismisses the results or applies every suggestion. Used
        // by beforeunload to warn before the tab is closed or refreshed.
        qaResultsActive: false,

        init: function() {
            this.bindEvents();
            this.setupBeforeUnload();
        },

        bindEvents: function() {
            $(document).on('click', '.lf-create-translation', this.createTranslation);
            $(document).on('click', '.lf-link-translation', this.showLinkDialog);
            $(document).on('click', '.lf-unlink-btn', this.unlinkTranslation);
            $(document).on('click', '.lf-ai-translate-btn', this.aiTranslatePost);
            $(document).on('click', '.lf-create-ai-translate', this.createAndAiTranslate);

            // Quick create from language column
            $(document).on('click', '.lf-col-trans--create', this.quickCreateFromColumn);

            // Term translation unlink
            $(document).on('click', '.avl-unlink-term-translation', this.unlinkTermTranslation);

            // QA Check
            $(document).on('click', '.lf-qa-check-btn', this.qaCheck);
            $(document).on('click', '.lf-qa-fix-btn', this.qaFix);
 // controlled reload when DOM sync couldn't find a matching
            // editor surface — server-side change IS saved, user just needs
            // to see it. Clear the unsaved-work flag first so WP's own
            // beforeunload handler doesn't prompt.
            $(document).on('click', '.lf-qa-reload-link', function(e) {
                e.preventDefault();
                LF_Admin.qaResultsActive = false;
                if (typeof window.tinymce !== 'undefined') {
                    try {
                        var ed = window.tinymce.get('content');
                        if (ed) ed.isNotDirty = true;
                    } catch (_) {}
                }
                window.location.reload();
            });
 // the "Dismiss" X button on the results panel clears
            // the unsaved flag so beforeunload stops nagging.
            $(document).on('click', '.lf-qa-dismiss', function() {
                LF_Admin.qaResultsActive = false;
                $(this).closest('.lf-qa-results').slideUp(200);
            });
        },

 // warn the user before leaving the page with unsaved AI QA
        // Check results. Fresh analysis costs credits to re-run.
        setupBeforeUnload: function() {
            $(window).on('beforeunload', function(e) {
                if (!LF_Admin.qaResultsActive) return;
                var msg = (window.lfAdmin && lfAdmin.strings && lfAdmin.strings.qaUnsaved)
                    ? lfAdmin.strings.qaUnsaved
                    : 'You have unsaved AI QA Check results. Leaving will lose them and re-running will spend AI credits.';
                (e || window.event).returnValue = msg;
                return msg;
            });
        },

        /**
 * Show credits exhausted message
 */
        showCreditsExhausted: function(data) {
            var resetDate = data.reset_date ? new Date(data.reset_date).toLocaleDateString() : '';
            var msg = 'Monthly AI credits exhausted.';
            if (resetDate) msg += ' Resets on ' + resetDate + '.';
            this.toast(msg, 'error');
        },

        /**
 * Show toast notification
 */
        toast: function(message, type) {
            type = type || 'success';
            var $toast = $('<div class="avl-toast avl-toast--' + type + '">' + message + '</div>');
            $('body').append($toast);
            setTimeout(function() {
                $toast.fadeOut(300, function() { $toast.remove(); });
            }, 3000);
        },

        createTranslation: function(e) {
            e.preventDefault();

            var $btn = $(this);
            var postId = $btn.data('post-id');
            var lang = $btn.data('lang');
            var originalText = $btn.text();

            $btn.prop('disabled', true).html('<span class="lf-spinner"></span>');

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_create_translation',
                    nonce: lfAdmin.nonce,
                    post_id: postId,
                    language: lang
                },
                success: function(response) {
                    if (response.success) {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.saved);
                        window.location.href = response.data.edit_url;
                    } else {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.error, 'error');
                        $btn.prop('disabled', false).text(originalText);
                    }
                },
                error: function() {
                    LF_Admin.toast(lfAdmin.strings.error, 'error');
                    $btn.prop('disabled', false).text(originalText);
                }
            });
        },

        showLinkDialog: function(e) {
            e.preventDefault();

            var $btn = $(this);
            var postId = $btn.data('post-id');
            var lang = $btn.data('lang');

            var targetId = prompt('Enter the Post ID to link as translation:');

            if (!targetId || isNaN(targetId)) {
                return;
            }

            $btn.prop('disabled', true).html('<span class="lf-spinner"></span>');

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_link_translation',
                    nonce: lfAdmin.nonce,
                    post_id: postId,
                    target_post_id: parseInt(targetId),
                    language: lang
                },
                success: function(response) {
                    if (response.success) {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.saved);
                        location.reload();
                    } else {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.error, 'error');
                        $btn.prop('disabled', false).text('Link existing');
                    }
                },
                error: function() {
                    LF_Admin.toast(lfAdmin.strings.error, 'error');
                    $btn.prop('disabled', false).text('Link existing');
                }
            });
        },

        unlinkTranslation: function(e) {
            e.preventDefault();

            if (!confirm('Unlink this translation?')) {
                return;
            }

            var $btn = $(this);
            var postId = $btn.data('post-id');
            var lang = $btn.data('lang');

            $btn.prop('disabled', true);

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_unlink_translation',
                    nonce: lfAdmin.nonce,
                    post_id: postId,
                    language: lang
                },
                success: function(response) {
                    if (response.success) {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.saved);
                        location.reload();
                    } else {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.error, 'error');
                        $btn.prop('disabled', false);
                    }
                },
                error: function() {
                    LF_Admin.toast(lfAdmin.strings.error, 'error');
                    $btn.prop('disabled', false);
                }
            });
        },

        /**
 * AI Translate an existing translation post
 */
        aiTranslatePost: function(e) {
            e.preventDefault();
            var $btn = $(this);
            var sourceId = $btn.data('source');
            var targetId = $btn.data('target');
            var sourceLang = $btn.data('source-lang');
            var targetLang = $btn.data('target-lang');

            if (!confirm('AI translate this post to ' + targetLang.toUpperCase() + '? This will overwrite the translation content.')) return;

            $btn.addClass('loading');

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_ai_translate_post',
                    nonce: lfAdmin.nonce,
                    source_id: sourceId,
                    target_id: targetId,
                    source_lang: sourceLang,
                    target_lang: targetLang
                },
                success: function(r) {
                    $btn.removeClass('loading');
                    if (r.success) {
                        LF_Admin.toast(r.data.message || 'Translation complete! Reloading...');
                        setTimeout(function(){ location.reload(); }, 1000);
                    } else if (r.data && r.data.error === 'credits_exhausted') {
                        LF_Admin.showCreditsExhausted(r.data);
                    } else {
                        LF_Admin.toast(r.data.message || 'Translation failed.', 'error');
                    }
                },
                error: function() {
                    $btn.removeClass('loading');
                    LF_Admin.toast('AI translation request failed.', 'error');
                }
            });
        },

        /**
 * Create translation + AI translate in one step
 */
        createAndAiTranslate: function(e) {
            e.preventDefault();
            var $btn = $(this);
            var postId = $btn.data('post-id');
            var lang = $btn.data('lang');
            var sourceLang = $btn.data('source-lang');

            $btn.prop('disabled', true).html('<span class="lf-spinner"></span> Creating + Translating...');

            // Step 1: Create translation
            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_create_translation',
                    nonce: lfAdmin.nonce,
                    post_id: postId,
                    language: lang
                },
                success: function(r) {
                    if (r.success && r.data.post_id) {
                        // Step 2: AI translate
                        $.ajax({
                            url: lfAdmin.ajaxUrl,
                            type: 'POST',
                            data: {
                                action: 'lf_ai_translate_post',
                                nonce: lfAdmin.nonce,
                                source_id: postId,
                                target_id: r.data.post_id,
                                source_lang: sourceLang,
                                target_lang: lang
                            },
                            success: function(r2) {
                                if (r2.success) {
                                    LF_Admin.toast('Created + AI translated! Redirecting...');
                                    setTimeout(function() {
                                        window.location.href = r.data.edit_url;
                                    }, 1000);
                                } else if (r2.data && r2.data.error === 'credits_exhausted') {
                                    LF_Admin.showCreditsExhausted(r2.data);
                                    window.location.href = r.data.edit_url;
                                } else {
                                    LF_Admin.toast('Created but translation failed: ' + (r2.data.message || ''), 'error');
                                    window.location.href = r.data.edit_url;
                                }
                            },
                            error: function() {
                                LF_Admin.toast('Created but AI translation failed.', 'error');
                                window.location.href = r.data.edit_url;
                            }
                        });
                    } else {
                        LF_Admin.toast(r.data.message || 'Failed to create translation.', 'error');
                        $btn.prop('disabled', false).html('<span class="dashicons dashicons-translation" style="font-size:14px;width:14px;height:14px;vertical-align:text-bottom;"></span> Create + AI Translate');
                    }
                },
                error: function() {
                    LF_Admin.toast('Request failed.', 'error');
                    $btn.prop('disabled', false).html('<span class="dashicons dashicons-translation" style="font-size:14px;width:14px;height:14px;vertical-align:text-bottom;"></span> Create + AI Translate');
                }
            });
        },

        /**
 * Quick create translation from Language column in post list
 */
        quickCreateFromColumn: function(e) {
            e.preventDefault();
            var $link = $(this);
            var postId = $link.data('post-id');
            var lang = $link.data('lang');
            var nonce = $link.data('nonce');

            $link.text('...').css('pointer-events', 'none');

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_create_translation',
                    nonce: nonce,
                    post_id: postId,
                    language: lang
                },
                success: function(r) {
                    if (r.success && r.data.edit_url) {
                        window.location.href = r.data.edit_url;
                    } else {
                        $link.text('+' + lang.toUpperCase()).css('pointer-events', '');
                        LF_Admin.toast(r.data.message || 'Error', 'error');
                    }
                },
                error: function() {
                    $link.text('+' + lang.toUpperCase()).css('pointer-events', '');
                }
            });
        },

        /**
 * QA Quality Check
 */
        qaCheck: function(e) {
            e.preventDefault();
            var $btn = $(this);
            var originalId = $btn.data('original');
            var translationId = $btn.data('translation');
            var sourceLang = $btn.data('source-lang');
            var targetLang = $btn.data('target-lang');
            var $results = $btn.closest('.lf-qa-section').find('.lf-qa-results');

            $btn.addClass('loading');
            $btn.find('.dashicons').removeClass('dashicons-yes-alt').addClass('dashicons-update');
            $results.hide().empty();

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_qa_check',
                    nonce: lfAdmin.nonce,
                    original_id: originalId,
                    translation_id: translationId,
                    source_lang: sourceLang,
                    target_lang: targetLang
                },
                success: function(r) {
                    $btn.removeClass('loading');
                    $btn.find('.dashicons').removeClass('dashicons-update').addClass('dashicons-yes-alt');
                    if (r.success) {
                        LF_Admin.renderQAResults($results, r.data, translationId);
                        $results.slideDown(200);
 // fresh QA results — mark unsaved so beforeunload warns
                        LF_Admin.qaResultsActive = (r.data && r.data.issues && r.data.issues.length > 0);
                    } else {
                        LF_Admin.toast(r.data.message || 'QA check failed.', 'error');
                        LF_Admin.qaResultsActive = false;
                    }
                },
                error: function() {
                    $btn.removeClass('loading');
                    $btn.find('.dashicons').removeClass('dashicons-update').addClass('dashicons-yes-alt');
                    LF_Admin.toast('QA check request failed.', 'error');
                }
            });
        },

        /**
 * Render QA results
 */
        renderQAResults: function($container, data, translationId) {
            var score = data.score || 0;
            var scoreClass = score >= 80 ? 'lf-qa-score-high' : (score >= 60 ? 'lf-qa-score-medium' : 'lf-qa-score-low');

 // dismiss (X) clears the unsaved flag + hides the panel
            var html = '<button type="button" class="lf-qa-dismiss" title="Dismiss" '
                + 'style="float:right;border:0;background:transparent;cursor:pointer;'
                + 'font-size:18px;color:#94a3b8;line-height:1;padding:2px 6px;">&times;</button>';
            html += '<div class="lf-qa-score-circle ' + scoreClass + '">' + score + '</div>';
            if (data.summary) {
                html += '<div class="lf-qa-summary">' + $('<span>').text(data.summary).html() + '</div>';
            }

            var typeLabels = {
                'missing': 'Missing',
                'meaning_changed': 'Meaning',
                'tone_mismatch': 'Tone',
                'grammar': 'Grammar',
                'untranslated_chunk': 'Untranslated',
                'formatting_lost': 'Formatting'
            };

            if (data.issues && data.issues.length > 0) {
                $.each(data.issues, function(i, issue) {
                    html += '<div class="lf-qa-issue">';
                    html += '<div class="lf-qa-issue-header">';
                    html += '<span class="lf-qa-severity lf-qa-severity-' + issue.severity + '">' + issue.severity + '</span>';
                    html += '<span class="lf-qa-issue-type">' + (typeLabels[issue.type] || issue.type) + '</span>';
                    html += '</div>';
                    if (issue.original_segment) {
                        html += '<div class="lf-qa-issue-text"><strong>Original:</strong> ' + $('<span>').text(issue.original_segment).html() + '</div>';
                    }
                    if (issue.translation_segment) {
                        html += '<div class="lf-qa-issue-text"><strong>Translation:</strong> ' + $('<span>').text(issue.translation_segment).html() + '</div>';
                    }
                    if (issue.suggestion) {
                        html += '<div class="lf-qa-issue-text"><strong>Suggestion:</strong> ' + $('<span>').text(issue.suggestion).html() + '</div>';
                        html += '<button type="button" class="lf-qa-fix-btn" data-translation-id="' + translationId + '" data-index="' + i + '"'
                            + ' data-translation-segment="' + $('<span>').text(issue.translation_segment || '').html().replace(/"/g, '&quot;') + '"'
                            + ' data-suggestion="' + $('<span>').text(issue.suggestion).html().replace(/"/g, '&quot;') + '"'
                            + '>' + ((lfAdmin.strings && lfAdmin.strings.fix) || 'Fix') + '</button>';
                    }
                    html += '</div>';
                });
            } else {
                html += '<div class="lf-qa-summary" style="color:#059669;font-weight:600;">No issues found!</div>';
            }

            $container.html(html);
        },

        /**
 * Sync classic post-edit UI with the server response after
 * applying a QA fix. The server already updated the DB (wp_update_post)
 * and returns { updated_field, new_value } — we just need to refresh
 * the inputs the user is looking at so the "Applied!" badge reflects
 * reality and the next Save doesn't clobber the fix with stale text.
 *
 * Covers:
 * - post_title → #title (plus title-prompt class dance)
 * - post_excerpt → #excerpt
 * - post_content → #content textarea + TinyMCE 'content' instance
 * (both Visual and Text modes)
 *
 * Returns true if at least one input was actually updated.
 */
        syncPostEditFromServer: function(data) {
            if (!data || !data.updated_field) return false;
            var v = (data.new_value == null ? '' : String(data.new_value));
            var touched = false;

            if (data.updated_field === 'post_title') {
                var $t = $('#title');
                if ($t.length) {
                    $t.val(v).trigger('input').trigger('change');
                    // WP's "Enter title here" prompt toggles classes; make sure
                    // it doesn't remain visually on top of the real title.
                    $('#title-prompt-text').addClass('screen-reader-text');
                    touched = true;
                }
            } else if (data.updated_field === 'post_excerpt') {
                var $e = $('#excerpt');
                if ($e.length) { $e.val(v).trigger('input').trigger('change'); touched = true; }
            } else if (data.updated_field === 'post_content') {
                // Classic editor — textarea is always the source of truth for
                // the Text tab and the form submission. TinyMCE is a separate
                // iframe that must be updated explicitly.
                var $c = $('#content');
                if ($c.length) { $c.val(v).trigger('input').trigger('change'); touched = true; }
                if (typeof window.tinymce !== 'undefined') {
                    try {
                        var ed = window.tinymce.get('content');
                        if (ed && !ed.isHidden()) {
                            ed.setContent(v);
                            ed.save();            // pushes iframe content → textarea
                            ed.isNotDirty = false; // so the next Save picks it up
                            touched = true;
                        }
                    } catch (err) { /* TinyMCE not ready — textarea alone is enough */ }
                }
                // Block editor (Gutenberg) path — covers new posts where the
                // classic textarea is present but hidden behind the block
                // editor. wp.data exposes an authoritative way to swap content.
                if (typeof window.wp !== 'undefined' && window.wp.data &&
                    window.wp.data.dispatch && window.wp.data.dispatch('core/editor')) {
                    try {
                        window.wp.data.dispatch('core/editor').editPost({ content: v });
                        touched = true;
                    } catch (err) { /* not a block-editor screen */ }
                }
            }

            return touched;
        },

        /**
 * Apply QA fix for a specific issue
 */
        qaFix: function(e) {
            e.preventDefault();
            var $btn = $(this);
            var translationId = $btn.data('translation-id');
            var translationSegment = $btn.data('translation-segment');
            var suggestion = $btn.data('suggestion');

            $btn.prop('disabled', true).text('Applying...');

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_qa_fix',
                    nonce: lfAdmin.nonce,
                    translation_id: translationId,
                    translation_segment: translationSegment,
                    suggestion: suggestion
                },
                success: function(r) {
                    if (r.success) {
 // server updated the DB; push the new value
                        // into whatever editor is on screen before flipping
                        // the badge to "Applied!". If we can't find a target
                        // input we offer a controlled reload so the user sees
                        // the real saved state, instead of a lying badge.
                        var applied = LF_Admin.syncPostEditFromServer(r.data || {});
                        var $issue = $btn.closest('.lf-qa-issue');
                        $btn.text(applied ? 'Applied!' : 'Saved!').css({background: '#059669'});
                        $issue.css({opacity: 0.5}).attr('data-applied', '1');
                        LF_Admin.toast((r.data && r.data.message) || 'Fix applied.');
                        if (!applied) {
                            $issue.find('.lf-qa-reload-hint').remove();
                            var reloadHtml = (lfAdmin.strings && lfAdmin.strings.changeSavedReload) || 'Change saved to translation. <a href="#" class="lf-qa-reload-link" style="color:#0EC49E;font-weight:600;">Refresh editor</a>';
                            $issue.append(
                                $('<p class="lf-qa-reload-hint" style="margin:6px 0 0;font-size:13px;color:#64748b;"></p>').html(reloadHtml)
                            );
                        }
                    } else {
                        $btn.prop('disabled', false).text((lfAdmin.strings && lfAdmin.strings.fix) || 'Fix');
                        LF_Admin.toast((r.data && r.data.message) || 'Fix failed.', 'error');
                    }
                },
                error: function() {
                    $btn.prop('disabled', false).text((lfAdmin.strings && lfAdmin.strings.fix) || 'Fix');
                    LF_Admin.toast('Fix request failed.', 'error');
                }
            });
        },

        unlinkTermTranslation: function(e) {
            e.preventDefault();

            if (!confirm('Unlink this term translation?')) {
                return;
            }

            var $btn = $(this);

            $.ajax({
                url: lfAdmin.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'lf_unlink_term_translation',
                    nonce: lfAdmin.nonce,
                    term_id: $btn.data('term-id'),
                    taxonomy: $btn.data('taxonomy'),
                    language: $btn.data('lang')
                },
                success: function(response) {
                    if (response.success) {
                        LF_Admin.toast(response.data.message || lfAdmin.strings.saved);
                        location.reload();
                    }
                }
            });
        }
    };

    $(document).ready(function() {
        LF_Admin.init();
    });

})(jQuery);
