/**
 * ============================================================================
 * EONSR ADMIN SCRIPT - REFACTORED & OPTIMIZED
 *
 * @package     EONSR_Agent
 * @description Handles Single Post Generation, Image Generation, and Bulk Processing.
 * @version     2.0 (Refactored)
 * ============================================================================
 */

jQuery(function ($) {
    'use strict';

    // ========================================================================
    // [PART 1] SINGLE POST GENERATION LOGIC
    // ========================================================================

    // --- DOM Element Cache (Cached for performance) ---
    const $form                   = $("#aeo-agent-generate-form");
    const $submitBtn              = $form.find('button[type="submit"]');
    const $card                   = $("#aeo-agent-preview-card");
    const $title                  = $("#aeo-agent-preview-title");
    const $kwWrap                 = $("#aeo-agent-preview-keywords");
    const $initialPlaceholder     = $("#aeo-agent-initial-placeholder");
    const $tabsWrapper            = $("#aeo-agent-tabs-wrapper");
    const $tabLinks               = $(".aeo-agent-tab-link");
    const $tabPanels              = $(".aeo-agent-tab-panel");
    const $body                   = $("#aeo-agent-preview-body");
    const $publishForm            = $("#aeo-agent-publish-form");
    const $pubBtn                 = $("#aeo-agent-publish-btn");
    const $previewBtn             = $('#aeo-agent-preview-btn');
    const $genImgBtn              = $("#aeo-agent-generate-images-btn");
    const $imgResults             = $("#aeo-agent-image-results");
    const $featuredPromptTextarea = $("#aeo-agent-featured-prompt");
    const $inContentPromptTextarea= $("#aeo-agent-incontent-prompt");
    const $reviewTabLink          = $tabLinks.filter('[data-tab="review"]');
    const $fullPreviewBody        = $("#aeo-agent-full-preview-body");
    const $scheduleOptions        = $("#aeo-agent-schedule-options");
    const $statusRadios           = $("input[name=post_status_choice]");
    const $scheduleDateInput      = $("input[name=schedule_date]");
    const $scheduleTimeInput      = $("input[name=schedule_time]");
    const $postIDHidden           = $("#post_id");
    const $categoryList           = $('.aeo-agent-category-list');
    const $categoryStatus         = $('#aeo-agent-category-status');
    const $updateContentBtn       = $('#aeo-agent-update-content-btn');
    const $updateStatus           = $('#aeo-agent-update-status');
    const $mainGrid               = $('.aeo-agent-grid');

    // --- State Variables ---
    let loading              = false;
    let updateTimeout        = null;
    let categorySaveTimeout  = null;
    let autoTranslateEnabled = false;
    let currentLanguage      = '';
    let isUnsavedChanges     = false;

    // To track prompt modifications
    let originalFeaturedPrompt  = "";
    let originalInContentPrompt = "";

    // --- Polling Variables ---
    let pollTimeout        = null;
    let currentJobId       = null;
    let currentPollRequest = null;
    let pollCount          = 0;
    let isJobCompleted     = false;
    let completedJobId     = null;

    const maxPolls           = 600;
    const POLL_DELAY_INITIAL = 10000;
    const POLL_DELAY_MID     = 5000;
    const POLL_DELAY_LONG    = 15000;
    let pollDelay            = POLL_DELAY_INITIAL;

    // ========================================================================
    // [SECTION] HELPER FUNCTIONS
    // ========================================================================

    /**
     * Sets the unsaved changes flag and logs status.
     * @param {boolean} status
     */
    function setUnsaved(status) {
        isUnsavedChanges = status;
        console.log(status
            ? '⚠️ [AEO Agent] Unsaved changes detected.'
            : '✅ [AEO Agent] Changes saved/cleared.'
        );
    }

    /**
     * Locks or unlocks the UI elements during processing.
     * @param {boolean} shouldLock
     */
    function lockUi(shouldLock) {
        if (shouldLock) {
            $mainGrid.addClass('aeo-agent-ui-locked');
            $form.find('button[type=submit]').prop('disabled', true);
            $genImgBtn.prop('disabled', true);
            $updateContentBtn.prop('disabled', true);
            $pubBtn.prop('disabled', true);
        } else {
            $mainGrid.removeClass('aeo-agent-ui-locked');
            $form.find('button[type=submit]').prop('disabled', false);

            if ($featuredPromptTextarea.val() && $inContentPromptTextarea.val()) {
                $genImgBtn.prop('disabled', false);
            }

            if ($postIDHidden.val()) {
                $pubBtn.prop('disabled', false);
            }
        }
    }

    /**
     * Toggles the loading spinner overlay.
     * @param {boolean} on
     */
    function setLoading(on) {
        loading = on;
        $card.toggleClass("is-loading", on);

        if (on && !$("#aeo-agent-spinner").length) {
            $("<div/>", {
                id: "aeo-agent-spinner",
                class: "aeo-agent-spinner"
            }).appendTo($card);
        } else if (!on) {
            $("#aeo-agent-spinner").remove();
        }
    }

    /**
     * Renders summary HTML into the summary tab.
     * @param {Object} summaries
     */
    function displaySummaries(summaries) {
        if (!summaries) return;

        const paragraphEl = document.getElementById('aeo-agent-summary-paragraph');
        if (paragraphEl && summaries.paragraph) {
            paragraphEl.innerHTML = `<p style="margin: 0; color: #1d2327;">${summaries.paragraph}</p>`;
        }

        const bulletsEl = document.getElementById('aeo-agent-summary-bullets');
        if (bulletsEl && summaries.bullets && summaries.bullets.length > 0) {
            const bulletHTML = summaries.bullets
                .map(bullet => `<li style="margin-bottom: 8px; color: #1d2327;">${bullet}</li>`)
                .join('');
            bulletsEl.innerHTML = `<ul style="margin: 0; padding-left: 20px;">${bulletHTML}</ul>`;
        }
    }

    /**
     * Validates and corrects the scheduled date/time input.
     * Ensures user cannot select past dates/times.
     */
    function updateScheduleTimeConstraints() {
        if (!$scheduleOptions.is(':visible')) return;

        const now = new Date();
        const todayString = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
        const currentTimeString = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

        $scheduleDateInput.attr('min', todayString);

        if ($scheduleDateInput.val() < todayString) {
            $scheduleDateInput.val(todayString);
        }

        const selectedDate = $scheduleDateInput.val();

        if (selectedDate === todayString) {
            $scheduleTimeInput.attr('min', currentTimeString);
            if ($scheduleTimeInput.val() < currentTimeString) {
                $scheduleTimeInput.val(currentTimeString);
            }
        } else {
            $scheduleTimeInput.removeAttr('min');
        }
    }

    /**
     * Toggles visibility of schedule options based on radio selection.
     */
    function toggleScheduleVisibility() {
        const isVisible = $statusRadios.filter(":checked").val() === "schedule";
        $scheduleOptions.toggleClass("visible", isVisible);

        if (isVisible) {
            updateScheduleTimeConstraints();
        }
    }

    /**
     * Displays a blocking alert for locked actions.
     * @param {string} message
     */
    function showLockPopup(message) {
        if (typeof Swal !== 'undefined') {
            Swal.fire({
                title: 'Thao tác bị chặn!',
                text: message,
                icon: 'warning',
                confirmButtonColor: '#d63638',
                confirmButtonText: 'Tôi đã hiểu',
                allowOutsideClick: false,
                backdrop: true,
                padding: '2em',
                width: '450px'
            });
        } else {
            alert(message);
        }
    }

    /**
     * Synchronizes license usage statistics (Tokens, Posts, Images) from the server.
     */
    function syncLicenseStats() {
        console.log('🔄 [AEO Agent] Syncing license details...');

        // UI Loading effect
        $('#aeo-live-tokens').css('opacity', '0.5');
        $('#aeo-live-usage').css('opacity', '0.5');
        $('#aeo-live-images').css('opacity', '0.5');

        $.post(eonsr_aeo_agent_ajax.ajax_url, {
            action: 'eonsr_aeo_agent_sync_license_details',
            nonce: eonsr_aeo_agent_ajax.nonce
        }).done(function (res) {
            if (res.success && res.data.usage) {
                var u = res.data.usage;
                console.log('✅ [AEO Agent] New Usage Data:', u);

                // 1. Update Token Usage
                if (u.tokenUsage !== undefined) {
                    var rawToken = u.tokenUsage;
                    var formattedToken = new Intl.NumberFormat('en-US').format(rawToken);

                    $('#aeo-live-tokens').text(formattedToken).css({ 'opacity': '1', 'color': '#00a32a', 'font-weight': 'bold' });
                    setTimeout(() => $('#aeo-live-tokens').css('color', ''), 2000);
                }

                // 2. Update Posts Today
                if (u.postsToday !== undefined) {
                    $('#aeo-live-usage').text(u.postsToday).css({ 'opacity': '1', 'color': '#00a32a', 'font-weight': 'bold' });
                    setTimeout(() => $('#aeo-live-usage').css('color', '#2271b1'), 2000);
                }

                // 3. Update Images Generated
                if (u.imagesToday !== undefined) {
                    $('#aeo-live-images').text(u.imagesToday).css({
                        'opacity': '1',
                        'color': '#00a32a',
                        'font-weight': 'bold'
                    });
                    setTimeout(() => $('#aeo-live-images').css('color', '#2271b1'), 2000);
                }
            }
        }).fail(function () {
            console.error('❌ [AEO Agent] Failed to sync details');
            // Reset opacity on error
            $('#aeo-live-tokens, #aeo-live-usage, #aeo-live-images').css('opacity', '1');
        });
    }

    // ========================================================================
    // [SECTION] POLLING LOGIC
    // ========================================================================

    /**
     * Initiates the polling process for a specific job.
     * @param {string} jobId
     */
    function startPolling(jobId) {
        if (completedJobId === jobId || isJobCompleted) return;

        currentJobId = jobId;
        pollCount = 0;
        pollDelay = POLL_DELAY_INITIAL;
        isJobCompleted = false;
        stopPolling();

        doPoll();
    }

    /**
     * Stops current polling process and aborts pending requests.
     */
    function stopPolling() {
        if (pollTimeout) {
            clearTimeout(pollTimeout);
            pollTimeout = null;
        }

        if (currentPollRequest && currentPollRequest.readyState !== 4) {
            currentPollRequest.abort();
            currentPollRequest = null;
        }

        pollCount = 0;
    }

    /**
     * Executes a single poll request recursively.
     */
    function doPoll() {
        if (!currentJobId || isJobCompleted) return;

        pollCount++;

        // Timeout check
        if (pollCount > maxPolls) {
            stopPolling();
            $title.text("Quá thời gian chờ");
            $body.html("<div class='notice notice-error'><p>⏱️ Timeout</p></div>");
            setLoading(false);
            $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
            setUnsaved(false);
            return;
        }

        // Adjust poll delay (Adaptive Polling)
        if (pollCount > 5) pollDelay = POLL_DELAY_MID;
        if (pollCount > 10) pollDelay = POLL_DELAY_LONG;

        // Abort previous request
        if (currentPollRequest && currentPollRequest.readyState !== 4) {
            currentPollRequest.abort();
        }

        // Send Poll Request
        currentPollRequest = $.post(eonsr_aeo_agent_ajax.ajax_url, {
            action: 'eonsr_aeo_agent_poll_job_status',
            nonce: eonsr_aeo_agent_ajax.poll_nonce,
            job_id: currentJobId
        })
        .done(handlePollSuccess)
        .fail(scheduleNextPoll)
        .always(() => {
            currentPollRequest = null;
        });
    }

    /**
     * Handles successful poll response.
     * @param {Object} response
     */
    function handlePollSuccess(response) {
        if (isJobCompleted || completedJobId === currentJobId) return;

        if (!response || !response.success) {
            handlePollError(response);
            return;
        }

        const data = response.data;
        if (!data || !data.status) {
            scheduleNextPoll();
            return;
        }

        switch (data.status) {
            case 'completed':
                handleCompletedStatus(data);
                break;
            case 'failed':
                handleFailedStatus(data);
                break;
            case 'queued':
            case 'processing':
                handleProcessingStatus(data);
                break;
            default:
                scheduleNextPoll();
        }
    }

    /**
     * Handles specific poll errors (e.g. Job Not Found).
     * @param {Object} response
     */
    function handlePollError(response) {
        if (response && response.data && response.data.message && response.data.message.includes('not found')) {
            stopPolling();
            $title.text("Lỗi");
            $body.html("<div class='notice notice-error'><p>❌ Job không tìm thấy</p></div>");
            setLoading(false);
            $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
            setUnsaved(false);
            return;
        }
        scheduleNextPoll();
    }

    /**
     * Logic when job is successfully completed.
     * @param {Object} data
     */
    function handleCompletedStatus(data) {
        // Update Summary Tab
        const summaryTab = document.querySelector('[data-tab="summary"]');
        if (data.summaries && data.summaries.paragraph) {
            displaySummaries(data.summaries);
            summaryTab.classList.remove('disabled');
        } else {
            summaryTab.style.display = 'none';
        }

        if (!data.post_id) {
            stopPolling();
            $title.text("Lỗi");
            $body.html("<div class='notice notice-error'><p>❌ Thiếu post_id</p></div>");
            setLoading(false);
            $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
            setUnsaved(false);
            return;
        }

        isJobCompleted = true;
        completedJobId = currentJobId;
        stopPolling();
        handleCompletedJob(data);
    }

    /**
     * Logic when job fails.
     * @param {Object} data
     */
    function handleFailedStatus(data) {
        stopPolling();
        const errorMsg = data.error || data.message || 'Lỗi không xác định';
        $title.text("Có lỗi xảy ra");
        $body.html(`<div class='notice notice-error'><p>❌ ${errorMsg}</p></div>`);
        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
        setUnsaved(false);

        currentJobId = null;
    }

    /**
     * Updates UI during processing state.
     * @param {Object} data
     */
    function handleProcessingStatus(data) {
        const statusMsg = data.status === 'queued'
            ? `⏳ Đang chờ... Vị trí: ${data.queuePosition || '?'}`
            : '🚀 Đang tạo bài viết... Khoảng 60 giây';

        $body.html(`<p class='aeo-agent-help'>${statusMsg}</p>`);
        scheduleNextPoll();
    }

    /**
     * Schedules the next poll execution.
     */
    function scheduleNextPoll() {
        if (currentJobId && !isJobCompleted) {
            pollTimeout = setTimeout(doPoll, pollDelay);
        }
    }

    /**
     * Populates form and UI with completed job data.
     * @param {Object} data
     */
    function handleCompletedJob(data) {
        $postIDHidden.val(data.post_id);

        if (data.preview_url) {
            $previewBtn.attr('href', data.preview_url).show();
        }

        $title.text(data.focus_keyphrase || data.title);

        // Update form fields
        const formFields = {
            preview_title: data.title || "",
            preview_slug: data.slug || "",
            preview_tags: data.tags ? data.tags.join(", ") : "",
            preview_meta_desc: data.meta_description || "",
            preview_focus_kw: data.focus_keyphrase || ""
        };

        Object.entries(formFields).forEach(([name, value]) => {
            $publishForm.find(`input[name=${name}]`).val(value);
        });

        // Update CSS styles
        $("#aeo-agent-preview-styles").remove();
        if (data.content_style) {
            $('<style id="aeo-agent-preview-styles">' + data.content_style + '</style>').appendTo('head');
        }

        // Update content body
        const previewContent = '<h1>' + data.title + '</h1>' + (data.content_body || "");
        $body.html(previewContent);

        // Update keywords/tags
        $kwWrap.empty();
        if (Array.isArray(data.tags) && data.tags.length) {
            data.tags.forEach(tag => {
                $("<span/>", {
                    class: "aeo-agent-badge",
                    text: tag
                }).appendTo($kwWrap);
            });
        }

        // Update prompts
        $featuredPromptTextarea.val(data.featured_image_prompt || "");
        $inContentPromptTextarea.val(data.in_content_image_prompt || "");

        // Save original prompts for change detection
        originalFeaturedPrompt = data.featured_image_prompt || "";
        originalInContentPrompt = data.in_content_image_prompt || "";

        // Enable buttons & UI
        $genImgBtn.prop("disabled", false);
        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');

        $('#aeo-agent-image-results').empty(); // Clear old images
        $('#btn-gen-all').show();              // Show "Generate All"
        $('#aeo-regen-buttons').hide();        // Hide regen buttons

        // Mark as unsaved
        setUnsaved(true);

        // Scroll to card
        $('html, body').animate({
            scrollTop: $card.offset().top - 100
        }, 500);

        currentJobId = null;
        completedJobId = null;
        syncLicenseStats();
    }

    // ========================================================================
    // [SECTION] IMAGE GENERATION
    // ========================================================================

    /**
     * Triggers the image generation AJAX process.
     * @param {string} targetType - 'all', 'featured', or 'in_content'
     */
    function triggerImageGeneration(targetType) {
        if (loading) return;

        const post_id = $postIDHidden.val();
        if (!post_id) {
            alert("Lỗi: Không tìm thấy ID bài nháp");
            return;
        }

        const featuredPrompt = $featuredPromptTextarea.val().trim();
        const inContentPrompt = $inContentPromptTextarea.val().trim();
        const useLogo = $('#use_custom_logo').is(':checked') ? 1 : 0;

        // Validation
        if (targetType === 'featured' && !featuredPrompt) { alert('Thiếu Prompt Thumbnail.'); return; }
        if (targetType === 'in_content' && !inContentPrompt) { alert('Thiếu Prompt Nội dung.'); return; }
        if (targetType === 'all' && (!featuredPrompt || !inContentPrompt)) { alert('Thiếu Prompt.'); return; }

        setLoading(true);
        setUnsaved(true);

        $('#btn-gen-all').hide();
        $('#aeo-regen-buttons').hide();

        const $resultsContainer = $('#aeo-agent-image-results');

        // Helper HTML Loading template
        const getLoadingHtml = (text) => `
            <div class="aeo-loading-wrap" style="text-align:center; padding: 40px; background:#f9f9f9; border-radius:8px; border:1px dashed #ccc; height:100%; display:flex; flex-direction:column; justify-content:center; align-items:center;">
                <span class="dashicons dashicons-update" style="font-size:32px; height:32px; width:32px; animation:spin 1.2s infinite linear; color:#2271b1; display:block; margin-bottom:15px;"></span>
                <strong style="font-size:14px; color:#2271b1; display:block; margin-bottom:5px;">${text}</strong>
                <span style="color:#666; font-size:13px;">AI đang vẽ...</span>
            </div>
        `;

        // Loading UI Logic
        if (targetType === 'all') {
            $resultsContainer.html(getLoadingHtml('📸 Đang tạo cả 2 ảnh...'));
        }
        else if (targetType === 'featured') {
            const $featBox = $('#img-res-featured');
            if ($featBox.length > 0) $featBox.html(getLoadingHtml('🖼️ Đang vẽ lại Thumbnail...'));
            else $resultsContainer.html(getLoadingHtml('🖼️ Đang tạo Thumbnail...'));
        }
        else if (targetType === 'in_content') {
            const $contentBox = $('#img-res-content');
            if ($contentBox.length > 0) $contentBox.html(getLoadingHtml('📝 Đang vẽ lại ảnh bài viết...'));
            else $resultsContainer.html(getLoadingHtml('📝 Đang tạo ảnh bài viết...'));
        }

        $tabLinks.filter('[data-tab="images"]').click();

        $.post(eonsr_aeo_agent_ajax.ajax_url, {
            action: "eonsr_aeo_agent_generate_images_ajax",
            nonce: eonsr_aeo_agent_ajax.generate_images_nonce,
            post_id: post_id,
            featured_prompt: featuredPrompt,
            in_content_prompt: inContentPrompt,
            use_custom_logo: useLogo,
            target_type: targetType
        })
        .done(function(res) {
            if (res.success) {
                handleImageSuccess(res, targetType);
            } else {
                handleImageGenerationError(res, targetType);
            }
        })
        .fail(function(xhr) {
            let msg = "Lỗi kết nối máy chủ";
            try { msg = JSON.parse(xhr.responseText).data.message; } catch(e){}
            handleImageGenerationError({ data: { message: msg } }, targetType);
        })
        .always(function() {
            setLoading(false);
        });
    }

    /**
     * Handles successful image generation.
     * @param {Object} res
     * @param {string} targetType
     */
    function handleImageSuccess(res, targetType) {
        if (!res || !res.success) {
            handleImageGenerationError(res);
            return;
        }

        const d = res.data;
        const $resultsContainer = $("#aeo-agent-image-results");

        // 1. Create containers if not exists
        if ($resultsContainer.find('#img-res-featured').length === 0) {
            $resultsContainer.html(`
                <div id="img-res-featured" style="margin-bottom: 20px; text-align: center;"></div>
                <div id="img-res-content" style="margin-bottom: 20px; text-align: center;"></div>
            `);
        }

        // 2. Update Thumbnail
        if (d.featuredImage) {
            $('#img-res-featured').html(`
                <h4 style="margin:5px 0; color:#2271b1;">Ảnh đại diện (Thumbnail)</h4>
                <img src="data:image/png;base64,${d.featuredImage}" style="max-width:100%; border-radius:8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);"/>
            `);
        }

        // 3. Update In-Content Image
        if (d.inContentImage) {
            $('#img-res-content').html(`
                <h4 style="margin:5px 0; color:#2271b1;">Ảnh trong bài viết</h4>
                <img src="data:image/png;base64,${d.inContentImage}" style="max-width:100%; border-radius:8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);"/>
            `);
        }

        // Update Meta (Title, Tags)
        if (d.updated_tags) $publishForm.find("input[name=preview_tags]").val(d.updated_tags.join(", "));
        if (d.updated_title) $publishForm.find("input[name=preview_title]").val(d.updated_title);

        // Update Review Tab
        updateReviewTab(d);

        // Button Control
        $('#btn-gen-all').hide();
        $('#aeo-regen-buttons').css('display', 'flex');
        $('.btn-gen-single').prop('disabled', false).removeClass('disabled');

        if (autoTranslateEnabled) triggerAutoTranslate();
        syncLicenseStats();
    }

    /**
     * Handles image generation errors with specific UI placement.
     * @param {Object} res
     * @param {string} targetType
     */
    function handleImageGenerationError(res, targetType) {
        const msg = (res.data && res.data.message) ? res.data.message : "Lỗi không xác định";
        const $resultsContainer = $('#aeo-agent-image-results');

        const errorHtml = `
            <div class='notice notice-error inline' style="padding:15px; border-left:4px solid #d63638; background:#fff; box-shadow:0 1px 1px rgba(0,0,0,.04); height:100%; display:flex; flex-direction:column; justify-content:center;">
                <p style="margin:0; font-size:13px; color:#d63638; line-height:1.4;">
                    <span class="dashicons dashicons-warning" style="vertical-align:middle; margin-right:5px;"></span>
                    <strong>Thất bại:</strong> ${msg}
                </p>
            </div>`;

        // Handle Locked Tab error
        if (res.data && res.data.code === 'LOCKED_SINGLE_TAB') {
            showLockPopup(msg);
        }

        // Placement Logic
        if (targetType === 'featured') {
            $('#img-res-featured').html(errorHtml);
        }
        else if (targetType === 'in_content') {
            $('#img-res-content').html(errorHtml);
        }
        else {
            if ($('#img-res-featured').length > 0) {
                $resultsContainer.prepend(errorHtml);
                $resultsContainer.find('.aeo-loading-wrap').remove();
            } else {
                $resultsContainer.html(errorHtml);
            }
        }

        // Restore Buttons
        const hasFeatured = $('#img-res-featured img').length > 0;
        const hasContent = $('#img-res-content img').length > 0;

        if (!hasFeatured && !hasContent && targetType === 'all') {
            $('#btn-gen-all').show();
            $('#aeo-regen-buttons').hide();
        } else {
            $('#btn-gen-all').hide();
            $('#aeo-regen-buttons').css('display', 'flex');
        }

        $('.btn-gen-single').prop('disabled', false).removeClass('disabled');
    }

    /**
     * Updates the Review Tab with the newly generated images.
     * @param {Object} imageData
     */
    function updateReviewTab(imageData) {
        $fullPreviewBody.empty();

        // Clone content from edit body
        const $clonedContent = $body.contents().clone(true, true);
        const $wrapper = $('<div>').append($clonedContent);

        // 1. Insert/Replace In-Content Image
        if (imageData.inContentImage) {
            const inContentImageHtml =
                '<figure id="gemini-in-content-image" style="margin: 2em 0; text-align:center;">' +
                '<img src="data:image/png;base64,' + imageData.inContentImage + '" alt="Ảnh minh họa" style="max-width:100%; height:auto; border-radius:4px;">' +
                '<figcaption style="font-style:italic; color:#666; margin-top:5px;">' +
                ($inContentPromptTextarea.val().substring(0, 80) + '...') +
                '</figcaption></figure>';

            const $placeholder = $wrapper.find('#gemini-in-content-image');
            if ($placeholder.length > 0) {
                $placeholder.replaceWith(inContentImageHtml);
            } else {
                const $paragraphs = $wrapper.find('p');
                if ($paragraphs.length >= 3) {
                    $paragraphs.eq(2).after(inContentImageHtml);
                } else {
                    $wrapper.append(inContentImageHtml);
                }
            }
        }

        // 2. Insert/Replace Featured Image
        if (imageData.featuredImage) {
            $wrapper.find('.featured-image').remove();
            const $featuredImg = $(
                '<figure class="featured-image" style="margin-bottom:30px;">' +
                '<img src="data:image/png;base64,' + imageData.featuredImage + '" alt="Ảnh đại diện" style="width:100%; height:auto; border-radius:8px;">' +
                '</figure>'
            );
            $wrapper.prepend($featuredImg);
        }

        // Append to review body
        const dest = $fullPreviewBody[0];
        $wrapper.contents().each(function () {
            dest.appendChild(this);
        });

        // Update UI states
        $body.prop('contenteditable', false);
        $fullPreviewBody.prop('contenteditable', true);
        $reviewTabLink.removeClass('disabled');
        $pubBtn.prop('disabled', false);
    }

    // --- Image Generation Event Listeners ---

    // Button: Generate All
    $(document).on('click', '#btn-gen-all', function(e) {
        e.preventDefault();
        verifyAndTriggerGeneration('all');
    });

    // Button: Generate Single (Featured or Content)
    $(document).on('click', '.btn-gen-single', function(e) {
        e.preventDefault();
        const type = $(this).data('target');
        verifyAndTriggerGeneration(type);
    });

    // ========================================================================
    // [SECTION] AUTO-TRANSLATE LOGIC
    // ========================================================================

    /**
     * Triggers the auto-translate process after post publication.
     */
    function triggerAutoTranslate() {
        const $successNotice = $('#aeo-agent-post-publish-success');
        const $translationStatus = $('#aeo-agent-translation-status');

        if (!$successNotice.length || !$translationStatus.length) {
            return;
        }

        const post_id = $successNotice.data('post-id');
        if (!post_id) return;

        const source_language = $('#language').val() || 'Vietnamese';

        lockUi(true);

        const data = {
            action: 'eonsr_aeo_agent_auto_translate_post',
            nonce: eonsr_aeo_agent_ajax.auto_translate_nonce,
            post_id: post_id,
            source_language: source_language
        };

        console.log('📤 [AEO Agent] Sending auto-translate request...');

        $.post(eonsr_aeo_agent_ajax.ajax_url, data)
            .done(handleAutoTranslateSuccess)
            .fail(handleAutoTranslateError)
            .always(() => {
                lockUi(false);
            });
    }

    /**
     * Handles successful translation initiation.
     * @param {Object} response
     */
    function handleAutoTranslateSuccess(response) {
        console.log('✅ [AEO Agent] Translate Response:', response);

        const $statusText = $('#aeo-agent-translation-status > p');
        const $resultsContainer = $('#aeo-agent-translation-results');

        $('.spinner', $statusText).removeClass('is-active');

        if (response.success) {
            const responseData = response.data;
            const targetLang = responseData.targetLanguage || 'ngôn ngữ đích';

            $statusText.html('<strong style="color: #00a32a;">✅ Đã thêm vào hàng đợi</strong>');

            const resultHtml =
                '<div style="background: #f0f6fc; border-left: 4px solid #72aee6; padding: 12px; margin-top: 10px; border-radius: 4px;">' +
                '<p style="margin: 0; color: #1d2327; font-size: 14px;">' +
                'Hệ thống đang tạo bài viết <strong>Tiếng ' + targetLang + '</strong> trong nền.' +
                '</p>' +
                '<p style="margin: 5px 0 0 0; font-size: 13px; color: #646970;">' +
                '🚀 Quá trình này diễn ra tự động và đăng sau sau hoành thành. Bạn có thể tắt trang này ngay bây giờ.' +
                '</p>' +
                '</div>';

            $resultsContainer.html(resultHtml);
        } else {
            console.error('❌ [AEO Agent] Translate Error:', response);
            $statusText.html('<strong style="color: #d63638;">❌ Lỗi khởi tạo</strong>');

            const errorMsg = (response.data && response.data.message)
                ? response.data.message
                : 'Không thể gửi lệnh dịch.';

            $resultsContainer.html(`<p style="color: #d63638; margin-top: 5px;">${errorMsg}</p>`);
        }
    }

    /**
     * Handles translation errors.
     * @param {Object} xhr
     */
    function handleAutoTranslateError(xhr) {
        console.log('❌ [AEO Agent] AJAX Fail:', xhr.status, xhr.responseText);

        let json = xhr.responseJSON;
        if (!json && xhr.responseText) {
            try {
                json = JSON.parse(xhr.responseText);
            } catch (e) {
                console.error('JSON Parse error');
            }
        }

        const lockMsg = (json && json.data && json.data.message)
            ? json.data.message
            : "Bạn đang có một bài viết đang được tạo ở tab khác. Vui lòng đợi.";

        if (xhr.status === 429 || (json && json.data && json.data.code === 'LOCKED_SINGLE_TAB')) {
            showLockPopup(lockMsg);
            $title.text("Tạm dừng tác vụ");
            $body.html(`<div class='notice notice-warning' style='margin-top:10px'><p>⛔ ${lockMsg}</p></div>`);
        } else {
            $title.text("Có lỗi xảy ra");
            const errorMsg = (json && json.data && json.data.message)
                ? json.data.message
                : `Lỗi kết nối máy chủ (${xhr.status})`;
            $body.html(`<div class='notice notice-error'><p>${errorMsg}</p></div>`);
        }

        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
        setUnsaved(false);
    }

    /**
     * Verifies if the prompt was modified and asks for user confirmation.
     * @param {string} targetType
     */
    function verifyAndTriggerGeneration(targetType) {
        let isModified = false;

        const currentFeatured = $featuredPromptTextarea.val().trim();
        const currentInContent = $inContentPromptTextarea.val().trim();

        if (targetType === 'featured') {
            if (currentFeatured !== originalFeaturedPrompt.trim()) isModified = true;
        }
        else if (targetType === 'in_content') {
            if (currentInContent !== originalInContentPrompt.trim()) isModified = true;
        }
        else if (targetType === 'all') {
            if (currentFeatured !== originalFeaturedPrompt.trim() || currentInContent !== originalInContentPrompt.trim()) {
                isModified = true;
            }
        }

        // Case 1: No change -> Run immediately
        if (!isModified) {
            triggerImageGeneration(targetType);
            return;
        }

        // Case 2: Changed -> Show Warning
        Swal.fire({
            title: '⚠️ Phát hiện thay đổi Prompt',
            html: `
                <p style="margin-bottom:10px;">Bạn đã chỉnh sửa câu lệnh tạo ảnh so với đề xuất của AI.</p>
                <ul style="text-align:left; font-size:13px; color:#d63638; background:#fff5f5; padding:10px 15px; border-radius:4px; border:1px solid #ffcaca;">
                    <li>Chúng tôi <strong>không chịu trách nhiệm</strong> về chất lượng ảnh khi prompt bị thay đổi.</li>
                    <li>Ảnh có thể bị lỗi, méo mó hoặc không đúng nội dung nếu prompt sai ngữ pháp.</li>
                </ul>
                <p style="margin-top:10px; font-size:14px;">Bạn muốn tiếp tục hay khôi phục lại gốc?</p>
            `,
            icon: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#2271b1',
            cancelButtonColor: '#d63638',
            confirmButtonText: 'Tôi hiểu, Vẫn tạo ảnh',
            cancelButtonText: 'Khôi phục Prompt gốc',
            reverseButtons: true
        }).then((result) => {
            if (result.isConfirmed) {
                // User accepts risk
                triggerImageGeneration(targetType);
            } else if (result.dismiss === Swal.DismissReason.cancel) {
                // User restores original prompt
                if (targetType === 'featured') {
                    $featuredPromptTextarea.val(originalFeaturedPrompt);
                }
                else if (targetType === 'in_content') {
                    $inContentPromptTextarea.val(originalInContentPrompt);
                }
                else if (targetType === 'all') {
                    $featuredPromptTextarea.val(originalFeaturedPrompt);
                    $inContentPromptTextarea.val(originalInContentPrompt);
                }

                Swal.fire({
                    icon: 'success',
                    title: 'Đã khôi phục',
                    text: 'Câu lệnh đã trở về mặc định của hệ thống.',
                    timer: 1500,
                    showConfirmButton: false
                });
            }
        });
    }

    /**
     * Triggers Polylang translation (Legacy method).
     */
    function triggerPolylangTranslation() {
        const $successNotice = $('#aeo-agent-post-publish-success');
        if (!$successNotice.length || !$('#aeo-agent-translation-status').length) {
            return;
        }

        const post_id = $successNotice.data('post-id');
        if (!post_id) return;

        const $resultsContainer = $('#aeo-agent-translation-results');
        const $statusText = $('#aeo-agent-translation-status > p');

        lockUi(true);

        const data = {
            action: 'eonsr_aeo_agent_polylang_translate_ajax',
            nonce: eonsr_aeo_agent_ajax.translate_nonce,
            post_id: post_id
        };

        $.post(eonsr_aeo_agent_ajax.ajax_url, data)
            .done(function (res) {
                $statusText.html('<strong>Các ngôn ngữ khác sẽ được dịch sớm</strong>');

                if (res.success && Array.isArray(res.data)) {
                    if (res.data.length === 0) {
                        $resultsContainer.append('<p>ℹ️ Không có ngôn ngữ khác</p>');
                    } else {
                        res.data.forEach(function (result) {
                            const cssClass = result.success ? 'color: #1e8465;' : 'color: #d63638;';
                            const icon = result.success ? '✅' : '❌';
                            $resultsContainer.append(`<p style="${cssClass}">${icon} ${result.message}</p>`);
                        });
                    }
                }
            })
            .always(() => {
                lockUi(false);
            });
    }

    // ========================================================================
    // [SECTION] MAIN EVENT HANDLERS
    // ========================================================================

    // Prevent accidental close/reload
    window.addEventListener('beforeunload', function (e) {
        if (loading || isUnsavedChanges) {
            e.preventDefault();
            e.returnValue = 'Bạn có chắc chắn muốn rời đi? Dữ liệu chưa lưu sẽ bị mất.';
            return e.returnValue;
        }
    });

    // Handle Form Submit: Generate Text
    $form.on("submit", function (e) {
        e.preventDefault();
        if (loading) return;

        // Capture auto-translate state
        autoTranslateEnabled = $('#auto_translate').is(':checked');
        currentLanguage = $('#language').val();

        console.log('[AEO Agent] Auto-translate:', autoTranslateEnabled);
        console.log('[AEO Agent] Language:', currentLanguage);

        // Reset states
        isJobCompleted = false;
        completedJobId = null;
        currentJobId = null;
        stopPolling();

        // Update UI
        $submitBtn.prop('disabled', true).text('Đang thêm vào hàng đợi...');
        setLoading(true);
        setUnsaved(true);

        $title.text("Đang khởi tạo...");
        $kwWrap.empty();
        $initialPlaceholder.hide();
        $tabsWrapper.show();
        $tabLinks.filter('[data-tab="content"]').removeClass('disabled').click();
        $tabLinks.filter('[data-tab="images"]').removeClass('disabled');
        $body.html("<p class='aeo-agent-help'>⏳ Đang thêm vào hàng đợi...</p>");
        $reviewTabLink.addClass('disabled');
        $fullPreviewBody.html('<p style="text-align:center;">Hình ảnh sẽ được ghép vào đây sau khi tạo thành công.</p>').prop('contenteditable', false);
        $body.prop('contenteditable', true);
        $pubBtn.prop("disabled", true);
        $previewBtn.hide();
        $genImgBtn.prop("disabled", true);
        $imgResults.empty();
        $postIDHidden.val('');
        $categoryList.find('input[type=checkbox]').prop('checked', false);
        $updateContentBtn.prop('disabled', true);
        $updateStatus.text('');

        // Prepare data
        const data = $form.serializeArray();
        data.push(
            { name: "action", value: "eonsr_aeo_agent_generate_ajax" },
            { name: "nonce", value: eonsr_aeo_agent_ajax.generate_text_nonce }
        );

        // Send AJAX request
        $.post(eonsr_aeo_agent_ajax.ajax_url, data)
            .done(handleTextGenerationSuccess)
            .fail(handleTextGenerationError)
            .always(() => {
                lockUi(false);
            });
    });

    /**
     * Handles text generation AJAX success.
     */
    function handleTextGenerationSuccess(res) {
        if (!res || !res.success) {
            const msg = (res.data && res.data.message) ? res.data.message : "Lỗi";

            if (res.data && res.data.code === 'LOCKED_SINGLE_TAB') {
                showLockPopup(msg);
                $title.text("Tạm dừng tác vụ");
                $body.html(`<div class='notice notice-warning' style='margin-top:10px'><p>⛔ ${msg}</p></div>`);
            } else {
                $title.text("Có lỗi xảy ra");
                $body.html(`<div class='notice notice-error'><p>${msg}</p></div>`);
            }

            setLoading(false);
            $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
            setUnsaved(false);
            return;
        }

        const d = res.data;
        if (d.usage) {
            updateLiveUsageUI(d.usage);
        }

        // Start Polling
        if (d.jobId) {
            $title.text("Đã thêm vào hàng đợi");
            $body.html("<p class='aeo-agent-help'>✅ Đang xử lý...</p>");

            startPolling(d.jobId);

            $submitBtn.text('Đang xử lý...');
        }
    }

    /**
     * Updates quota usage UI (Tokens, Posts).
     */
    function updateLiveUsageUI(usage) {
        console.log('🔄 [AEO Agent] Live Usage Update:', usage);
        if (!usage) return;

        if (usage.postsToday !== undefined) {
            const $quotaEl = $('#aeo-live-usage');
            if ($quotaEl.length) {
                $quotaEl.text(usage.postsToday).css('color', '#d63638').css('font-weight', 'bold');
                setTimeout(() => $quotaEl.css('color', ''), 1500);
            }
        }

        if (usage.tokenUsage !== undefined) {
            const $tokenEl = $('#aeo-live-tokens');
            if ($tokenEl.length) {
                const formattedToken = new Intl.NumberFormat('en-US').format(usage.tokenUsage);
                $tokenEl.text(formattedToken).css('color', '#d63638').css('font-weight', 'bold');
                setTimeout(() => $tokenEl.css('color', ''), 1500);
            }
        }
    }

    /**
     * Handles text generation AJAX error.
     */
    function handleTextGenerationError(xhr) {
        console.log('❌ [AEO Agent] AJAX Fail:', xhr.status, xhr.responseText);

        let json = xhr.responseJSON;
        if (!json && xhr.responseText) {
            try { json = JSON.parse(xhr.responseText); } catch (e) { console.error('JSON Parse error'); }
        }

        const lockMsg = (json && json.data && json.data.message)
            ? json.data.message
            : "Bạn đang có một bài viết đang được tạo ở tab khác. Vui lòng đợi.";

        if (xhr.status === 429 || (json && json.data && json.data.code === 'LOCKED_SINGLE_TAB')) {
            showLockPopup(lockMsg);
            $title.text("Tạm dừng tác vụ");
            $body.html(`<div class='notice notice-warning' style='margin-top:10px'><p>⛔ ${lockMsg}</p></div>`);
        } else {
            $title.text("Có lỗi xảy ra");
            const errorMsg = (json && json.data && json.data.message)
                ? json.data.message
                : `Lỗi kết nối máy chủ (${xhr.status})`;
            $body.html(`<div class='notice notice-error'><p>${errorMsg}</p></div>`);
        }

        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
        setUnsaved(false);
    }

    // Handle Publish Form Submit
    $publishForm.on("submit", function () {
        const h1_text = $body.find('h1:first').text();
        if (h1_text) {
            $(this).find("input[name=preview_title]").val(h1_text);
        }

        setUnsaved(false);
        loading = false;
    });

    // Detect Content Edits
    $body.add($fullPreviewBody).on('input', function () {
        if ($postIDHidden.val()) {
            $updateContentBtn.prop('disabled', false);
            setUnsaved(true);
        }
    });

    // Handle Content Update Button
    $updateContentBtn.on('click', function () {
        const post_id = $postIDHidden.val();
        if (!post_id || $(this).is(':disabled')) return;

        $(this).prop('disabled', true);
        $updateStatus.text('Đang cập nhật...').css('color', '#666');
        clearTimeout(updateTimeout);

        const activeTabLink = $tabLinks.filter('.active');
        const activeTabName = activeTabLink.data('tab');
        const contentToUpdate = (activeTabName === 'review')
            ? $fullPreviewBody.html()
            : $body.html();

        const data = {
            action: 'eonsr_aeo_agent_update_content_ajax',
            nonce: eonsr_aeo_agent_ajax.update_content_nonce,
            post_id: post_id,
            content: contentToUpdate,
            active_tab: activeTabName
        };

        $.post(eonsr_aeo_agent_ajax.ajax_url, data)
            .done(function (res) {
                if (res.success) {
                    $updateStatus.text('Đã cập nhật!').css('color', '#1e8465');
                } else {
                    $updateStatus.text('Lỗi!').css('color', '#d63638');
                }
                $updateContentBtn.prop('disabled', false);
            })
            .always(function () {
                updateTimeout = setTimeout(() => {
                    $updateStatus.text('');
                }, 3000);
            });
    });

    // Handle Category Changes
    $categoryList.on('change', 'input[type=checkbox]', function () {
        const post_id = $postIDHidden.val();
        if (!post_id) return;

        clearTimeout(categorySaveTimeout);
        $categoryStatus.text('Đang lưu...').css('color', '#666');

        const selectedCategories = $categoryList
            .find('input:checked')
            .map(function () { return $(this).val(); })
            .get();

        const data = {
            action: 'eonsr_aeo_agent_update_categories_ajax',
            nonce: eonsr_aeo_agent_ajax.update_categories_nonce,
            post_id: post_id,
            categories: selectedCategories
        };

        $.post(eonsr_aeo_agent_ajax.ajax_url, data)
            .done(function (res) {
                if (res.success) {
                    $categoryStatus.text('Đã lưu!').css('color', '#1e8465');
                } else {
                    $categoryStatus.text('Lỗi!').css('color', '#d63638');
                }
            })
            .always(function () {
                categorySaveTimeout = setTimeout(() => {
                    $categoryStatus.text('');
                }, 2500);
            });
    });

    // Handle Tab Switching
    $tabLinks.on('click', function (e) {
        e.preventDefault();
        if ($(this).hasClass('disabled')) return;

        const tabId = $(this).data('tab');
        $tabLinks.removeClass('active');
        $(this).addClass('active');
        $tabPanels.removeClass('active');
        $('#aeo-agent-tab-' + tabId).addClass('active');
    });

    // Prevent Link Clicks in Preview
    $body.add($fullPreviewBody).on('click', function (e) {
        const $link = $(e.target).closest('a');
        if ($link.length > 0 && $link.attr('href')) {
            e.preventDefault();
            e.stopImmediatePropagation();
            window.open($link.attr('href'), '_blank', 'noopener,noreferrer');
        }
    });

    // General Image Generation Button
    $genImgBtn.on("click", function(e) {
        e.preventDefault();
        triggerImageGeneration('all');
    });

    // Schedule Inputs
    $statusRadios.on("change", toggleScheduleVisibility);
    $scheduleDateInput.on("change", updateScheduleTimeConstraints);

    // Cleanup on Unload
    $(window).on('beforeunload', function () {
        if (pollTimeout || currentPollRequest) {
            stopPolling();
        }
    });

    // ========================================================================
    // [SECTION] INITIALIZATION
    // ========================================================================

    $(document).ready(function () {
        console.log('🔍 [AEO Agent] Document ready, checking for auto-translate trigger');

        // Legacy Auto Translate Trigger
        if ($('#aeo-agent-translation-status').length > 0) {
            console.log('✅ [AEO Agent] Translation status div found, will trigger in 500ms');
            setTimeout(function () {
                console.log('⏰ [AEO Agent] Timeout fired, calling triggerAutoTranslate');
                triggerAutoTranslate();
            }, 500);
        } else {
            console.log('ℹ️ [AEO Agent] No translation status div found');
        }

        // Auto Resume Session Check
        checkActiveSession();
        syncLicenseStats();
    });

    // ========================================================================
    // [SECTION] SESSION & HEARTBEAT
    // ========================================================================

    $(document).ready(function () {
        checkActiveSession();

        // Heartbeat: Check every 5s if page is idle
        setInterval(function() {
            if (!loading && !currentJobId) {
                $.post(eonsr_aeo_agent_ajax.ajax_url, {
                    action: 'eonsr_aeo_agent_check_active_session',
                    nonce: eonsr_aeo_agent_ajax.check_active_nonce
                }).done(function(res) {
                    if (res.success && res.data.has_active_job) {
                        console.log("⚠️ [AEO Agent] Detected job from another tab via Heartbeat!");
                        checkActiveSession();
                    }
                });
            }
        }, 5000);
    });

    /**
     * Checks if there is an active session on the server and restores UI.
     */
    function checkActiveSession() {
        if ($form.length === 0) return;
        if (loading) return;

        $.post(eonsr_aeo_agent_ajax.ajax_url, {
            action: 'eonsr_aeo_agent_check_active_session',
            nonce: eonsr_aeo_agent_ajax.check_active_nonce
        }).done(function(res) {
            if (res.success && res.data.has_active_job) {
                var jobData = res.data;
                console.log('🔄 [AEO Agent] Detected active session:', jobData);

                // Case 1: Restore Image Generation
                if (jobData.type === 'image') {
                    $title.text("Đang đồng bộ tạo ảnh...");
                    $body.html(`
                        <div class="notice notice-info" style="margin-top:20px;">
                            <p><strong>🖼️ Đang tạo hình ảnh...</strong></p>
                            <p>Phát hiện tiến trình tạo ảnh cho bài viết "${jobData.primary_term}" ở tab khác.</p>
                        </div>
                        <p class='aeo-agent-help'>⏳ Đang chờ kết quả...</p>
                    `);

                    $submitBtn.prop('disabled', true).text('Đang tạo ảnh...');
                    setLoading(true);
                    setUnsaved(true);

                    $postIDHidden.val(jobData.post_id);

                    // Switch to Images Tab
                    $kwWrap.empty();
                    $initialPlaceholder.hide();
                    $tabsWrapper.show();
                    $tabLinks.filter('[data-tab="images"]').click();
                    $imgResults.html("<p>🔄 Đang kết nối lại tiến trình...</p>");

                    startImageRecoveryPolling(jobData.post_id);
                }
                // Case 2: Restore Text Generation
                else {
                    $title.text("Đang khôi phục bài viết...");
                    $body.html(`
                        <div class="notice notice-info" style="margin-top:20px;">
                            <p><strong>🔄 Đang đồng bộ...</strong></p>
                            <p>Bài viết <em>"${jobData.primary_term}"</em> đang được tạo ở tab khác.</p>
                        </div>
                        <p class='aeo-agent-help'>⏳ Đang xử lý...</p>
                    `);

                    $submitBtn.prop('disabled', true).text('Đang xử lý...');
                    setLoading(true);
                    setUnsaved(true);

                    $kwWrap.empty();
                    $initialPlaceholder.hide();
                    $tabsWrapper.show();
                    $tabLinks.filter('[data-tab="content"]').click();

                    startPolling(jobData.job_id);
                }
            }
        });
    }

    /**
     * Polls for image recovery status.
     * @param {int} postId
     */
    function startImageRecoveryPolling(postId) {
        var attempts = 0;
        var interval = setInterval(function() {
            attempts++;
            if (attempts > 60) {
                clearInterval(interval);
                handleImageRecoveryFailed("Hết thời gian chờ. Vui lòng thử lại.");
                return;
            }

            $.post(eonsr_aeo_agent_ajax.ajax_url, {
                action: 'eonsr_aeo_agent_poll_image_recovery',
                nonce: eonsr_aeo_agent_ajax.check_active_nonce,
                post_id: postId
            }).done(function(res) {
                if (!res.success) return;

                if (res.data.status === 'completed') {
                    clearInterval(interval);
                    handleImageRecoverySuccess(res.data.data);
                } else if (res.data.status === 'failed') {
                    clearInterval(interval);
                    handleImageRecoveryFailed(res.data.message);
                }
            });
        }, 3000);
    }

    /**
     * Handles successful image recovery.
     * @param {Object} data
     */
    function handleImageRecoverySuccess(data) {
        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');

        // Restore Prompts
        $featuredPromptTextarea.val(data.featured_image_prompt || "");
        $inContentPromptTextarea.val(data.in_content_image_prompt || "");

        originalFeaturedPrompt = data.featured_image_prompt || "";

        // Restore Image Previews (using src URL)
        var imgHtml = '';
        if (data.featuredImageSrc) {
            imgHtml += '<div><h4>Ảnh đại diện</h4><img src="' + data.featuredImageSrc + '"/></div>';
        }
        if (data.inContentImageSrc) {
            imgHtml += '<div><h4>Ảnh nội dung</h4><img src="' + data.inContentImageSrc + '"/></div>';
        }
        $imgResults.html(imgHtml);

        // Update Title & Tags
        if (data.updated_title) $publishForm.find("input[name=preview_title]").val(data.updated_title);
        if (data.updated_tags && Array.isArray(data.updated_tags)) {
             $kwWrap.empty();
             data.updated_tags.forEach(tag => {
                $("<span/>", { class: "aeo-agent-badge", text: tag }).appendTo($kwWrap);
            });
        }

        // Adjust UI Buttons
        if (data.featuredImageSrc || data.inContentImageSrc) {
            $('#btn-gen-all').hide();
            $('#aeo-regen-buttons').css('display', 'flex');
        } else {
            $('#btn-gen-all').show();
            $('#aeo-regen-buttons').hide();
        }

        // Trigger existing check to update review tab context (Simulated)
        $.post(eonsr_aeo_agent_ajax.ajax_url, {
            action: 'eonsr_aeo_agent_poll_job_status',
            nonce: eonsr_aeo_agent_ajax.poll_nonce,
            job_id: 'fake_id_to_trigger_existing_check'
        }).always(function() {
             $title.text("Đã khôi phục ảnh thành công!");
             $body.html("<div class='notice notice-success'><p>✅ Ảnh đã được tạo và lưu vào bài viết.</p></div>");

             $reviewTabLink.removeClass('disabled');
             $genImgBtn.text('Tạo lại ảnh').prop('disabled', false);
        });
        currentJobId = null;
    }

    /**
     * Handles failed image recovery.
     * @param {string} msg
     */
    function handleImageRecoveryFailed(msg) {
        setLoading(false);
        $submitBtn.prop('disabled', false).text('Tạo bài viết & Câu lệnh ảnh');
        $imgResults.html(`<div class='notice notice-error'><p>❌ ${msg}</p></div>`);
        $title.text("Lỗi khôi phục");
        currentJobId = null;
    }

    // --- Init Schedule & Translations ---
    toggleScheduleVisibility();
    setInterval(updateScheduleTimeConstraints, 1000);
    triggerPolylangTranslation();

    // ========================================================================
    // [PART 2] BULK PROCESSOR LOGIC
    // ========================================================================

    (function ($) {
        'use strict';

        if (!$('#aeo-agent-bulk-form').length) return;

        // --- Bulk State Variables ---
        let statusCheckInterval = null;
        let currentBulkId       = null;
        let currentType         = null;
        let currentBulkStatus   = null;
        let isBulkUploading     = false;
        let historyState        = { page: 1, search: '' };
        let searchDebounceTimer;

        // ====================================================================
        // BULK HELPER FUNCTIONS
        // ====================================================================

        /**
         * Renders the bulk dashboard UI status.
         */
        function renderDashboardUI(params) {
            const $statusDiv = $('#aeo-agent-bulk-status');
            const bulkId     = params.bulkUploadId;
            const filename   = params.filename || '---';
            const total      = params.totalJobs;
            const isResume   = params.isResume || false;

            let statusLabel = isResume ? 'Đang xem lại' : 'Đã lên lịch';
            let statusColor = isResume ? '#2271b1' : '#dba617';

            if (currentBulkStatus === 'cancelled') {
                statusLabel = 'Đã hủy';
                statusColor = '#d63638';
            } else if (currentBulkStatus === 'completed') {
                statusLabel = 'Hoàn thành';
                statusColor = '#00a32a';
            }

            const noticeClass = isResume ? 'notice-info' : 'notice-success';
            const noticeText = isResume
                ? `<p>👁️ Đang xem chi tiết file: <strong>${filename}</strong></p>`
                : `<p>✅ <strong>Upload thành công!</strong> File <strong>${filename}</strong> đã được lên lịch.</p>`;

            let html = '<div style="margin-bottom: 20px;">';
            html += `<div class="notice ${noticeClass} inline">${noticeText}</div>`;
            html += '<div class="aeo-stats-grid">';
            html += `<div class="aeo-stat-card"><h4>Tổng số bài</h4><div class="stat-value">${total}</div></div>`;
            html += `<div class="aeo-stat-card"><h4>Trạng thái</h4><div class="stat-value" id="dashboard-status-text" style="color:${statusColor}">${statusLabel}</div></div>`;
            html += `<div class="aeo-stat-card"><h4>ID Bulk</h4><div class="stat-value" style="font-size:16px">${bulkId ? '...' + bulkId.slice(-10) : '---'}</div></div>`;
            html += '</div>';
            html += '<div class="aeo-actions-bar">';
            html += '<button type="button" class="aeo-btn aeo-btn-primary" id="auto-refresh-btn" data-active="false">🔁 Tự động cập nhật</button>';
            html += '<button type="button" class="aeo-btn aeo-btn-secondary" id="check-scheduled-status-btn">📊 Kiểm tra ngay</button>';
            html += isResume
                ? '<button type="button" class="aeo-btn aeo-btn-secondary" onclick="location.reload()">⬅️ Quay lại Upload</button>'
                : '<button type="button" class="aeo-btn aeo-btn-secondary" onclick="location.reload()">➕ Upload CSV mới</button>';
            html += '</div></div>';

            $statusDiv.html(html);
        }

        /**
         * Renders the list of scheduled jobs.
         */
        function renderScheduledList(jobs) {
            const $jobsList = $('#aeo-agent-bulk-jobs-list');

            if (!jobs || jobs.length === 0) {
                $jobsList.html('<p class="description">Chưa có dữ liệu bài viết.</p>');
                return;
            }

            let html = '';

            jobs.forEach(function (job, index) {
                const status = job.status || 'scheduled';
                let icon = '📅';
                let statusText = 'Đã lên lịch';

                switch (status) {
                    case 'completed':  icon = '✅'; statusText = 'Hoàn thành'; break;
                    case 'processing': icon = '⏳'; statusText = 'Đang xử lý'; break;
                    case 'failed':     icon = '❌'; statusText = 'Thất bại';   break;
                    case 'cancelled':  icon = '🚫'; statusText = 'Đã hủy';     break;
                }

                html += `<div class="aeo-bulk-job-item ${status}" id="job-row-${job.jobId}">`;
                html += '<div style="flex: 1;">';
                html += `<strong>${index + 1}. ${job.primary_term || job.params?.primary_term || 'N/A'}</strong>`;

                if (job.audience) {
                    html += `<div class="job-meta">👥 ${job.audience}</div>`;
                }

                html += '</div>';
                html += '<div style="text-align: right; min-width: 220px;">';
                html += `<span class="job-status-badge">${icon} ${statusText}</span>`;

                // Display scheduled time
                if (job.scheduledTime) {
                    let dateObj;
                    // Handle DD/MM/YYYY format manual parsing
                    if (typeof job.scheduledTime === 'string' && job.scheduledTime.includes('/')) {
                        const [datePart, timePart] = job.scheduledTime.split(' ');
                        if (datePart && timePart) {
                            const [day, month, year] = datePart.split('/');
                            const isoString = `20${year}-${month}-${day}T${timePart}:00`;
                            dateObj = new Date(isoString);
                        } else {
                            dateObj = new Date(job.scheduledTime);
                        }
                    } else {
                        dateObj = new Date(job.scheduledTime);
                    }

                    if (!isNaN(dateObj.getTime())) {
                        html += '<div class="job-meta">🕒 ' +
                            dateObj.toLocaleTimeString('vi-VN', { hour: '2-digit', minute: '2-digit' }) + ' ' +
                            dateObj.toLocaleDateString('vi-VN') +
                            '</div>';
                    }
                }

                // Show cancel button if active
                const isActive = (status === 'scheduled' || status === 'pending');
                const isGlobalActive = (currentBulkStatus !== 'cancelled' && currentBulkStatus !== 'failed');

                if (isActive && isGlobalActive) {
                    html += `<button type="button" class="button-link-delete cancel-single-job-btn" data-id="${job.jobId}" style="margin-top:5px; color:#a00; text-decoration:none;">[Hủy bài này]</button>`;
                }

                // Show error if exists
                if (job.error) {
                    let errorMsg = typeof job.error === 'string' ? job.error : (job.error.message || '');
                    if (errorMsg && errorMsg !== '{}') {
                        html += `<div class="job-meta" style="color:#d63638; margin-top:4px;"><small>⚠️ ${errorMsg}</small></div>`;
                    }
                }

                html += '</div></div>';
            });

            $jobsList.html(html);
        }

        /**
         * Renders pagination controls.
         */
        function renderPagination(pagination) {
            const $container = $('#aeo-history-pagination');
            $container.empty();

            if (pagination.total_pages <= 1) return;

            const current = pagination.current_page;
            const total = pagination.total_pages;
            const start = (current - 1) * pagination.limit + 1;
            const end = Math.min(current * pagination.limit, pagination.total_items);

            let html = `<span class="aeo-pagination-info">Hiển thị ${start}-${end} / ${pagination.total_items}</span>`;
            html += `<button type="button" class="aeo-page-btn" data-page="${current - 1}" ${current === 1 ? 'disabled' : ''}>« Trước</button>`;

            for (let i = 1; i <= total; i++) {
                if (i === 1 || i === total || (i >= current - 2 && i <= current + 2)) {
                    html += `<button type="button" class="aeo-page-btn ${i === current ? 'active' : ''}" data-page="${i}">${i}</button>`;
                } else if (i === current - 3 || i === current + 3) {
                    html += '<span style="padding:0 5px;">...</span>';
                }
            }

            html += `<button type="button" class="aeo-page-btn" data-page="${current + 1}" ${current === total ? 'disabled' : ''}>Sau »</button>`;
            $container.html(html);
        }

        /**
         * Renders the bulk history table.
         */
        function renderHistoryTable(logs) {
            const $tbody = $('#aeo-bulk-history-body');
            $tbody.empty();

            if (!logs || logs.length === 0) {
                $tbody.html('<tr><td colspan="6" style="text-align:center; padding:20px;">Không có dữ liệu lịch sử.</td></tr>');
                return;
            }

            logs.forEach(function (log) {
                let badge = '';

                switch (log.status) {
                    case 'processing': badge = '<span class="job-status-badge processing">⏳ Đang chạy</span>'; break;
                    case 'completed':  badge = '<span class="job-status-badge completed">✅ Hoàn thành</span>'; break;
                    case 'cancelled':  badge = '<span class="job-status-badge failed">🚫 Đã hủy</span>'; break;
                    case 'failed':     badge = '<span class="job-status-badge failed">❌ Lỗi</span>'; break;
                    default:           badge = `<span class="job-status-badge">${log.status}</span>`;
                }

                const viewBtn = `<button type="button" class="button button-small view-bulk-detail-btn" data-id="${log.bulk_id}" data-filename="${log.filename}" data-total="${log.total_jobs}" data-status="${log.status}" title="Xem chi tiết">👁️</button>`;
                const deleteRowBtn = `<button type="button" class="button button-small delete-log-btn" data-id="${log.bulk_id}" title="Xóa khỏi lịch sử" style="color:#a00; border-color:#d63638; margin-left:5px;">🗑️</button>`;
                const cancelProcessBtn = (log.status === 'processing')
                    ? `<button type="button" class="button button-small button-link-delete cancel-bulk-history-btn" data-id="${log.bulk_id}" style="color:#d63638; margin-left:5px">🚫 Stop</button>`
                    : '';

                const dateStr = new Date(log.created_at).toLocaleString('vi-VN');
                const displayName = log.filename.replace(/\.[^/.]+$/, "");

                const row = `<tr id="history-row-${log.bulk_id}">
                    <td>${dateStr}</td>
                    <td><strong>${displayName}</strong></td>
                    <td><code>...${log.bulk_id.slice(-10)}</code></td>
                    <td>${log.total_jobs} bài</td>
                    <td>${badge}</td>
                    <td style="text-align:right;">${viewBtn}${cancelProcessBtn}${deleteRowBtn}</td>
                </tr>`;

                $tbody.append(row);
            });
        }

        /**
         * Loads bulk history via AJAX.
         */
        function loadBulkHistory(callback) {
            const $tbody = $('#aeo-bulk-history-body');
            $tbody.css('opacity', '0.5');

            $.ajax({
                url: eonsr_aeo_agent_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'eonsr_aeo_agent_get_bulk_history',
                    nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce,
                    paged: historyState.page,
                    search: historyState.search
                },
                success: function (response) {
                    if (response.success) {
                        const data = response.data;
                        renderHistoryTable(data.logs);
                        renderPagination(data.pagination);
                    } else {
                        $tbody.html('<tr><td colspan="6">Lỗi tải dữ liệu.</td></tr>');
                    }
                    if (callback) callback();
                },
                complete: function () {
                    $tbody.css('opacity', '1');
                }
            });
        }

        /**
         * Checks the status of a specific bulk job.
         */
        function checkScheduledStatus() {
            if (!currentBulkId) return;

            const $btn = $('#check-scheduled-status-btn');
            $btn.prop('disabled', true).text('⏳...');

            $.ajax({
                url: eonsr_aeo_agent_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'eonsr_aeo_agent_check_scheduled_bulk_status',
                    nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce,
                    bulkUploadId: currentBulkId
                },
                success: function (response) {
                    if (response.success) {
                        displayScheduledStatus(response.data);
                    } else {
                        if (response.data && response.data.code === 'NOT_FOUND_ON_SERVER') {
                            Swal.fire({
                                icon: 'info',
                                title: 'Dữ liệu không tồn tại',
                                text: response.data.message
                            });
                            stopAutoRefresh();
                            $('#aeo-agent-bulk-details').hide();
                            $('#aeo-agent-bulk-status').empty();
                            currentBulkId = null;
                            loadBulkHistory();
                        } else {
                            console.log('Error checking status:', response);
                        }
                    }
                },
                complete: function () {
                    $btn.prop('disabled', false).text('📊 Kiểm tra ngay');
                }
            });
        }

        function displayScheduledStatus(data) {
            const stats = data.stats || {};
            const jobs = data.jobs || [];

            renderScheduledList(jobs);

            const activeCount = (stats.scheduled || 0) + (stats.processing || 0);
            const $actionsBar = $('.aeo-actions-bar');

            $('#cancel-bulk-btn').remove();

            if (activeCount > 0 && currentBulkStatus !== 'cancelled' && currentBulkStatus !== 'failed') {
                const cancelBtn = `<button type="button" class="aeo-btn aeo-btn-danger" id="cancel-bulk-btn" style="margin-left:auto">🚫 Hủy toàn bộ (${activeCount})</button>`;
                $actionsBar.append(cancelBtn);
            } else {
                if (currentBulkStatus !== 'cancelled') {
                    loadBulkHistory();
                }
            }
        }

        function checkImmediateStatus() {
            const $btn = $('#check-immediate-status-btn');
            $btn.prop('disabled', true);

            $.ajax({
                url: eonsr_aeo_agent_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'eonsr_aeo_agent_check_bulk_status',
                    nonce: eonsr_aeo_agent_ajax.bulk_status_nonce
                },
                success: function (response) {
                    if (response.success) {
                        displayImmediateList(response.data);
                    }
                },
                complete: function () {
                    $btn.prop('disabled', false);
                }
            });
        }

        function displayImmediateList(data) {
            const jobs = data.jobs || [];
            let html = '<h4>Chi tiết:</h4>';

            jobs.forEach((job, i) => {
                let icon = '⏳';
                if (job.status === 'completed') icon = '✅';
                if (job.status === 'failed') icon = '❌';

                html += `<div class="aeo-bulk-job-item ${job.status}">
                    <strong>${i + 1}. ${job.params?.primary_term || 'Job'}</strong>
                    <span style="float:right">${icon} ${job.status}</span>
                </div>`;
            });

            $('#aeo-agent-bulk-jobs-list').html(html);
        }

        function handleScheduledSuccess(data) {
            const $detailsDiv = $('#aeo-agent-bulk-details');
            currentBulkId = data.bulkUploadId;
            currentBulkStatus = 'scheduled';
            const total = data.totalJobs || (data.schedule ? data.schedule.length : 0);

            renderDashboardUI({
                bulkUploadId: currentBulkId,
                filename: data.filename,
                totalJobs: total,
                isResume: false
            });

            if (data.schedule && data.schedule.length > 0) {
                renderScheduledList(data.schedule);
                $detailsDiv.show();
            } else if (total === 0) {
                $detailsDiv.show();
                $('#aeo-agent-bulk-jobs-list').html('<div class="notice notice-warning"><p>⚠️ File CSV hợp lệ nhưng không tìm thấy dữ liệu.</p></div>');
            }

            $('#auto-refresh-btn').click();
            $('#aeo-agent-bulk-form')[0].reset();
            $('#file-name-display').text('Chưa chọn file').css({ 'color': '#666', 'font-weight': 'normal' });
            $('#aeo-bulk-submit-btn').prop('disabled', true).addClass('disabled');
        }

        function handleImmediateSuccess(data) {
            const $statusDiv = $('#aeo-agent-bulk-status');
            const $detailsDiv = $('#aeo-agent-bulk-details');
            const summary = data.summary || { total: 0, successful: 0, failed: 0 };
            currentBulkStatus = 'immediate';

            let html = '<div class="notice notice-warning" style="padding: 15px;">';
            html += '<h3>⚠️ Upload thành công (Legacy Mode)</h3>';
            html += `<p><strong>Tổng:</strong> ${summary.total} | <strong>Thành công:</strong> ${summary.successful} | <strong>Thất bại:</strong> ${summary.failed}</p>`;
            html += '<p style="margin-top: 15px;"><button type="button" class="button button-primary" onclick="location.reload()">🔄 Upload lại</button></p>';
            html += '</div>';

            $statusDiv.html(html);
            $detailsDiv.show();

            if (data.jobIds && data.jobIds.length > 0) {
                checkImmediateStatus();
            }
        }

        function handleError(data) {
            const message = data.message || 'Lỗi không xác định';
            $('#aeo-agent-bulk-status').html(
                `<div class="notice notice-error" style="padding:15px">
                    <h3>❌ Lỗi</h3>
                    <p>${message}</p>
                    <button class="button" onclick="location.reload()">Thử lại</button>
                </div>`
            );
            $('#aeo-agent-bulk-details').hide();
        }

        // --- Auto Refresh Logic ---
        function startAutoRefresh() {
            const $btn = $('#auto-refresh-btn');
            $btn.attr('data-active', 'true').text('⏸️ Dừng cập nhật');
            $btn.removeClass('aeo-btn-primary').addClass('aeo-btn-danger');
            performCheck();
            statusCheckInterval = setInterval(performCheck, 30000);
        }

        function stopAutoRefresh() {
            const $btn = $('#auto-refresh-btn');
            if (statusCheckInterval) {
                clearInterval(statusCheckInterval);
                statusCheckInterval = null;
            }
            $btn.attr('data-active', 'false').text('🔁 Tự động cập nhật');
            $btn.removeClass('aeo-btn-danger').addClass('aeo-btn-primary');
        }

        function performCheck() {
            if (currentType === 'scheduled') {
                checkScheduledStatus();
            } else {
                checkImmediateStatus();
            }
        }

        // ====================================================================
        // BULK EVENT HANDLERS
        // ====================================================================

        window.addEventListener('beforeunload', function (e) {
            if (isBulkUploading) {
                e.preventDefault();
                e.returnValue = 'File đang được tải lên. Bạn có chắc muốn hủy không?';
                return e.returnValue;
            }
        });

        $('#aeo-agent-bulk-form').on('submit', function (e) {
            e.preventDefault();

            const $form = $(this);
            const $fileInput = $('input[name="bulk_csv_file"]');
            const $submitBtn = $('#aeo-bulk-submit-btn');
            const $statusDiv = $('#aeo-agent-bulk-status');

            if (!$fileInput[0].files.length) {
                Swal.fire('Lỗi', 'Vui lòng chọn file XLSX', 'warning');
                return;
            }

            const file = $fileInput[0].files[0];
            const fileName = file.name.toLowerCase();

            if (!fileName.endsWith('.xlsx')) {
                Swal.fire({ icon: 'error', title: 'Sai định dạng file', text: 'Hệ thống chỉ chấp nhận file .xlsx' });
                return;
            }

            isBulkUploading = true;

            $submitBtn.prop('disabled', true).html('⏳ Đang tải lên...');
            $statusDiv.html('<div class="notice notice-info"><p>📤 Đang xử lý file CSV...</p></div>');

            const formData = new FormData($form[0]);
            formData.append('action', 'eonsr_aeo_agent_bulk_upload_csv');
            formData.append('nonce', eonsr_aeo_agent_ajax.bulk_upload_nonce);

            stopAutoRefresh();

            $.ajax({
                url: eonsr_aeo_agent_ajax.ajax_url,
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                timeout: 300000,
                success: function (response) {
                    if (response.success) {
                        const type = response.data.type || 'immediate';
                        currentType = type;
                        loadBulkHistory();

                        if (type === 'scheduled') {
                            handleScheduledSuccess(response.data);
                        } else {
                            handleImmediateSuccess(response.data);
                        }
                    } else {
                        handleError(response.data);
                    }
                },
                error: function (xhr, status, error) {
                    handleError({ message: 'Lỗi kết nối: ' + error });
                },
                complete: function () {
                    isBulkUploading = false;
                    $submitBtn.prop('disabled', false).html('📤 Upload và Bắt đầu');
                }
            });
        });

        $(document).on('click', '#check-scheduled-status-btn', checkScheduledStatus);

        $(document).on('click', '.cancel-single-job-btn', function () {
            const jobId = $(this).data('id');
            const $btn = $(this);

            Swal.fire({
                title: 'Hủy bài viết này?',
                text: "Bài viết này sẽ bị loại khỏi hàng chờ.",
                icon: 'question',
                showCancelButton: true,
                confirmButtonColor: '#d63638',
                cancelButtonColor: '#3085d6',
                confirmButtonText: 'Hủy bài',
                cancelButtonText: 'Không'
            }).then((result) => {
                if (result.isConfirmed) {
                    $btn.text('...').prop('disabled', true);

                    $.ajax({
                        url: eonsr_aeo_agent_ajax.ajax_url,
                        type: 'POST',
                        data: {
                            action: 'eonsr_aeo_agent_cancel_job',
                            nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce,
                            jobId: jobId
                        },
                        success: function (response) {
                            if (response.success) {
                                $('#job-row-' + jobId)
                                    .removeClass('scheduled pending')
                                    .addClass('cancelled')
                                    .find('.job-status-badge')
                                    .html('🚫 Đã hủy');

                                $btn.remove();

                                const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 });
                                Toast.fire({ icon: 'success', title: 'Đã hủy bài viết' });
                            } else {
                                Swal.fire('Lỗi', response.data.message, 'error');
                                $btn.text('[Hủy bài này]').prop('disabled', false);
                            }
                        }
                    });
                }
            });
        });

        $(document).on('click', '.view-bulk-detail-btn', function () {
            const bulkId = $(this).data('id');
            const filename = $(this).data('filename');
            const total = $(this).data('total');
            const status = $(this).data('status');

            currentBulkId = bulkId;
            currentType = 'scheduled';
            currentBulkStatus = status;

            const $target = $('#aeo-agent-bulk-status');
            if ($target.length) {
                $('html, body').animate({ scrollTop: $target.offset().top - 50 }, 'fast');
            }

            $('#aeo-agent-bulk-status').html(
                `<div class="notice notice-info inline">
                    <p>⏳ Đang tải chi tiết cho file: <strong>${filename}</strong>...</p>
                </div>`
            );

            $('#aeo-agent-bulk-jobs-list').html('<p>Đang tải dữ liệu...</p>');
            $('#aeo-agent-bulk-details').show();

            renderDashboardUI({ bulkUploadId: bulkId, filename: filename, totalJobs: total, isResume: true });

            checkScheduledStatus();

            if (status === 'processing') {
                startAutoRefresh();
            } else {
                stopAutoRefresh();
            }
        });

        $(document).on('click', '#cancel-bulk-btn', function () {
            if (!currentBulkId) return;

            Swal.fire({
                title: '⚠️ CẢNH BÁO',
                text: "Bạn có chắc muốn hủy toàn bộ tiến trình này không? Hành động này không thể hoàn tác.",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#d63638',
                cancelButtonColor: '#3085d6',
                confirmButtonText: 'Đồng ý hủy',
                cancelButtonText: 'Quay lại'
            }).then((result) => {
                if (result.isConfirmed) {
                    const $btn = $('#cancel-bulk-btn');
                    $btn.text('⏳ Đang hủy...').prop('disabled', true);
                    currentBulkStatus = 'cancelled';
                    stopAutoRefresh();

                    $.ajax({
                        url: eonsr_aeo_agent_ajax.ajax_url,
                        type: 'POST',
                        data: {
                            action: 'eonsr_aeo_agent_cancel_bulk',
                            nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce,
                            bulkUploadId: currentBulkId
                        },
                        success: function (response) {
                            if (response.success) {
                                $btn.remove();
                                $('#dashboard-status-text').css('color', '#d63638').text('Đã hủy');
                                checkScheduledStatus();
                                loadBulkHistory();
                                Swal.fire({ title: 'Đã hủy!', text: 'Tiến trình đã được hủy thành công.', icon: 'success', timer: 2000, showConfirmButton: false });
                            } else {
                                Swal.fire('Lỗi', response.data.message, 'error');
                                $btn.text('🚫 Hủy toàn bộ').prop('disabled', false);
                                currentBulkStatus = 'processing';
                            }
                        }
                    });
                }
            });
        });

        $(document).on('click', '.cancel-bulk-history-btn', function () {
            const bulkId = $(this).data('id');
            const $btn = $(this);

            Swal.fire({
                title: 'Hủy file CSV này?',
                text: "Các bài viết chưa chạy sẽ bị dừng lại.",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#d63638',
                confirmButtonText: 'Đồng ý hủy',
                cancelButtonText: 'Thôi'
            }).then((result) => {
                if (result.isConfirmed) {
                    $btn.text('...').prop('disabled', true);
                    $.ajax({
                        url: eonsr_aeo_agent_ajax.ajax_url,
                        type: 'POST',
                        data: { action: 'eonsr_aeo_agent_cancel_bulk', nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce, bulkUploadId: bulkId },
                        success: function (response) {
                            if (response.success) {
                                Swal.fire('Thành công', 'Đã hủy tiến trình.', 'success');
                                loadBulkHistory();
                            } else {
                                Swal.fire('Lỗi', response.data.message, 'error');
                                $btn.text('🚫 Hủy').prop('disabled', false);
                            }
                        }
                    });
                }
            });
        });

        $(document).on('click', '.delete-log-btn', function () {
            const bulkId = $(this).data('id');

            Swal.fire({
                title: 'Xóa nhật ký này?',
                text: "Dữ liệu bài viết đã tạo sẽ KHÔNG bị mất. Chỉ xóa dòng nhật ký này khỏi bảng.",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#d63638',
                confirmButtonText: 'Xóa',
                cancelButtonText: 'Hủy'
            }).then((result) => {
                if (result.isConfirmed) {
                    $.ajax({
                        url: eonsr_aeo_agent_ajax.ajax_url,
                        type: 'POST',
                        data: { action: 'eonsr_aeo_agent_delete_bulk_log', nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce, bulkUploadId: bulkId },
                        success: function () {
                            $('#history-row-' + bulkId).fadeOut(300, function () { $(this).remove(); });
                        }
                    });
                }
            });
        });

        $(document).on('click', '#clear-all-history-btn', function () {
            Swal.fire({
                title: '⚠️ Xóa SẠCH lịch sử?',
                text: "Hành động này sẽ xóa toàn bộ danh sách bên dưới. Dữ liệu bài viết trên website vẫn an toàn.",
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#d63638',
                confirmButtonText: 'Xóa tất cả',
                cancelButtonText: 'Hủy'
            }).then((result) => {
                if (result.isConfirmed) {
                    const $btn = $('#clear-all-history-btn');
                    $btn.prop('disabled', true).text('Đang xóa...');
                    $.ajax({
                        url: eonsr_aeo_agent_ajax.ajax_url,
                        type: 'POST',
                        data: { action: 'eonsr_aeo_agent_clear_all_history', nonce: eonsr_aeo_agent_ajax.bulk_upload_nonce },
                        success: function (response) {
                            Swal.fire('Đã dọn dẹp!', 'Lịch sử đã được xóa sạch.', 'success');
                            loadBulkHistory();
                        },
                        complete: function () {
                            $btn.prop('disabled', false).text('🗑️ Xóa sạch lịch sử');
                        }
                    });
                }
            });
        });

        $('#refresh-history-btn').on('click', loadBulkHistory);

        $('#history-search-input').on('keyup', function () {
            clearTimeout(searchDebounceTimer);
            const val = $(this).val().trim();
            searchDebounceTimer = setTimeout(function () {
                historyState.search = val;
                historyState.page = 1;
                loadBulkHistory();
            }, 500);
        });

        $(document).on('click', '.aeo-page-btn', function () {
            const page = $(this).data('page');
            if (page) {
                historyState.page = page;
                loadBulkHistory();
            }
        });

        $(document).on('click', '#auto-refresh-btn', function () {
            const $btn = $(this);
            const isActive = $btn.attr('data-active') === 'true';
            if (isActive) stopAutoRefresh();
            else startAutoRefresh();
        });

        $(window).on('beforeunload', function () {
            if (statusCheckInterval) clearInterval(statusCheckInterval);
        });

        // Initialize Bulk History
        loadBulkHistory();

    })(jQuery);

    // ========================================================================
    // [PART 3] CUSTOM LOGO UPLOAD LOGIC
    // ========================================================================

    // Toggle Upload Area
    $(document).on('change', '#use_custom_logo', function() {
        if($(this).is(':checked')) {
            $('#aeo-logo-upload-area').slideDown();
        } else {
            $('#aeo-logo-upload-area').slideUp();
        }
    });

    // Trigger File Input
    $(document).on('click', '#btn-upload-logo', function(e) {
        e.preventDefault();
        $('#aeo-logo-file').click();
    });

    // Handle File Change & Upload
    $(document).on('change', '#aeo-logo-file', function() {
        var file = this.files[0];
        if (!file) return;

        // Validation
        if (file.type !== 'image/png') {
            alert('Vui lòng chỉ chọn file ảnh PNG.');
            return;
        }

        var formData = new FormData();
        formData.append('action', 'eonsr_aeo_agent_upload_logo');
        formData.append('nonce', eonsr_aeo_agent_ajax.setup_nonce);
        formData.append('custom_logo', file);

        const $btn = $('#btn-upload-logo');
        const originalText = $btn.text();
        $btn.text('Đang tải...').prop('disabled', true);

        $.ajax({
            url: eonsr_aeo_agent_ajax.ajax_url,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(res) {
                if (res.success) {
                    $('#aeo-logo-preview').html('<img src="' + res.data.url + '" style="max-width:100%; max-height:100%;">');
                    $('#btn-remove-logo').show();
                    if(typeof Swal !== 'undefined') {
                        Swal.fire('Thành công', 'Đã lưu logo mới!', 'success');
                    } else {
                        alert('Đã lưu logo mới!');
                    }
                } else {
                    alert(res.data.message || 'Lỗi upload');
                }
            },
            error: function() {
                alert('Lỗi kết nối server.');
            },
            complete: function() {
                $btn.text(originalText).prop('disabled', false);
                $('#aeo-logo-file').val(''); // Reset input
            }
        });
    });

    // ============================================================================
// [PART 4] WIZARD SETUP LOGIC
// Uses eonsr_aeo_wizard_data passed via wp_add_inline_script
// ============================================================================

(function() {
    if (typeof eonsr_aeo_wizard_data === 'undefined') return;

    const allLanguages = eonsr_aeo_wizard_data.allLanguages;
    const allCountries = eonsr_aeo_wizard_data.allCountries;
    const allStyles    = eonsr_aeo_wizard_data.allStyles;
    const langLimit    = eonsr_aeo_wizard_data.langLimit;
    const countryLimit = eonsr_aeo_wizard_data.countryLimit;
    const styleLimit   = eonsr_aeo_wizard_data.styleLimit;
    const setupNonce   = eonsr_aeo_wizard_data.setupNonce;

    // Helper: Filter Grid
    window.filterWizardGrid = function(inputId, gridId) {
        var input = document.getElementById(inputId);
        var filter = input.value.toLowerCase();
        var items = document.querySelectorAll('#' + gridId + ' .eonsr-aeo-wizard-item');
        items.forEach(function(item) {
            var nameElement = item.querySelector('.eonsr-aeo-item-name');
            var text = nameElement ? nameElement.textContent : item.textContent;
            item.style.display = text.toLowerCase().indexOf(filter) > -1 ? '' : 'none';
        });
    };

    // Helper: Build Grid
    function buildWizardGrid(items, name, searchId, listId, limit, selectedValues) {
        selectedValues = selectedValues || [];
        var html = '<div class="eonsr-aeo-wizard-search-box">' +
            '<span class="dashicons dashicons-search eonsr-aeo-wizard-search-icon"></span>' +
            '<input type="text" id="' + searchId + '" placeholder="Tìm kiếm..." onkeyup="filterWizardGrid(\'' + searchId + '\', \'' + listId + '\')">' +
            '</div><div id="' + listId + '" class="eonsr-aeo-wizard-grid">';

        var defaults = ['Vietnamese', 'English', 'VN', 'US'];

        Object.entries(items).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var isChecked = '';
            if (selectedValues.length > 0) {
                if (selectedValues.indexOf(key) > -1) isChecked = 'checked';
            } else {
                if (defaults.indexOf(key) > -1) isChecked = 'checked';
            }
            html += '<label class="eonsr-aeo-wizard-item" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="' + name + '" value="' + key + '" class="eonsr-aeo-setup-' + name + '" ' + isChecked + '>' +
                '<div class="eonsr-aeo-wizard-card">' +
                '<div class="eonsr-aeo-check-icon"></div>' +
                '<span style="font-size:18px;">' + data.flag + '</span>' +
                '<span class="eonsr-aeo-item-name">' + data.name + '</span>' +
                '</div></label>';
        });

        html += '</div>';
        return html;
    }

    // Helper: Build Style List
    function buildStyleList(styles) {
        var html = '<div class="eonsr-aeo-style-list">';
        Object.entries(styles).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var checked = (key === 'Mac dinh') ? 'checked' : '';
            var demoUrl = (data.url && data.url !== '#') ? data.url : 'javascript:void(0)';
            var target  = (data.url && data.url !== '#') ? 'target="_blank"' : '';
            var styleNameDisplay = data.name.split('(')[0];
            var styleTagMatch = data.name.match(/\(([^)]+)\)/);
            var styleTag = styleTagMatch ? styleTagMatch[1] : '';

            html += '<label class="eonsr-aeo-style-card-wrapper" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="style" value="' + key + '" class="eonsr-aeo-setup-style" ' + checked + ' style="position:absolute; opacity:0; width:0; height:0;">' +
                '<div class="eonsr-aeo-style-card">' +
                '<div class="eonsr-aeo-style-content">' +
                '<h4>' + styleNameDisplay + (styleTag ? ' <span class="eonsr-aeo-style-tag">' + styleTag + '</span>' : '') + '</h4>' +
                '<p>' + (data.desc || 'Phong cách viết chất lượng cao.') + '</p>' +
                '</div>' +
                '<a href="' + demoUrl + '" ' + target + ' class="eonsr-aeo-btn-preview" onclick="event.stopPropagation();">' +
                '<span class="dashicons dashicons-visibility"></span> Xem mẫu</a>' +
                '</div></label>';
        });
        html += '</div>';
        return html;
    }

    // Helper: Limit Enforcement
    function enforceLimit(className, limit, errorId, badgeId) {
        var container = Swal.getHtmlContainer();
        var inputs    = container.querySelectorAll('.' + className);
        var errorMsg  = container.querySelector('#' + errorId);
        var badge     = container.querySelector('#' + badgeId);

        inputs.forEach(function(input) {
            input.addEventListener('change', function() {
                var checkedCount = container.querySelectorAll('.' + className + ':checked').length;
                if (checkedCount > limit) {
                    this.checked = false;
                    if (errorMsg) {
                        errorMsg.innerText = 'Chỉ được chọn tối đa ' + limit + ' mục!';
                        errorMsg.classList.add('eonsr-aeo-error-show');
                    }
                    if (badge) badge.classList.add('eonsr-aeo-badge-error');
                    setTimeout(function() {
                        if (errorMsg) errorMsg.classList.remove('eonsr-aeo-error-show');
                        if (badge) badge.classList.remove('eonsr-aeo-badge-error');
                    }, 2000);
                }
            });
        });
    }

    // Main Wizard Loop
    async function runAeoSetupWizard() {
        var currentStep = 1;
        var cachedData  = { langs: [], countries: [] };

        while (true) {
            if (currentStep === 1) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 1/2: Chọn khu vực</span>',
                    width: '900px',
                    padding: '2em',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:20px;">Chọn ngôn ngữ và quốc gia mục tiêu để tối ưu hóa nội dung SEO.</p>' +
                        '<div class="eonsr-aeo-layout-row">' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Ngôn ngữ</span><span id="badge-lang" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + langLimit + '</span>' +
                        '<span id="error-lang" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allLanguages, 'lang', 'sLang', 'lLang', langLimit, cachedData.langs) +
                        '</div>' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Quốc gia</span><span id="badge-country" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + countryLimit + '</span>' +
                        '<span id="error-country" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allCountries, 'country', 'sCountry', 'lCountry', countryLimit, cachedData.countries) +
                        '</div></div></div>',
                    confirmButtonText: 'Tiếp theo &rarr;',
                    confirmButtonColor: '#2271b1',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-lang', langLimit, 'error-lang', 'badge-lang');
                        enforceLimit('eonsr-aeo-setup-country', countryLimit, 'error-country', 'badge-country');
                    },
                    preConfirm: function() {
                        var langs     = Array.from(document.querySelectorAll('.eonsr-aeo-setup-lang:checked')).map(function(c) { return c.value; });
                        var countries = Array.from(document.querySelectorAll('.eonsr-aeo-setup-country:checked')).map(function(c) { return c.value; });
                        if (langs.length === 0 || countries.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 Ngôn ngữ và 1 Quốc gia.');
                            return false;
                        }
                        return { langs: langs, countries: countries };
                    }
                });

                if (result.isConfirmed) {
                    cachedData.langs     = result.value.langs;
                    cachedData.countries = result.value.countries;
                    currentStep = 2;
                } else {
                    break;
                }
            }
            else if (currentStep === 2) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 2/2: Chọn phong cách viết</span>',
                    width: '650px',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:10px;">Chọn các phong cách viết phù hợp với thương hiệu của bạn.</p>' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0; margin-bottom:15px;"><div style="display:flex; align-items:center;">' +
                        '<span>Phong cách</span><span id="badge-style" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + styleLimit + '</span>' +
                        '<span id="error-style" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildStyleList(allStyles) + '</div>',
                    confirmButtonText: 'Hoàn tất cài đặt <span class="dashicons dashicons-yes" style="vertical-align:middle"></span>',
                    confirmButtonColor: '#2271b1',
                    showCancelButton: true,
                    cancelButtonText: 'Quay lại',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    allowEnterKey: false,
                    showCloseButton: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-style', styleLimit, 'error-style', 'badge-style');
                    },
                    preConfirm: function() {
                        var styles = Array.from(document.querySelectorAll('.eonsr-aeo-setup-style:checked')).map(function(c) { return c.value; });
                        if (styles.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 phong cách.');
                            return false;
                        }
                        return styles;
                    }
                });

                if (result.isConfirmed) {
                    Swal.fire({ title: 'Đang lưu cấu hình...', html: 'Vui lòng không tắt trình duyệt.', allowOutsideClick: false, showConfirmButton: false, didOpen: function() { Swal.showLoading(); } });

                    jQuery.post(ajaxurl, {
                        action: 'eonsr_aeo_agent_save_initial_setup',
                        nonce: setupNonce,
                        languages: cachedData.langs,
                        countries: cachedData.countries,
                        styles: result.value
                    }).done(function(res) {
                        if (res.success) {
                            Swal.fire({ icon: 'success', title: 'Thành công!', text: 'Cài đặt ban đầu hoàn tất.', confirmButtonColor: '#2271b1' }).then(function() { window.location.reload(); });
                        } else {
                            Swal.fire('Lỗi', res.data.message, 'error');
                        }
                    }).fail(function() {
                        Swal.fire('Lỗi', 'Không thể kết nối đến máy chủ.', 'error');
                    });
                    break;
                } else if (result.dismiss === Swal.DismissReason.cancel) {
                    currentStep = 1;
                }
            }
        }
    }

    document.addEventListener('DOMContentLoaded', function() {
        runAeoSetupWizard();
    });
})();

// ============================================================================
// [PART 4] WIZARD SETUP LOGIC
// Uses eonsr_aeo_wizard_data passed via wp_add_inline_script
// ============================================================================

(function() {
    if (typeof eonsr_aeo_wizard_data === 'undefined') return;

    const allLanguages = eonsr_aeo_wizard_data.allLanguages;
    const allCountries = eonsr_aeo_wizard_data.allCountries;
    const allStyles    = eonsr_aeo_wizard_data.allStyles;
    const langLimit    = eonsr_aeo_wizard_data.langLimit;
    const countryLimit = eonsr_aeo_wizard_data.countryLimit;
    const styleLimit   = eonsr_aeo_wizard_data.styleLimit;
    const setupNonce   = eonsr_aeo_wizard_data.setupNonce;

    // Helper: Filter Grid
    window.filterWizardGrid = function(inputId, gridId) {
        var input = document.getElementById(inputId);
        var filter = input.value.toLowerCase();
        var items = document.querySelectorAll('#' + gridId + ' .eonsr-aeo-wizard-item');
        items.forEach(function(item) {
            var nameElement = item.querySelector('.eonsr-aeo-item-name');
            var text = nameElement ? nameElement.textContent : item.textContent;
            item.style.display = text.toLowerCase().indexOf(filter) > -1 ? '' : 'none';
        });
    };

    // Helper: Build Grid
    function buildWizardGrid(items, name, searchId, listId, limit, selectedValues) {
        selectedValues = selectedValues || [];
        var html = '<div class="eonsr-aeo-wizard-search-box">' +
            '<span class="dashicons dashicons-search eonsr-aeo-wizard-search-icon"></span>' +
            '<input type="text" id="' + searchId + '" placeholder="Tìm kiếm..." onkeyup="filterWizardGrid(\'' + searchId + '\', \'' + listId + '\')">' +
            '</div><div id="' + listId + '" class="eonsr-aeo-wizard-grid">';

        var defaults = ['Vietnamese', 'English', 'VN', 'US'];

        Object.entries(items).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var isChecked = '';
            if (selectedValues.length > 0) {
                if (selectedValues.indexOf(key) > -1) isChecked = 'checked';
            } else {
                if (defaults.indexOf(key) > -1) isChecked = 'checked';
            }
            html += '<label class="eonsr-aeo-wizard-item" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="' + name + '" value="' + key + '" class="eonsr-aeo-setup-' + name + '" ' + isChecked + '>' +
                '<div class="eonsr-aeo-wizard-card">' +
                '<div class="eonsr-aeo-check-icon"></div>' +
                '<span style="font-size:18px;">' + data.flag + '</span>' +
                '<span class="eonsr-aeo-item-name">' + data.name + '</span>' +
                '</div></label>';
        });

        html += '</div>';
        return html;
    }

    // Helper: Build Style List
    function buildStyleList(styles) {
        var html = '<div class="eonsr-aeo-style-list">';
        Object.entries(styles).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var checked = (key === 'Mac dinh') ? 'checked' : '';
            var demoUrl = (data.url && data.url !== '#') ? data.url : 'javascript:void(0)';
            var target  = (data.url && data.url !== '#') ? 'target="_blank"' : '';
            var styleNameDisplay = data.name.split('(')[0];
            var styleTagMatch = data.name.match(/\(([^)]+)\)/);
            var styleTag = styleTagMatch ? styleTagMatch[1] : '';

            html += '<label class="eonsr-aeo-style-card-wrapper" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="style" value="' + key + '" class="eonsr-aeo-setup-style" ' + checked + ' style="position:absolute; opacity:0; width:0; height:0;">' +
                '<div class="eonsr-aeo-style-card">' +
                '<div class="eonsr-aeo-style-content">' +
                '<h4>' + styleNameDisplay + (styleTag ? ' <span class="eonsr-aeo-style-tag">' + styleTag + '</span>' : '') + '</h4>' +
                '<p>' + (data.desc || 'Phong cách viết chất lượng cao.') + '</p>' +
                '</div>' +
                '<a href="' + demoUrl + '" ' + target + ' class="eonsr-aeo-btn-preview" onclick="event.stopPropagation();">' +
                '<span class="dashicons dashicons-visibility"></span> Xem mẫu</a>' +
                '</div></label>';
        });
        html += '</div>';
        return html;
    }

    // Helper: Limit Enforcement
    function enforceLimit(className, limit, errorId, badgeId) {
        var container = Swal.getHtmlContainer();
        var inputs    = container.querySelectorAll('.' + className);
        var errorMsg  = container.querySelector('#' + errorId);
        var badge     = container.querySelector('#' + badgeId);

        inputs.forEach(function(input) {
            input.addEventListener('change', function() {
                var checkedCount = container.querySelectorAll('.' + className + ':checked').length;
                if (checkedCount > limit) {
                    this.checked = false;
                    if (errorMsg) {
                        errorMsg.innerText = 'Chỉ được chọn tối đa ' + limit + ' mục!';
                        errorMsg.classList.add('eonsr-aeo-error-show');
                    }
                    if (badge) badge.classList.add('eonsr-aeo-badge-error');
                    setTimeout(function() {
                        if (errorMsg) errorMsg.classList.remove('eonsr-aeo-error-show');
                        if (badge) badge.classList.remove('eonsr-aeo-badge-error');
                    }, 2000);
                }
            });
        });
    }

    // Main Wizard Loop
    async function runAeoSetupWizard() {
        var currentStep = 1;
        var cachedData  = { langs: [], countries: [] };

        while (true) {
            if (currentStep === 1) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 1/2: Chọn khu vực</span>',
                    width: '900px',
                    padding: '2em',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:20px;">Chọn ngôn ngữ và quốc gia mục tiêu để tối ưu hóa nội dung SEO.</p>' +
                        '<div class="eonsr-aeo-layout-row">' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Ngôn ngữ</span><span id="badge-lang" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + langLimit + '</span>' +
                        '<span id="error-lang" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allLanguages, 'lang', 'sLang', 'lLang', langLimit, cachedData.langs) +
                        '</div>' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Quốc gia</span><span id="badge-country" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + countryLimit + '</span>' +
                        '<span id="error-country" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allCountries, 'country', 'sCountry', 'lCountry', countryLimit, cachedData.countries) +
                        '</div></div></div>',
                    confirmButtonText: 'Tiếp theo &rarr;',
                    confirmButtonColor: '#2271b1',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-lang', langLimit, 'error-lang', 'badge-lang');
                        enforceLimit('eonsr-aeo-setup-country', countryLimit, 'error-country', 'badge-country');
                    },
                    preConfirm: function() {
                        var langs     = Array.from(document.querySelectorAll('.eonsr-aeo-setup-lang:checked')).map(function(c) { return c.value; });
                        var countries = Array.from(document.querySelectorAll('.eonsr-aeo-setup-country:checked')).map(function(c) { return c.value; });
                        if (langs.length === 0 || countries.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 Ngôn ngữ và 1 Quốc gia.');
                            return false;
                        }
                        return { langs: langs, countries: countries };
                    }
                });

                if (result.isConfirmed) {
                    cachedData.langs     = result.value.langs;
                    cachedData.countries = result.value.countries;
                    currentStep = 2;
                } else {
                    break;
                }
            }
            else if (currentStep === 2) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 2/2: Chọn phong cách viết</span>',
                    width: '650px',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:10px;">Chọn các phong cách viết phù hợp với thương hiệu của bạn.</p>' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0; margin-bottom:15px;"><div style="display:flex; align-items:center;">' +
                        '<span>Phong cách</span><span id="badge-style" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + styleLimit + '</span>' +
                        '<span id="error-style" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildStyleList(allStyles) + '</div>',
                    confirmButtonText: 'Hoàn tất cài đặt <span class="dashicons dashicons-yes" style="vertical-align:middle"></span>',
                    confirmButtonColor: '#2271b1',
                    showCancelButton: true,
                    cancelButtonText: 'Quay lại',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    allowEnterKey: false,
                    showCloseButton: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-style', styleLimit, 'error-style', 'badge-style');
                    },
                    preConfirm: function() {
                        var styles = Array.from(document.querySelectorAll('.eonsr-aeo-setup-style:checked')).map(function(c) { return c.value; });
                        if (styles.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 phong cách.');
                            return false;
                        }
                        return styles;
                    }
                });

                if (result.isConfirmed) {
                    Swal.fire({ title: 'Đang lưu cấu hình...', html: 'Vui lòng không tắt trình duyệt.', allowOutsideClick: false, showConfirmButton: false, didOpen: function() { Swal.showLoading(); } });

                    jQuery.post(ajaxurl, {
                        action: 'eonsr_aeo_agent_save_initial_setup',
                        nonce: setupNonce,
                        languages: cachedData.langs,
                        countries: cachedData.countries,
                        styles: result.value
                    }).done(function(res) {
                        if (res.success) {
                            Swal.fire({ icon: 'success', title: 'Thành công!', text: 'Cài đặt ban đầu hoàn tất.', confirmButtonColor: '#2271b1' }).then(function() { window.location.reload(); });
                        } else {
                            Swal.fire('Lỗi', res.data.message, 'error');
                        }
                    }).fail(function() {
                        Swal.fire('Lỗi', 'Không thể kết nối đến máy chủ.', 'error');
                    });
                    break;
                } else if (result.dismiss === Swal.DismissReason.cancel) {
                    currentStep = 1;
                }
            }
        }
    }

    document.addEventListener('DOMContentLoaded', function() {
        runAeoSetupWizard();
    });
})();

// ============================================================================
// [PART 5] LICENSE PAGE - KEY INPUT MASKING & FORM LOADING STATE
// ============================================================================

(function() {
    function setupKeyInput(visualId, hiddenId) {
        var visualInput = document.getElementById(visualId);
        var hiddenInput = document.getElementById(hiddenId);
        if (!visualInput || !hiddenInput) return;

        visualInput.addEventListener('input', function(e) {
            var rawValue = e.target.value.replace(/[^a-fA-F0-9]/g, '');
            hiddenInput.value = rawValue.toLowerCase();
            var formatted = rawValue.toUpperCase().match(/.{1,4}/g);
            e.target.value = (formatted ? formatted.join('-') : rawValue.toUpperCase()).substring(0, 79);
        });

        if (visualId === 'eonsr_visual_license_key') visualInput.focus();
    }

    function handleFormSubmit(formId) {
        var form = document.getElementById(formId);
        if (!form) return;

        form.addEventListener('submit', function(e) {
            var btn = form.querySelector('.btn-submit-anim');
            if (!btn) return;

            if (btn.classList.contains('is-loading')) { e.preventDefault(); return; }

            btn.classList.add('is-loading');
            var textSpan = btn.querySelector('.btn-text');
            var iconSpan = btn.querySelector('.dashicons');
            var spinner  = btn.querySelector('.eonsr-aeo-spinner');

            if (iconSpan) iconSpan.style.display = 'none';
            if (textSpan) textSpan.innerText = 'Đang xử lý...';
            if (spinner)  spinner.style.display = 'block';

            document.querySelectorAll('.eonsr-aeo-btn').forEach(function(b) {
                b.style.pointerEvents = 'none';
                if (b !== btn) b.style.opacity = '0.5';
            });
        });
    }

    document.addEventListener('DOMContentLoaded', function() {
        setupKeyInput('eonsr_visual_license_key', 'eonsr_hidden_license_key');
        setupKeyInput('eonsr_visual_license_key_upgrade', 'eonsr_hidden_license_key_upgrade');
        handleFormSubmit('eonsr-form-activate-pro');
        handleFormSubmit('eonsr-form-activate-trial');
        handleFormSubmit('eonsr-form-upgrade-pro');
    });
})();

// ============================================================================
// [PART 4] WIZARD SETUP LOGIC
// Uses eonsr_aeo_wizard_data passed via wp_add_inline_script
// ============================================================================

(function() {
    if (typeof eonsr_aeo_wizard_data === 'undefined') return;

    const allLanguages = eonsr_aeo_wizard_data.allLanguages;
    const allCountries = eonsr_aeo_wizard_data.allCountries;
    const allStyles    = eonsr_aeo_wizard_data.allStyles;
    const langLimit    = eonsr_aeo_wizard_data.langLimit;
    const countryLimit = eonsr_aeo_wizard_data.countryLimit;
    const styleLimit   = eonsr_aeo_wizard_data.styleLimit;
    const setupNonce   = eonsr_aeo_wizard_data.setupNonce;

    // Helper: Filter Grid
    window.filterWizardGrid = function(inputId, gridId) {
        var input = document.getElementById(inputId);
        var filter = input.value.toLowerCase();
        var items = document.querySelectorAll('#' + gridId + ' .eonsr-aeo-wizard-item');
        items.forEach(function(item) {
            var nameElement = item.querySelector('.eonsr-aeo-item-name');
            var text = nameElement ? nameElement.textContent : item.textContent;
            item.style.display = text.toLowerCase().indexOf(filter) > -1 ? '' : 'none';
        });
    };

    // Helper: Build Grid
    function buildWizardGrid(items, name, searchId, listId, limit, selectedValues) {
        selectedValues = selectedValues || [];
        var html = '<div class="eonsr-aeo-wizard-search-box">' +
            '<span class="dashicons dashicons-search eonsr-aeo-wizard-search-icon"></span>' +
            '<input type="text" id="' + searchId + '" placeholder="Tìm kiếm..." onkeyup="filterWizardGrid(\'' + searchId + '\', \'' + listId + '\')">' +
            '</div><div id="' + listId + '" class="eonsr-aeo-wizard-grid">';

        var defaults = ['Vietnamese', 'English', 'VN', 'US'];

        Object.entries(items).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var isChecked = '';
            if (selectedValues.length > 0) {
                if (selectedValues.indexOf(key) > -1) isChecked = 'checked';
            } else {
                if (defaults.indexOf(key) > -1) isChecked = 'checked';
            }
            html += '<label class="eonsr-aeo-wizard-item" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="' + name + '" value="' + key + '" class="eonsr-aeo-setup-' + name + '" ' + isChecked + '>' +
                '<div class="eonsr-aeo-wizard-card">' +
                '<div class="eonsr-aeo-check-icon"></div>' +
                '<span style="font-size:18px;">' + data.flag + '</span>' +
                '<span class="eonsr-aeo-item-name">' + data.name + '</span>' +
                '</div></label>';
        });

        html += '</div>';
        return html;
    }

    // Helper: Build Style List
    function buildStyleList(styles) {
        var html = '<div class="eonsr-aeo-style-list">';
        Object.entries(styles).forEach(function(entry) {
            var key  = entry[0];
            var data = entry[1];
            var checked = (key === 'Mac dinh') ? 'checked' : '';
            var demoUrl = (data.url && data.url !== '#') ? data.url : 'javascript:void(0)';
            var target  = (data.url && data.url !== '#') ? 'target="_blank"' : '';
            var styleNameDisplay = data.name.split('(')[0];
            var styleTagMatch = data.name.match(/\(([^)]+)\)/);
            var styleTag = styleTagMatch ? styleTagMatch[1] : '';

            html += '<label class="eonsr-aeo-style-card-wrapper" onclick="event.stopPropagation()">' +
                '<input type="checkbox" name="style" value="' + key + '" class="eonsr-aeo-setup-style" ' + checked + ' style="position:absolute; opacity:0; width:0; height:0;">' +
                '<div class="eonsr-aeo-style-card">' +
                '<div class="eonsr-aeo-style-content">' +
                '<h4>' + styleNameDisplay + (styleTag ? ' <span class="eonsr-aeo-style-tag">' + styleTag + '</span>' : '') + '</h4>' +
                '<p>' + (data.desc || 'Phong cách viết chất lượng cao.') + '</p>' +
                '</div>' +
                '<a href="' + demoUrl + '" ' + target + ' class="eonsr-aeo-btn-preview" onclick="event.stopPropagation();">' +
                '<span class="dashicons dashicons-visibility"></span> Xem mẫu</a>' +
                '</div></label>';
        });
        html += '</div>';
        return html;
    }

    // Helper: Limit Enforcement
    function enforceLimit(className, limit, errorId, badgeId) {
        var container = Swal.getHtmlContainer();
        var inputs    = container.querySelectorAll('.' + className);
        var errorMsg  = container.querySelector('#' + errorId);
        var badge     = container.querySelector('#' + badgeId);

        inputs.forEach(function(input) {
            input.addEventListener('change', function() {
                var checkedCount = container.querySelectorAll('.' + className + ':checked').length;
                if (checkedCount > limit) {
                    this.checked = false;
                    if (errorMsg) {
                        errorMsg.innerText = 'Chỉ được chọn tối đa ' + limit + ' mục!';
                        errorMsg.classList.add('eonsr-aeo-error-show');
                    }
                    if (badge) badge.classList.add('eonsr-aeo-badge-error');
                    setTimeout(function() {
                        if (errorMsg) errorMsg.classList.remove('eonsr-aeo-error-show');
                        if (badge) badge.classList.remove('eonsr-aeo-badge-error');
                    }, 2000);
                }
            });
        });
    }

    // Main Wizard Loop
    async function runAeoSetupWizard() {
        var currentStep = 1;
        var cachedData  = { langs: [], countries: [] };

        while (true) {
            if (currentStep === 1) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 1/2: Chọn khu vực</span>',
                    width: '900px',
                    padding: '2em',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:20px;">Chọn ngôn ngữ và quốc gia mục tiêu để tối ưu hóa nội dung SEO.</p>' +
                        '<div class="eonsr-aeo-layout-row">' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Ngôn ngữ</span><span id="badge-lang" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + langLimit + '</span>' +
                        '<span id="error-lang" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allLanguages, 'lang', 'sLang', 'lLang', langLimit, cachedData.langs) +
                        '</div>' +
                        '<div class="eonsr-aeo-layout-col">' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0;"><div style="display:flex; align-items:center;">' +
                        '<span>Quốc gia</span><span id="badge-country" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + countryLimit + '</span>' +
                        '<span id="error-country" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildWizardGrid(allCountries, 'country', 'sCountry', 'lCountry', countryLimit, cachedData.countries) +
                        '</div></div></div>',
                    confirmButtonText: 'Tiếp theo &rarr;',
                    confirmButtonColor: '#2271b1',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-lang', langLimit, 'error-lang', 'badge-lang');
                        enforceLimit('eonsr-aeo-setup-country', countryLimit, 'error-country', 'badge-country');
                    },
                    preConfirm: function() {
                        var langs     = Array.from(document.querySelectorAll('.eonsr-aeo-setup-lang:checked')).map(function(c) { return c.value; });
                        var countries = Array.from(document.querySelectorAll('.eonsr-aeo-setup-country:checked')).map(function(c) { return c.value; });
                        if (langs.length === 0 || countries.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 Ngôn ngữ và 1 Quốc gia.');
                            return false;
                        }
                        return { langs: langs, countries: countries };
                    }
                });

                if (result.isConfirmed) {
                    cachedData.langs     = result.value.langs;
                    cachedData.countries = result.value.countries;
                    currentStep = 2;
                } else {
                    break;
                }
            }
            else if (currentStep === 2) {
                const result = await Swal.fire({
                    title: '<span style="font-weight:600; font-size:20px;">Bước 2/2: Chọn phong cách viết</span>',
                    width: '650px',
                    html: '<div class="eonsr-aeo-wizard-container">' +
                        '<p class="eonsr-aeo-wizard-desc" style="margin-bottom:10px;">Chọn các phong cách viết phù hợp với thương hiệu của bạn.</p>' +
                        '<div class="eonsr-aeo-wizard-section-title" style="margin-top:0; margin-bottom:15px;"><div style="display:flex; align-items:center;">' +
                        '<span>Phong cách</span><span id="badge-style" class="eonsr-aeo-wizard-limit-badge" style="margin-left:8px">Max ' + styleLimit + '</span>' +
                        '<span id="error-style" class="eonsr-aeo-inline-error"></span></div></div>' +
                        buildStyleList(allStyles) + '</div>',
                    confirmButtonText: 'Hoàn tất cài đặt <span class="dashicons dashicons-yes" style="vertical-align:middle"></span>',
                    confirmButtonColor: '#2271b1',
                    showCancelButton: true,
                    cancelButtonText: 'Quay lại',
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    allowEnterKey: false,
                    showCloseButton: false,
                    didOpen: function() {
                        enforceLimit('eonsr-aeo-setup-style', styleLimit, 'error-style', 'badge-style');
                    },
                    preConfirm: function() {
                        var styles = Array.from(document.querySelectorAll('.eonsr-aeo-setup-style:checked')).map(function(c) { return c.value; });
                        if (styles.length === 0) {
                            Swal.showValidationMessage('Vui lòng chọn ít nhất 1 phong cách.');
                            return false;
                        }
                        return styles;
                    }
                });

                if (result.isConfirmed) {
                    Swal.fire({ title: 'Đang lưu cấu hình...', html: 'Vui lòng không tắt trình duyệt.', allowOutsideClick: false, showConfirmButton: false, didOpen: function() { Swal.showLoading(); } });

                    jQuery.post(ajaxurl, {
                        action: 'eonsr_aeo_agent_save_initial_setup',
                        nonce: setupNonce,
                        languages: cachedData.langs,
                        countries: cachedData.countries,
                        styles: result.value
                    }).done(function(res) {
                        if (res.success) {
                            Swal.fire({ icon: 'success', title: 'Thành công!', text: 'Cài đặt ban đầu hoàn tất.', confirmButtonColor: '#2271b1' }).then(function() { window.location.reload(); });
                        } else {
                            Swal.fire('Lỗi', res.data.message, 'error');
                        }
                    }).fail(function() {
                        Swal.fire('Lỗi', 'Không thể kết nối đến máy chủ.', 'error');
                    });
                    break;
                } else if (result.dismiss === Swal.DismissReason.cancel) {
                    currentStep = 1;
                }
            }
        }
    }

    document.addEventListener('DOMContentLoaded', function() {
        runAeoSetupWizard();
    });
})();

// ============================================================================
// [PART 5] LICENSE PAGE - KEY INPUT MASKING & FORM LOADING STATE
// ============================================================================

(function() {
    function setupKeyInput(visualId, hiddenId) {
        var visualInput = document.getElementById(visualId);
        var hiddenInput = document.getElementById(hiddenId);
        if (!visualInput || !hiddenInput) return;

        visualInput.addEventListener('input', function(e) {
            var rawValue = e.target.value.replace(/[^a-fA-F0-9]/g, '');
            hiddenInput.value = rawValue.toLowerCase();
            var formatted = rawValue.toUpperCase().match(/.{1,4}/g);
            e.target.value = (formatted ? formatted.join('-') : rawValue.toUpperCase()).substring(0, 79);
        });

        if (visualId === 'eonsr_visual_license_key') visualInput.focus();
    }

    function handleFormSubmit(formId) {
        var form = document.getElementById(formId);
        if (!form) return;

        form.addEventListener('submit', function(e) {
            var btn = form.querySelector('.btn-submit-anim');
            if (!btn) return;

            if (btn.classList.contains('is-loading')) { e.preventDefault(); return; }

            btn.classList.add('is-loading');
            var textSpan = btn.querySelector('.btn-text');
            var iconSpan = btn.querySelector('.dashicons');
            var spinner  = btn.querySelector('.eonsr-aeo-spinner');

            if (iconSpan) iconSpan.style.display = 'none';
            if (textSpan) textSpan.innerText = 'Đang xử lý...';
            if (spinner)  spinner.style.display = 'block';

            document.querySelectorAll('.eonsr-aeo-btn').forEach(function(b) {
                b.style.pointerEvents = 'none';
                if (b !== btn) b.style.opacity = '0.5';
            });
        });
    }

    document.addEventListener('DOMContentLoaded', function() {
        setupKeyInput('eonsr_visual_license_key', 'eonsr_hidden_license_key');
        setupKeyInput('eonsr_visual_license_key_upgrade', 'eonsr_hidden_license_key_upgrade');
        handleFormSubmit('eonsr-form-activate-pro');
        handleFormSubmit('eonsr-form-activate-trial');
        handleFormSubmit('eonsr-form-upgrade-pro');
    });
})();

// ============================================================================
// [PART 6] PURCHASE PAGE - PLAN SELECTION & SWEETALERT LOGIC
// Uses eonsr_aeo_purchase_data passed via wp_localize_script
// ============================================================================

(function() {
    // Handle Plan Selection (called from onclick in PHP template)
    window.selectPlan = function(id, cardElement) {
        if (cardElement.classList.contains('is-current')) return;
        var radio = document.getElementById('radio_' + id);
        if (radio) {
            radio.checked = true;
            radio.dispatchEvent(new Event('change', { bubbles: true }));
        }
    };

    document.addEventListener('DOMContentLoaded', function() {
        var form         = document.getElementById('form-select-product');
        var totalDisplay = document.getElementById('display-total-price');

        function calculateTotal() {
            var total       = 0;
            var selectedPlan = document.querySelector('input[name="selected_product_id"]:checked');
            if (selectedPlan) {
                total += parseFloat(selectedPlan.getAttribute('data-price') || 0);
                var currentCard = selectedPlan.closest('.plan-card');
                if (currentCard) {
                    currentCard.querySelectorAll('.addon-checkbox:checked').forEach(function(cb) {
                        total += parseFloat(cb.getAttribute('data-price') || 0);
                    });
                }
            }
            if (totalDisplay) {
                totalDisplay.textContent = new Intl.NumberFormat('vi-VN').format(total) + ' đ';
            }
        }

        if (form) {
            form.addEventListener('change', function(e) {
                if (e.target.name === 'selected_product_id') {
                    document.querySelectorAll('.plan-card').forEach(function(card) {
                        if (!card.contains(e.target)) {
                            card.querySelectorAll('.addon-checkbox').forEach(function(cb) { cb.checked = false; });
                        }
                    });
                }
                calculateTotal();
            });
            calculateTotal();
        }

        // SweetAlert: Upgrade confirmation
        var btnUpgrade = document.getElementById('btn-process-payment');
        if (btnUpgrade && typeof eonsr_aeo_purchase_data !== 'undefined') {
            btnUpgrade.addEventListener('click', function(e) {
                var hasActiveLicense = eonsr_aeo_purchase_data.hasActiveLicense === '1';
                if (!hasActiveLicense) return;
                e.preventDefault();
                Swal.fire({
                    title: 'Xác nhận thay đổi',
                    text: 'Gói hiện tại sẽ bị hủy và thay thế ngay lập tức bởi gói mới.',
                    icon: 'info',
                    showCancelButton: true,
                    confirmButtonText: 'Đồng ý',
                    confirmButtonColor: '#667eea'
                }).then(function(r) {
                    if (r.isConfirmed) form.submit();
                });
            });
        }

        // SweetAlert: Cancel license
        var btnCancel = document.getElementById('btn-cancel-license');
        if (btnCancel) {
            btnCancel.addEventListener('click', function() {
                Swal.fire({
                    title: 'Gỡ License?',
                    text: 'Website sẽ mất tính năng PRO.',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonColor: '#ef4444',
                    confirmButtonText: 'Gỡ bỏ'
                }).then(function(r) {
                    if (r.isConfirmed) document.getElementById('form-cancel-license').submit();
                });
            });
        }
    });
})();
}); 