(function ($) {
    'use strict';

    const $button = $('#shrinkwell-start-bulk');
    const $testButton = $('#shrinkwell-start-test-bulk');
    const $pause = $('#shrinkwell-pause-bulk');
    const $bulkFlow = $('#shrinkwell-bulk-flow');
    const $flowDots = $('.shrinkwell-flow-dot');
    const $flowLabel = $('#shrinkwell-flow-label');
    const $progress = $('.shrinkwell-progress');
    const $bar = $('.shrinkwell-progress .shrinkwell-progress-bar span');
    const $text = $('#shrinkwell-progress-text');
    const $detail = $('#shrinkwell-progress-detail');
    const $currentImage = $('#shrinkwell-current-image');
    const $runErrors = $('#shrinkwell-run-errors');
    const $bulkMeter = $('#shrinkwell-bulk-meter');
    const $progressPercent = $('#shrinkwell-progress-percent');
    const $progressLabel = $('#shrinkwell-progress-label');
    const $runSaved = $('#shrinkwell-run-saved');
    const $runErrorCount = $('#shrinkwell-run-error-count');
    const $runDoneCount = $('#shrinkwell-run-done-count');
    const $runSkippedValues = $('.shrinkwell-run-skipped-value');
    const $runSavedValues = $('.shrinkwell-run-saved-value');
    const $runSavedStat = $('.shrinkwell-run-saved-stat, .shrinkwell-bulk-card-saved');
    const $runSkippedStat = $('.shrinkwell-bulk-card-skipped');
    const $bulkState = $('.shrinkwell-bulk-state');
    const $bulkNextStep = $('#shrinkwell-bulk-next-step');
    const $resultErrorText = $('#shrinkwell-result-error-text');
    const $completionBanner = $('#shrinkwell-completion-banner');
    const $completionSummary = $('#shrinkwell-completion-summary');
    const $webpRebuildStatus = $('.shrinkwell-webp-rebuild-status');
    const $stats = $('.shrinkwell-stats');
    const $deliveryButton = $('#shrinkwell-run-delivery-test');
    const $deliveryResults = $('#shrinkwell-delivery-test-results');
    const $frontendProofButton = $('#shrinkwell-run-frontend-proof-scan');
    const $frontendProofResults = $('#shrinkwell-frontend-proof-results');
    const $seoButton = $('#shrinkwell-run-seo-scan');
    const $seoResults = $('#shrinkwell-seo-results');
    const $zeroSavingsPanel = $('.shrinkwell-zero-savings-panel');
    const $zeroSavingsButton = $('#shrinkwell-scan-zero-savings');
    const $zeroSavingsSpinner = $('#shrinkwell-zero-savings-spinner');
    const $zeroSavingsStatus = $('#shrinkwell-zero-savings-status');
    const $zeroSavingsResults = $('#shrinkwell-zero-savings-results');
    const $backupCleanupButton = $('#shrinkwell-check-old-backups');
    const $backupDeleteButton = $('#shrinkwell-delete-checked-backups');
    const $backupCheckResult = $('#shrinkwell-backup-check-result');
    const $backupCheckSummary = $('#shrinkwell-backup-check-summary');
    const $backupCleanupStatus = $('#shrinkwell-backup-cleanup-status');
    const $cleanupScanButton = $('#shrinkwell-cleanup-scan');
    const $cleanupSpinner = $('#shrinkwell-cleanup-spinner');
    const $cleanupStatus = $('#shrinkwell-cleanup-status');
    const $cleanupProgress = $('#shrinkwell-cleanup-progress');
    const $cleanupResults = $('#shrinkwell-cleanup-results');
    const $cleanupRows = $('#shrinkwell-cleanup-rows');
    const $cleanupSelected = $('#shrinkwell-cleanup-selected');
    const $cleanupSelectionHelp = $('#shrinkwell-cleanup-selection-help');
    const $cleanupTrashButton = $('#shrinkwell-cleanup-trash-selected');
    const $cleanupSelectAll = $('#shrinkwell-cleanup-select-all');
    const $trashActionStatus = $('#shrinkwell-trash-action-status');
    const $recommendationButton = $('#shrinkwell-run-recommendation-scan');
    const $recommendationResults = $('#shrinkwell-recommendation-results');
    const $profileTitle = $('#shrinkwell-profile-title');
    const $profileDescription = $('#shrinkwell-profile-description');
    const $activeQuality = $('#shrinkwell-active-quality');
    const $customQuality = $('#shrinkwell-custom-quality');
    const $customStrength = $('#shrinkwell-custom-strength');
    const $customControls = $('.shrinkwell-custom-controls');
    const $customStrengthValue = $('#shrinkwell-custom-strength-value');
    const $customStrengthMeaning = $('#shrinkwell-custom-strength-meaning');
    const $customStrengthDescription = $('#shrinkwell-custom-strength-description');
    const $stickySave = $('#shrinkwell-sticky-save');
    let lastRecommendedSettings = null;
    const startLabel = $.trim($button.text());
    const testStartLabel = $.trim($testButton.text());
    let paused = false;
    let queue = [];
    let processed = 0;
    let expectedTotal = 0;
    let savedBytes = 0;
    let errors = 0;
    let skipped = 0;
    let processedIds = [];
    let runLimit = null;
    let runWebpOnly = false;
    let isBulkRunning = false;
    let runErrorItems = [];
    let zeroSavingsItems = [];
    let $activeWebpRebuildButton = $();
    let webpRebuildButtonLabel = '';
    let completionReloadTimer = null;
    let backupCleanupCheck = null;
    let pendingCleanupAction = null;

    function showMonthlyLimitModal() {
        $('.shrinkwell-limit-modal').remove();
        $('body').addClass('shrinkwell-limit-modal-open').append(
            '<div class="shrinkwell-limit-modal" role="dialog" aria-modal="true" aria-labelledby="shrinkwell-limit-modal-title">' +
                '<div class="shrinkwell-limit-modal-card">' +
                    '<button type="button" class="shrinkwell-limit-modal-x" aria-label="' + escapeHtml(shrinkwellAdmin.maybeLaterText) + '">&times;</button>' +
                    '<h2 id="shrinkwell-limit-modal-title">' + escapeHtml(shrinkwellAdmin.monthlyLimitReachedTitleText) + '</h2>' +
                    '<p>' + escapeHtml(shrinkwellAdmin.monthlyLimitReachedDetailText) + '</p>' +
                    '<p>' + escapeHtml(shrinkwellAdmin.monthlyLimitReachedUpgradeText) + '</p>' +
                    '<div class="shrinkwell-limit-modal-actions">' +
                        '<button type="button" class="button shrinkwell-limit-modal-close">' + escapeHtml(shrinkwellAdmin.maybeLaterText) + '</button>' +
                        '<a class="button button-primary" href="' + escapeHtml(shrinkwellAdmin.upgradeUrl) + '">' + escapeHtml(shrinkwellAdmin.upgradeToProText) + '</a>' +
                    '</div>' +
                '</div>' +
            '</div>'
        );
    }

    function closeMonthlyLimitModal() {
        $('body').removeClass('shrinkwell-limit-modal-open');
        $('.shrinkwell-limit-modal').remove();
    }

    function setProgress(done, total, message) {
        const percent = total ? Math.round((done / total) * 100) : 0;
        $progress.prop('hidden', false);
        $bar.css('width', percent + '%');
        $text.text(message || done + ' / ' + total);
        let detail = formatBytes(savedBytes) + ' ' + shrinkwellAdmin.savedText + ' - ' + skipped + ' ' + shrinkwellAdmin.skippedText;
        if (errors) {
            detail += ' - ' + errors + ' ' + shrinkwellAdmin.errorsText;
        }
        $detail.text(detail);
        $bulkMeter.css('--shrinkwell-progress', percent + '%');
        $bulkMeter.toggleClass('is-running', isBulkRunning && percent < 100);
        $progressPercent.text(percent + '%');
        $progressLabel.text(total ? done + ' / ' + total : shrinkwellAdmin.scanText);
        $runDoneCount.text(done);
        $runSaved.text(formatBytes(savedBytes));
        $runErrorCount.text(skipped + errors);
        $runSkippedValues.text(skipped + errors);
        $runSavedValues.text(formatBytes(savedBytes));
        $runSavedStat.prop('hidden', savedBytes <= 0);
        $runSkippedStat.prop('hidden', skipped + errors <= 0);
        if (runWebpOnly) {
            setWebpRebuildStatus((message || shrinkwellAdmin.webpOnlyRunningText) + (total ? ' ' + done + ' / ' + total : ''), 'running');
        }
    }

    function setFlowState(state) {
        if (!$bulkFlow.length) {
            return;
        }

        const labels = {
            idle: shrinkwellAdmin.idleStepText,
            testing: shrinkwellAdmin.testingStepText,
            'result-ok': shrinkwellAdmin.resultStepText,
            'result-error': shrinkwellAdmin.resultStepText,
            running: shrinkwellAdmin.runningStepText,
            paused: shrinkwellAdmin.pausedStepText,
            proof: shrinkwellAdmin.proofStepText
        };
        const step = {
            idle: 0,
            testing: 0,
            'result-ok': 1,
            'result-error': 1,
            running: 2,
            paused: 2,
            proof: 3
        }[state] || 0;

        $bulkFlow.attr('data-state', state);
        $flowLabel.text(labels[state] || labels.idle);
        $flowDots.each(function (index) {
            $(this).toggleClass('is-active', index === step).toggleClass('is-done', index < step);
        });
    }

    function setBulkState(label, active) {
        if (!$bulkState.length) {
            return;
        }

        $bulkState.toggleClass('is-active', !!active);
        $bulkState.contents().filter(function () {
            return this.nodeType === 3;
        }).remove();
        $bulkState.append(document.createTextNode(label || shrinkwellAdmin.readyText));
    }

    function setWebpRebuildStatus(message, state) {
        if (!$webpRebuildStatus.length) {
            return;
        }

        $webpRebuildStatus
            .prop('hidden', false)
            .removeClass('is-running is-done is-error')
            .addClass(state ? 'is-' + state : '')
            .text(message || '');
    }

    function resetWebpRebuildButton() {
        if (!$activeWebpRebuildButton.length) {
            return;
        }

        $activeWebpRebuildButton
            .prop('disabled', false)
            .text(webpRebuildButtonLabel || shrinkwellAdmin.webpOnlyDoneText);
        $activeWebpRebuildButton = $();
        webpRebuildButtonLabel = '';
    }

    function showBulkNextStep(type) {
        if (!$bulkNextStep.length) {
            return;
        }

        const needsReview = type === 'review';
        const title = needsReview ? shrinkwellAdmin.testReviewTitleText : shrinkwellAdmin.testCompleteTitleText;
        const detail = needsReview ? shrinkwellAdmin.testReviewDetailText : shrinkwellAdmin.testCompleteDetailText;
        const saving = savedBytes > 0 ? '<span class="shrinkwell-result-saving">~' + escapeHtml(formatBytes(savedBytes)) + '</span>' : '';
        let actions = '<div class="shrinkwell-result-actions">';
        if (needsReview) {
            actions += '<a class="button button-primary" href="' + escapeHtml(shrinkwellAdmin.settingsUrl) + '">' + escapeHtml(shrinkwellAdmin.settingsButtonText) + '</a>';
            actions += '<button type="button" class="button-link" id="shrinkwell-force-bulk">' + escapeHtml(shrinkwellAdmin.skipAndContinueText) + '</button>';
        } else {
            actions += '<a class="button" href="' + escapeHtml(shrinkwellAdmin.settingsUrl) + '">' + escapeHtml(shrinkwellAdmin.settingsButtonText) + '</a>';
            actions += '<button type="button" class="button button-primary" id="shrinkwell-result-start-bulk">' + escapeHtml(shrinkwellAdmin.optimizeAllButtonText) + '</button>';
        }
        actions += '</div>';
        $bulkNextStep
            .prop('hidden', false)
            .toggleClass('is-review', needsReview)
            .toggleClass('is-ok', !needsReview)
            .html('<strong>' + escapeHtml(title) + '</strong><span>' + escapeHtml(detail) + '</span>' + saving + actions);
        if (needsReview && runErrorItems[0] && runErrorItems[0].message) {
            $resultErrorText.text(runErrorItems[0].message);
        }
    }

    function formatBytes(bytes) {
        if (!bytes) {
            return '0 B';
        }

        const units = ['B', 'KB', 'MB', 'GB'];
        let value = bytes;
        let unit = 0;

        while (value >= 1024 && unit < units.length - 1) {
            value = value / 1024;
            unit++;
        }

        return value.toFixed(unit ? 1 : 0) + ' ' + units[unit];
    }

    function escapeHtml(value) {
        return String(value).replace(/[&<>"']/g, function (character) {
            return {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            }[character];
        });
    }

    function formatText(template) {
        const values = Array.prototype.slice.call(arguments, 1);
        let sequentialIndex = 0;

        return String(template || '').replace(/%(\d+\$)?s/g, function (match, position) {
            const index = position ? parseInt(position, 10) - 1 : sequentialIndex++;
            return typeof values[index] === 'undefined' ? match : values[index];
        });
    }

    function zeroSavingsReasonLabel(reason) {
        const labels = {
            already_small: shrinkwellAdmin.zeroSavingsAlreadySmallText,
            already_webp: shrinkwellAdmin.zeroSavingsAlreadyWebpText,
            encoder_skipped: shrinkwellAdmin.zeroSavingsEncoderSkippedText,
            large_png: shrinkwellAdmin.zeroSavingsLargePngText,
            resize_skipped: shrinkwellAdmin.zeroSavingsResizeSkippedText,
            unknown: shrinkwellAdmin.zeroSavingsUnknownText
        };

        return labels[reason] || shrinkwellAdmin.zeroSavingsUnknownText;
    }

    function zeroSavingsFilterMatches(item, filter) {
        if (filter === 'all') {
            return true;
        }

        if (filter === 'skipped') {
            return item.reason === 'encoder_skipped' || item.reason === 'resize_skipped';
        }

        return item.reason === filter;
    }

    function zeroSavingsSummaryText(summary, total) {
        const parts = [
            (summary.already_small || 0) + 'x ' + shrinkwellAdmin.zeroSavingsAlreadySmallText,
            (summary.already_webp || 0) + 'x ' + shrinkwellAdmin.zeroSavingsAlreadyWebpText,
            (summary.encoder_skipped || 0) + 'x ' + shrinkwellAdmin.zeroSavingsEncoderSkippedText,
            (summary.large_png || 0) + 'x ' + shrinkwellAdmin.zeroSavingsLargePngText,
            (summary.resize_skipped || 0) + 'x ' + shrinkwellAdmin.zeroSavingsResizeSkippedText,
            (summary.unknown || 0) + 'x ' + shrinkwellAdmin.zeroSavingsUnknownText
        ];

        return formatText(shrinkwellAdmin.zeroSavingsSummaryText, total, parts.join(' | '));
    }

    function selectedZeroSavingsIds() {
        return $zeroSavingsResults.find('.shrinkwell-zero-savings-check:checked').map(function () {
            return parseInt($(this).val(), 10);
        }).get().filter(Boolean);
    }

    function renderZeroSavingsTable(items, summary) {
        const total = items.length;

        if (!total) {
            $zeroSavingsResults.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.zeroSavingsEmptyText) + '</p>');
            return;
        }

        let html = '<div class="shrinkwell-zero-savings-summary">' + escapeHtml(zeroSavingsSummaryText(summary || {}, total)) + '</div>';
        html += '<div class="shrinkwell-zero-savings-filters" role="group">';
        [
            ['all', shrinkwellAdmin.zeroSavingsAllText],
            ['already_small', shrinkwellAdmin.zeroSavingsAlreadySmallText],
            ['already_webp', shrinkwellAdmin.zeroSavingsAlreadyWebpText],
            ['large_png', shrinkwellAdmin.zeroSavingsLargePngText],
            ['skipped', shrinkwellAdmin.zeroSavingsSkippedText],
            ['unknown', shrinkwellAdmin.zeroSavingsUnknownText]
        ].forEach(function (filter) {
            html += '<button type="button" class="button button-small shrinkwell-zero-filter' + (filter[0] === 'all' ? ' is-active' : '') + '" data-filter="' + escapeHtml(filter[0]) + '">' + escapeHtml(filter[1]) + '</button>';
        });
        html += '</div>';
        html += '<table class="widefat striped shrinkwell-zero-savings-table"><thead><tr>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsThumbnailText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.filenameText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsOriginalSizeText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsSavedText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsPercentText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsReasonText) + '</th>';
        html += '<th>' + escapeHtml(shrinkwellAdmin.zeroSavingsSelectText) + '</th>';
        html += '</tr></thead><tbody>';

        items.forEach(function (item) {
            const reason = item.reason || 'unknown';
            html += '<tr data-reason="' + escapeHtml(reason) + '">';
            html += '<td>';
            if (item.thumbnail_url) {
                html += '<img src="' + escapeHtml(item.thumbnail_url) + '" alt="">';
            }
            html += '</td>';
            html += '<td>' + escapeHtml(item.filename || '') + '</td>';
            html += '<td>' + escapeHtml(formatBytes(item.original_size || 0)) + '</td>';
            html += '<td>' + escapeHtml(formatBytes(item.savings_bytes || 0)) + '</td>';
            html += '<td>' + escapeHtml((parseFloat(item.savings_pct || 0)).toFixed(1) + '%') + '</td>';
            html += '<td><span class="shrinkwell-zero-reason shrinkwell-zero-reason-' + escapeHtml(reason) + '">' + escapeHtml(zeroSavingsReasonLabel(reason)) + '</span></td>';
            html += '<td><input type="checkbox" class="shrinkwell-zero-savings-check" value="' + escapeHtml(item.attachment_id || '') + '"></td>';
            html += '</tr>';
        });

        html += '</tbody></table>';
        html += '<p class="shrinkwell-zero-savings-bulk-actions">';
        html += '<button type="button" class="button" id="shrinkwell-select-visible-zero-savings">' + escapeHtml(shrinkwellAdmin.zeroSavingsSelectVisibleText) + '</button>';
        html += '<button type="button" class="button button-primary" id="shrinkwell-force-reoptimize-selected">' + escapeHtml(shrinkwellAdmin.forceReoptimizeText) + '</button>';
        html += '<button type="button" class="button" id="shrinkwell-dismiss-zero-savings">' + escapeHtml(shrinkwellAdmin.zeroSavingsDismissAllText) + '</button>';
        html += '<span class="shrinkwell-zero-savings-action-status" aria-live="polite"></span>';
        html += '</p>';

        $zeroSavingsResults.prop('hidden', false).html(html);
    }

    function copyToClipboard(text, $feedback) {
        if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(text).then(function () {
                $feedback.text(shrinkwellAdmin.proofReportCopiedText);
            }).catch(function () {
                fallbackCopyToClipboard(text, $feedback);
            });
            return;
        }

        fallbackCopyToClipboard(text, $feedback);
    }

    function fallbackCopyToClipboard(text, $feedback) {
        const $textarea = $('<textarea readonly>')
            .val(text)
            .css({
                position: 'fixed',
                top: '-9999px',
                left: '-9999px'
            })
            .appendTo('body');

        $textarea[0].select();
        document.execCommand('copy');
        $textarea.remove();
        $feedback.text(shrinkwellAdmin.proofReportCopiedText);
    }

    function downloadTextFile(filename, text) {
        const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');

        link.href = url;
        link.download = filename;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
    }

    function proofReportFilename() {
        return 'shrinkwell-page-proof-' + new Date().toISOString().slice(0, 10) + '.txt';
    }

    function mediaActionStatus($link) {
        const $proof = $link.closest('.shrinkwell-media-proof');

        if ($proof.length) {
            return $proof.find('.shrinkwell-media-action-status').first();
        }

        let $status = $link.siblings('.shrinkwell-media-action-status, .shrinkwell-media-test-status').first();

        if (!$status.length) {
            $status = $('<span class="shrinkwell-media-action-status" aria-live="polite"></span>');
            $link.after($status);
        }

        return $status;
    }

    function deliveryResultHtml(data) {
        const checks = data.checks || [];
        let html = '<p><strong>' + escapeHtml(shrinkwellAdmin.testDoneText) + '</strong></p>';
        html += '<p class="' + (data.passed ? 'shrinkwell-check-ok' : 'shrinkwell-check-warn') + '"><strong>' + escapeHtml(data.passed ? shrinkwellAdmin.testPassedText : shrinkwellAdmin.testNeedsWorkText) + '</strong></p>';
        html += '<p>' + escapeHtml(data.title || '') + '</p>';
        html += '<ul>';

        checks.forEach(function (check) {
            html += '<li class="' + (check.ok ? 'shrinkwell-check-ok' : 'shrinkwell-check-warn') + '">' + escapeHtml(check.label) + '</li>';
        });

        html += '</ul><p class="description">' + escapeHtml(data.message || '') + '</p>';

        return html;
    }

    function runDeliveryTest($target, doneCallback) {
        $target.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.deliveryReadinessCheckingText) + '</p>');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_delivery_test',
            nonce: shrinkwellAdmin.nonce
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $target.html('<p class="shrinkwell-test-error">' + escapeHtml(message) + '</p>');
                return;
            }

            $target.html(deliveryResultHtml(response.data || {}));
        }).fail(function () {
            $target.html('<p class="shrinkwell-test-error">' + escapeHtml(shrinkwellAdmin.errorText) + '</p>');
        }).always(function () {
            if (typeof doneCallback === 'function') {
                doneCallback();
            }
        });
    }

    function getProofNextSteps(data) {
        const estimate = data.estimate || {};
        const rewritePreview = data.rewritePreview || {};
        const steps = [];

        if (data.passed) {
            steps.push(shrinkwellAdmin.proofNextStepPassedText);
        }

        if (rewritePreview.wouldImprove) {
            steps.push(shrinkwellAdmin.proofNextStepRewriteText);
        }

        if (data.cacheWarning || (data.filesReady && (estimate.uncoveredReady || 0) > 0)) {
            steps.push(shrinkwellAdmin.proofNextStepCacheText);
        }

        if (data.backgroundSamples && data.backgroundSamples.length) {
            steps.push(shrinkwellAdmin.proofNextStepBackgroundText);
        }

        if (estimate.uncoveredSamples && estimate.uncoveredSamples.length) {
            steps.push(shrinkwellAdmin.proofNextStepManualText);
        }

        if (!steps.length) {
            steps.push(shrinkwellAdmin.proofNextStepPassedText);
        }

        return steps;
    }

    function getProofCacheChecklistItems() {
        return [
            shrinkwellAdmin.cacheChecklistWordPressText,
            shrinkwellAdmin.cacheChecklistDiviText,
            shrinkwellAdmin.cacheChecklistHostText,
            shrinkwellAdmin.cacheChecklistBrowserText
        ].filter(Boolean);
    }

    function getProofPlainVerdict(data) {
        const estimate = data.estimate || {};

        if (data.passed) {
            return {
                type: 'good',
                title: shrinkwellAdmin.proofPlainGoodTitleText,
                detail: shrinkwellAdmin.proofPlainGoodDetailText
            };
        }

        if (!data.filesReady && (estimate.checked || 0) > 0) {
            return {
                type: 'warn',
                title: shrinkwellAdmin.proofPlainMissingTitleText,
                detail: shrinkwellAdmin.proofPlainMissingDetailText
            };
        }

        if (data.filesReady && ((estimate.uncoveredReady || 0) > 0 || data.cacheWarning)) {
            return {
                type: 'warn',
                title: shrinkwellAdmin.proofPlainReadyTitleText,
                detail: shrinkwellAdmin.proofPlainReadyDetailText
            };
        }

        if (data.backgroundSamples && data.backgroundSamples.length) {
            return {
                type: 'warn',
                title: shrinkwellAdmin.proofPlainBackgroundTitleText,
                detail: shrinkwellAdmin.proofPlainBackgroundDetailText
            };
        }

        return {
            type: 'warn',
            title: shrinkwellAdmin.proofPlainUnknownTitleText,
            detail: shrinkwellAdmin.proofPlainUnknownDetailText
        };
    }

    function buildProofReport(data) {
        const estimate = data.estimate || {};
        const rewritePreview = data.rewritePreview || {};
        const diagnosis = data.diagnosis || {};
        const checks = data.checks || [];
        const cacheHeaders = data.cacheHeaders || [];
        const verdict = getProofPlainVerdict(data);
        let evidenceLabel = shrinkwellAdmin.proofEvidenceNotDetectedText;

        if (data.passed) {
            evidenceLabel = shrinkwellAdmin.proofEvidenceFoundText;
        } else if (data.partial || data.webpEvidenceFound) {
            evidenceLabel = shrinkwellAdmin.proofEvidencePartialText;
        }

        const lines = [
            shrinkwellAdmin.proofReportTitleText,
            '============================',
            shrinkwellAdmin.proofReportSiteText + ' ' + (shrinkwellAdmin.siteUrl || ''),
            shrinkwellAdmin.proofReportPageScannedText + ' ' + (data.url || $('#shrinkwell-proof-url').val() || ''),
            shrinkwellAdmin.proofReportDateText + ' ' + new Date().toLocaleString(),
            shrinkwellAdmin.proofReportPluginVersionText + ' ' + (shrinkwellAdmin.pluginVersion || ''),
            '',
            shrinkwellAdmin.proofReportSimpleResultText,
            '- ' + (verdict.title || ''),
            '- ' + (verdict.detail || ''),
            ''
        ];

        if (!data.passed || data.cacheWarning) {
            lines.push(shrinkwellAdmin.proofDoThisFirstText + ':');
            getProofCacheChecklistItems().forEach(function (step) {
                lines.push('- ' + step);
            });
            lines.push('- ' + shrinkwellAdmin.proofThenText);
            lines.push('');
        }

        if (estimate.uncoveredSamples && estimate.uncoveredSamples.length) {
            lines.push(shrinkwellAdmin.proofImagesToReviewText + ':');
            estimate.uncoveredSamples.forEach(function (sample) {
                lines.push('- ' + (sample.file || sample.url || ''));
            });
            lines.push('');
        }

        if (data.backgroundSamples && data.backgroundSamples.length) {
            lines.push(shrinkwellAdmin.proofBackgroundImagesToReviewText);
            data.backgroundSamples.forEach(function (sample) {
                lines.push('- ' + sample);
            });
            lines.push('');
        }

        lines.push(shrinkwellAdmin.proofTechnicalDetailsText + ':');
        lines.push('- ' + shrinkwellAdmin.proofWebpEvidenceText + ' ' + evidenceLabel);
        lines.push('- ' + shrinkwellAdmin.proofWebpDeliveryCoverageText + ' ' + (estimate.coveragePercent || 0) + '%');
        lines.push('- ' + shrinkwellAdmin.proofWebpFilesReadyText + ' ' + (data.filesReady ? shrinkwellAdmin.proofYesText : shrinkwellAdmin.proofNoText));
        lines.push('- ' + formatText(shrinkwellAdmin.proofUsableWebpUrlsText, estimate.webpReady || 0, estimate.checked || 0));
        lines.push('- ' + shrinkwellAdmin.proofEstimatedSavedPayloadText + ' ' + (estimate.savedFormatted || '0 B'));
        lines.push('- ' + shrinkwellAdmin.proofOriginalPayloadCheckedText + ' ' + (estimate.originalFormatted || '0 B'));
        lines.push('- ' + shrinkwellAdmin.proofWebpPayloadAvailableText + ' ' + (estimate.webpFormatted || '0 B'));
        lines.push('- ' + shrinkwellAdmin.proofExistingWebpFilesFoundText + ' ' + (estimate.webpExisting || estimate.webpReady || 0));
        lines.push('- ' + shrinkwellAdmin.proofWebpFilesLargerThanOriginalText + ' ' + (estimate.largerWebp || 0));
        lines.push('- ' + shrinkwellAdmin.proofIgnoredSiteIconUrlsText + ' ' + (estimate.ignoredNonContentImages || 0));
        lines.push('');

        if (diagnosis.title || diagnosis.detail || diagnosis.action) {
            lines.push(shrinkwellAdmin.proofDiagnosisTitleText + ':');
            [diagnosis.title, diagnosis.detail, diagnosis.action].forEach(function (item) {
                if (item) {
                    lines.push('- ' + item);
                }
            });
            lines.push('');
        }

        if (rewritePreview.wouldImprove) {
            lines.push(shrinkwellAdmin.proofRewritePreviewTitleText + ':');
            lines.push('- ' + shrinkwellAdmin.proofRewritePreviewCanAddText);
            lines.push('- ' + shrinkwellAdmin.proofCoverageAfterPreviewText + ' ' + (rewritePreview.coverageAfter || 0) + '%');
            lines.push('- ' + shrinkwellAdmin.proofUncoveredAfterPreviewText + ' ' + (rewritePreview.uncoveredAfter || 0));
            lines.push('');
        }

        if (cacheHeaders.length) {
            lines.push(shrinkwellAdmin.proofCacheHeadersSawText);
            cacheHeaders.forEach(function (header) {
                lines.push('- ' + (header.name || '') + ': ' + (header.value || ''));
            });
            lines.push('');
        }

        if (checks.length) {
            lines.push(shrinkwellAdmin.proofChecksText);
            checks.forEach(function (check) {
                lines.push('- ' + (check.label || '') + ': ' + (check.value || (check.ok ? shrinkwellAdmin.proofOkText : shrinkwellAdmin.needsAttentionText)));
            });
            lines.push('');
        }

        if (estimate.largerWebpSamples && estimate.largerWebpSamples.length) {
            lines.push(shrinkwellAdmin.proofExistingLargerWebpText);
            estimate.largerWebpSamples.forEach(function (sample) {
                lines.push('- ' + (sample.file || sample.url || '') + ' (' + formatText(shrinkwellAdmin.proofOriginalWebpSizeText, sample.original || '0 B', sample.webp || '0 B') + ')');
            });
            lines.push('');
        }

        lines.push(shrinkwellAdmin.proofGeneratedByText);

        return lines.join('\n');
    }

    function decodeHtml(value) {
        return $('<textarea>').html(value || '').text();
    }

    function compactErrorMessage(message) {
        const cleanMessage = decodeHtml(message || shrinkwellAdmin.errorText);

        if (cleanMessage === shrinkwellAdmin.serverStoppedText || cleanMessage.indexOf('server stopped') !== -1) {
            return shrinkwellAdmin.serverStoppedShortText;
        }

        if (cleanMessage.indexOf('Image skipped:') === 0) {
            return cleanMessage;
        }

        if (cleanMessage.indexOf('very large dimensions') !== -1 || cleanMessage.indexOf('too large for safe local processing') !== -1) {
            return shrinkwellAdmin.largeImageShortText;
        }

        return cleanMessage;
    }

    function compactRunTitle(title) {
        const cleanTitle = decodeHtml(title || '');

        if (cleanTitle.length <= 52) {
            return cleanTitle;
        }

        return cleanTitle.substring(0, 49) + '...';
    }

    function strengthToQuality(strength) {
        const safeStrength = Math.min(10, Math.max(1, parseInt(strength, 10) || 5));

        return Math.min(95, Math.max(40, Math.round(95 - (((safeStrength - 1) / 9) * 55))));
    }

    function updateCustomStrength() {
        if (!$customStrength.length) {
            return;
        }

        const strength = Math.min(10, Math.max(1, parseInt($customStrength.val(), 10) || 5));
        const quality = strengthToQuality(strength);
        let meaning = shrinkwellAdmin.balancedStrengthText;
        let description = shrinkwellAdmin.customMediumText;

        if (strength <= 3) {
            meaning = shrinkwellAdmin.qualityStrengthText;
            description = shrinkwellAdmin.customQualityText;
        } else if (strength >= 8) {
            meaning = shrinkwellAdmin.smallFilesStrengthText;
            description = shrinkwellAdmin.customStrongRiskText;
        } else if (strength >= 6) {
            description = shrinkwellAdmin.customStrongRiskText;
        }

        $customQuality.val(quality);
        $customStrengthValue.text(strength + '/10');
        $customStrengthMeaning.text(meaning);
        $customStrengthDescription.text(description);
    }

    function updateCompressionHelp() {
        const $selected = $('input[name="shrinkwell_settings[compression_profile]"]:checked');

        if (!$selected.length) {
            return;
        }

        const label = $selected.data('label');
        const description = $selected.data('description');
        const quality = $selected.val() === 'custom' ? $customQuality.val() : $selected.data('quality');
        const isCustom = $selected.val() === 'custom';

        $profileTitle.text(formatText(shrinkwellAdmin.selectedProfileText, label));
        $profileDescription.text(description);
        $activeQuality.val(quality);
        $customControls.toggle(isCustom);
    }

    function bulkFilters() {
        return {
            only_large: 0,
            min_kb: 500,
            date_from: '',
            date_to: '',
            reoptimize: 0,
            webp_only: runWebpOnly ? 1 : 0
        };
    }

    function addRunError(title, message) {
        if (!$runErrors.length) {
            return;
        }

        $runErrors.prop('hidden', false);
        runErrorItems.push({
            title: decodeHtml(title || shrinkwellAdmin.imageText),
            message: compactErrorMessage(message)
        });

        renderRunErrors();
    }

    function renderRunErrors() {
        const $list = $runErrors.find('ul');
        const visibleItems = runErrorItems.slice(0, 8);

        $runErrors.find('.shrinkwell-run-errors-summary').remove();
        $runErrors.find('.shrinkwell-run-errors-reason').remove();
        $list.empty();

        $('<p class="shrinkwell-run-errors-summary">')
            .text(runErrorItems.length + ' ' + shrinkwellAdmin.skippedSummaryText)
            .insertAfter($runErrors.find('strong').first());

        if (runErrorItems[0] && runErrorItems[0].message) {
            $('<p class="shrinkwell-run-errors-reason">')
                .text(runErrorItems[0].message)
                .insertBefore($list);
        }

        visibleItems.forEach(function (item) {
            $('<li>').text(item.title).appendTo($list);
        });

        if (runErrorItems.length > visibleItems.length) {
            $('<li class="shrinkwell-run-errors-more">')
                .text('+' + (runErrorItems.length - visibleItems.length) + ' ' + shrinkwellAdmin.moreSkippedText)
                .appendTo($list);
        }
    }

    function recordClientError(id, title, message) {
        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_log_client_error',
            nonce: shrinkwellAdmin.nonce,
            attachment_id: id || 0,
            title: title || '',
            message: message || shrinkwellAdmin.errorText
        });
    }

    function setCurrentImage(prefix, title) {
        if (!title) {
            $currentImage.prop('hidden', true).text('');
            return;
        }

        $currentImage.prop('hidden', false).text(prefix + ' ' + decodeHtml(title));
    }

    function finish() {
        const finishedTestRun = !!runLimit && !runWebpOnly;
        const finishedWebpOnly = runWebpOnly;
        const needsReview = errors > 0 || skipped > 0 || runErrorItems.length > 0;
        setProgress(expectedTotal || 1, expectedTotal || 1, runWebpOnly ? shrinkwellAdmin.webpOnlyDoneText : shrinkwellAdmin.doneText);
        setCurrentImage('', '');
        $button.prop('disabled', false).text(startLabel);
        $testButton.prop('disabled', false).text(testStartLabel);
        $pause.prop('disabled', true).text(shrinkwellAdmin.pauseText);
        paused = false;
        runWebpOnly = false;
        isBulkRunning = false;
        $progress.removeClass('is-active');
        $stats.removeClass('is-dimmed');
        $bulkMeter.removeClass('is-running');
        setBulkState(shrinkwellAdmin.readyText, false);
        if (finishedWebpOnly) {
            const statusText = processed
                ? formatText(shrinkwellAdmin.webpOnlySummaryText, processed, skipped + errors)
                : shrinkwellAdmin.webpOnlyNoFilesText;
            setWebpRebuildStatus(statusText, errors ? 'error' : 'done');
            resetWebpRebuildButton();
            return;
        }
        if (finishedTestRun) {
            showBulkNextStep(needsReview ? 'review' : 'ok');
            setFlowState(needsReview ? 'result-error' : 'result-ok');
            return;
        }
        $completionSummary.text(formatText(
            shrinkwellAdmin.completionSummaryText,
            expectedTotal || processed,
            formatBytes(savedBytes),
            skipped + errors
        ));
        $completionBanner.prop('hidden', false);
        setFlowState('proof');
        completionReloadTimer = window.setTimeout(function () {
            window.location.reload();
        }, 1200);
    }

    function optimizeBatch(callback) {
        if (paused) {
            $button.prop('disabled', false);
            return;
        }

        if (!queue.length) {
            callback();
            return;
        }

        const remainingLimit = runLimit ? Math.max(0, runLimit - processed) : 1;
        const batchSize = runLimit ? Math.min(1, remainingLimit) : 1;
        const batch = queue.splice(0, batchSize);

        if (!batch.length) {
            callback();
            return;
        }

        const ids = batch.map(function (item) {
            return typeof item === 'object' ? item.id : item;
        });
        const firstItem = batch[0] || {};
        const firstTitle = typeof firstItem === 'object' ? firstItem.title : '';

        if (firstTitle) {
            setCurrentImage(shrinkwellAdmin.currentImageText, firstTitle);
        }

        function skipBatch(message) {
            let compactMessage = compactErrorMessage(message);
            if (firstItem && firstItem.size && firstItem.dimensions && message === shrinkwellAdmin.serverStoppedText) {
                compactMessage = shrinkwellAdmin.serverStoppedWithDetailsText + ' ' + firstItem.size + ', ' + firstItem.dimensions + '. ' + shrinkwellAdmin.configuredLimitText + ' ' + firstItem.limit + '.';
            }
            processed += batch.length;
            processedIds = processedIds.concat(ids);
            skipped += batch.length;
            addRunError(firstTitle || ids.join(', '), compactMessage);
            recordClientError(ids[0], firstTitle, message);
            setProgress(processed, expectedTotal, shrinkwellAdmin.skippedImageText + ' ' + compactRunTitle(firstTitle || ids.join(', ')));
            setCurrentImage('', '');
            window.setTimeout(function () {
                optimizeBatch(callback);
            }, 350);
        }

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_bulk_optimize',
            nonce: shrinkwellAdmin.nonce,
            ids: ids,
            webp_only: runWebpOnly ? 1 : 0
        }).done(function (response) {
            processed += batch.length;
            processedIds = processedIds.concat(ids);

            if (response.success && response.data) {
                savedBytes += response.data.savedBytes || 0;
                errors += response.data.errors || 0;
                skipped += response.data.skipped || 0;
            } else {
                errors += batch.length;
            }

            if (response.success && response.data && response.data.limitReached) {
                isBulkRunning = false;
                queue = [];
                $button.prop('disabled', false);
                $testButton.prop('disabled', false);
                $pause.prop('disabled', true);
                setFlowState('result-error');
                showMonthlyLimitModal();
                return;
            }

            if (response.success && response.data && (response.data.errors || response.data.skipped)) {
                const message = compactErrorMessage(response.data.message || shrinkwellAdmin.errorText);
                addRunError(firstTitle || ids.join(', '), message);
                setProgress(processed, expectedTotal, shrinkwellAdmin.skippedImageText + ' ' + compactRunTitle(firstTitle || ids.join(', ')));
                setCurrentImage('', '');
            } else if (!response.success) {
                const message = compactErrorMessage(response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText);
                addRunError(firstTitle || ids.join(', '), message);
                setProgress(processed, expectedTotal, shrinkwellAdmin.skippedImageText + ' ' + compactRunTitle(firstTitle || ids.join(', ')));
                setCurrentImage('', '');
            } else {
                setCurrentImage('', '');
                setProgress(processed, expectedTotal);
            }
            optimizeBatch(callback);
        }).fail(function () {
            skipBatch(shrinkwellAdmin.serverStoppedText);
        });
    }

    function scanAndOptimize() {
        if (paused) {
            return;
        }

        if (runLimit && processed >= runLimit) {
            finish();
            return;
        }

        $.post(shrinkwellAdmin.ajaxUrl, Object.assign({
            action: 'shrinkwell_bulk_ids',
            nonce: shrinkwellAdmin.nonce,
            exclude_ids: processedIds
        }, bulkFilters())).done(function (response) {
            if (response.success && response.data && response.data.scannedIds && response.data.scannedIds.length) {
                response.data.scannedIds.forEach(function (id) {
                    if (processedIds.indexOf(id) === -1) {
                        processedIds.push(id);
                    }
                });
            }

            if (!response.success || !response.data.ids.length) {
                if (response.success && response.data.scannedIds && response.data.scannedIds.length) {
                    scanAndOptimize();
                    return;
                }

                if (runWebpOnly) {
                    finish();
                } else if (processed) {
                    finish();
                } else {
                    const skippedMessage = response.success && response.data && response.data.skippedMessage ? response.data.skippedMessage : '';
                    const message = skippedMessage ? skippedMessage + ' ' + shrinkwellAdmin.largeFilesBlockedText : shrinkwellAdmin.emptyText;
                    setProgress(1, 1, message);

                    if (skippedMessage && response.data.skippedExamples && response.data.skippedExamples.length) {
                        response.data.skippedExamples.forEach(function (item) {
                            addRunError(item.title || skippedMessage, compactErrorMessage(item.message || shrinkwellAdmin.largeImageShortText));
                        });
                    }

                    $button.prop('disabled', false);
                    $testButton.prop('disabled', false);
                    $pause.prop('disabled', true);
                    isBulkRunning = false;
                    setFlowState('result-error');
                    showBulkNextStep('review');
                }
                return;
            }

            const items = response.data.items && response.data.items.length ? response.data.items : response.data.ids;
            const remainingLimit = runLimit ? Math.max(0, runLimit - processed) : items.length;
            queue = runLimit ? items.slice(0, remainingLimit) : items;
            expectedTotal = runLimit ? Math.min(runLimit, processed + response.data.total) : processed + response.data.total;

            optimizeBatch(function () {
                scanAndOptimize();
            });
        }).fail(function () {
            $text.text(shrinkwellAdmin.errorText);
            if (runWebpOnly) {
                setWebpRebuildStatus(shrinkwellAdmin.errorText, 'error');
                resetWebpRebuildButton();
            }
            $button.prop('disabled', false);
            $testButton.prop('disabled', false);
            $pause.prop('disabled', true);
            isBulkRunning = false;
            setFlowState('result-error');
        });
    }

    function startBulk(limit, webpOnly) {
        if (paused) {
            paused = false;
            isBulkRunning = true;
            setFlowState('running');
            setBulkState(shrinkwellAdmin.runningText, true);
            $bulkMeter.addClass('is-running');
            $button.prop('disabled', true).text(startLabel);
            $testButton.prop('disabled', true).text(testStartLabel);
            $pause.prop('disabled', false).text(shrinkwellAdmin.pauseText);
            if (queue.length) {
                optimizeBatch(function () {
                    scanAndOptimize();
                });
            } else {
                scanAndOptimize();
            }
            return;
        }

        processed = 0;
        expectedTotal = 0;
        savedBytes = 0;
        errors = 0;
        skipped = 0;
        runErrorItems = [];
        queue = [];
        processedIds = [];
        runLimit = limit || null;
        runWebpOnly = !!webpOnly;
        paused = false;
        isBulkRunning = true;
        if (completionReloadTimer) {
            window.clearTimeout(completionReloadTimer);
            completionReloadTimer = null;
        }
        setFlowState(runLimit ? 'testing' : 'running');
        setBulkState(shrinkwellAdmin.runningText, true);
        if (runWebpOnly) {
            setWebpRebuildStatus(shrinkwellAdmin.webpOnlyRunningText, 'running');
        }
        $bulkMeter.addClass('is-running');
        $progress.addClass('is-active');
        $stats.addClass('is-dimmed');
        $bulkNextStep.prop('hidden', true).removeClass('is-review is-ok').empty();
        $completionBanner.prop('hidden', true);
        $runErrors.prop('hidden', true).find('ul').empty();
        $runErrors.find('.shrinkwell-run-errors-summary, .shrinkwell-run-errors-reason').remove();
        $button.prop('disabled', true);
        $testButton.prop('disabled', true);
        $pause.prop('disabled', false).text(shrinkwellAdmin.pauseText);
        setProgress(0, 1, runWebpOnly ? shrinkwellAdmin.webpOnlyRunningText : shrinkwellAdmin.scanText);
        scanAndOptimize();
    }

    $button.on('click', function () {
        startBulk(null, false);
    });

    $(document).on('click', '#shrinkwell-force-bulk, #shrinkwell-result-start-bulk', function () {
        startBulk(null, false);
    });

    $('#shrinkwell-new-run').on('click', function () {
        setFlowState('idle');
        processed = 0;
        expectedTotal = 0;
        savedBytes = 0;
        errors = 0;
        skipped = 0;
        runErrorItems = [];
        $bulkNextStep.prop('hidden', true).removeClass('is-review is-ok').empty();
        $completionBanner.prop('hidden', true);
        $frontendProofResults.prop('hidden', true).empty();
        $runErrors.prop('hidden', true).find('ul').empty();
        setProgress(0, 1, '');
        $progress.prop('hidden', true).removeClass('is-active');
    });

    $testButton.on('click', function () {
        startBulk(5, false);
    });

    $(document).on('click', '.shrinkwell-trigger-webp-rebuild', function () {
        $activeWebpRebuildButton = $(this);
        webpRebuildButtonLabel = $.trim($activeWebpRebuildButton.text());
        $activeWebpRebuildButton.prop('disabled', true).text(shrinkwellAdmin.webpOnlyRunningText);
        startBulk(null, true);
    });

    $pause.on('click', function () {
        paused = true;
        isBulkRunning = false;
        setFlowState('paused');
        setBulkState(shrinkwellAdmin.readyText, false);
        $stats.removeClass('is-dimmed');
        $bulkMeter.removeClass('is-running');
        $button.prop('disabled', false).text(shrinkwellAdmin.resumeText);
        $testButton.prop('disabled', true);
        $pause.prop('disabled', true);
        setCurrentImage('', '');
    });

    window.addEventListener('beforeunload', function (event) {
        if (!isBulkRunning) {
            return undefined;
        }

        event.preventDefault();
        event.returnValue = shrinkwellAdmin.leaveWarningText;

        return shrinkwellAdmin.leaveWarningText;
    });

    $('input[name="shrinkwell_settings[compression_profile]"]').on('change', updateCompressionHelp);
    $customStrength.on('input change', function () {
        updateCustomStrength();
        updateCompressionHelp();
    });
    updateCustomStrength();
    updateCompressionHelp();

    $deliveryButton.on('click', function () {
        $deliveryButton.prop('disabled', true);
        $deliveryResults.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.testText) + '</p>');
        runDeliveryTest($deliveryResults, function () {
            $deliveryButton.prop('disabled', false);
        });
    });

    $frontendProofButton.on('click', function () {
        $frontendProofButton.prop('disabled', true);
        $frontendProofResults.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.proofScanText) + '</p>');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_frontend_proof_scan',
            nonce: shrinkwellAdmin.nonce,
            url: $('#shrinkwell-proof-url').val()
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $frontendProofResults.html('<p class="shrinkwell-test-error">' + escapeHtml(message) + '</p>');
                return;
            }

            const checks = response.data.checks || [];
            const verdict = getProofPlainVerdict(response.data);
            let html = '<p><strong>' + escapeHtml(shrinkwellAdmin.proofScanDoneText) + '</strong></p>';
            html += '<div class="shrinkwell-proof-verdict is-' + escapeHtml(verdict.type) + '">';
            html += '<strong>' + escapeHtml(verdict.title) + '</strong>';
            html += '<p>' + escapeHtml(verdict.detail) + '</p>';
            if (!response.data.passed || response.data.cacheWarning) {
                html += '<span>' + escapeHtml(shrinkwellAdmin.proofThenText) + '</span>';
            }
            html += '</div>';

            if (response.data.estimate) {
                const estimate = response.data.estimate;
                html += '<div class="shrinkwell-proof-estimate is-compact">';
                html += '<strong>' + escapeHtml(estimate.savedFormatted || '0 B') + '</strong>';
                html += '<span>' + escapeHtml(shrinkwellAdmin.proofEstimatedReductionText) + '</span>';
                html += '<small>' + escapeHtml(formatText(shrinkwellAdmin.proofUsableWebpSentenceText, estimate.webpReady || 0, estimate.checked || 0)) + ' ';
                html += escapeHtml(formatText(shrinkwellAdmin.proofOriginalVsWebpText, estimate.originalFormatted || '0 B', estimate.webpFormatted || '0 B'));
                if (estimate.coveragePercent || estimate.uncoveredReady) {
                    html += '. ' + escapeHtml(formatText(shrinkwellAdmin.proofDeliveryCoverageSentenceText, estimate.coveragePercent || 0));
                }
                if ((estimate.savedBytes || 0) > 0 && estimate.savedPercent) {
                    html += ' (' + escapeHtml(formatText(shrinkwellAdmin.proofSmallerSentenceText, estimate.savedPercent)) + ').';
                } else if ((estimate.webpReady || 0) > 0) {
                    html += '. ' + escapeHtml(shrinkwellAdmin.proofScanNoSavingsText);
                } else {
                    html += '.';
                }
                if (estimate.ignoredNonContentImages) {
                    html += ' ' + escapeHtml(String(estimate.ignoredNonContentImages)) + ' ' + escapeHtml(shrinkwellAdmin.proofScanIgnoredIconsText);
                }
                if (estimate.largerWebp) {
                    html += ' ' + escapeHtml(String(estimate.largerWebp)) + ' ' + escapeHtml(shrinkwellAdmin.proofScanLargerWebpText);
                }
                html += '</small></div>';
            }

            if (!response.data.passed || response.data.cacheWarning) {
                html += '<details class="shrinkwell-proof-details shrinkwell-cache-checklist" open><summary>' + escapeHtml(shrinkwellAdmin.cacheChecklistTitleText) + '</summary><ul>';
                getProofCacheChecklistItems().forEach(function (step) {
                    html += '<li>' + escapeHtml(step) + '</li>';
                });
                html += '</ul></details>';
            }

            if (response.data.diagnosis && (response.data.diagnosis.title || response.data.diagnosis.detail || response.data.diagnosis.action)) {
                const diagnosis = response.data.diagnosis;
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(shrinkwellAdmin.proofDiagnosisTitleText) + '</summary>';
                if (diagnosis.title) {
                    html += '<p><strong>' + escapeHtml(diagnosis.title) + '</strong></p>';
                }
                if (diagnosis.detail) {
                    html += '<p>' + escapeHtml(diagnosis.detail) + '</p>';
                }
                if (diagnosis.action) {
                    html += '<p>' + escapeHtml(diagnosis.action) + '</p>';
                }
                html += '</details>';
            }

            if (response.data.rewritePreview && response.data.rewritePreview.wouldImprove) {
                const preview = response.data.rewritePreview;
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(shrinkwellAdmin.proofRewritePreviewTitleText) + '</summary>';
                html += '<p>' + escapeHtml(shrinkwellAdmin.proofRewritePreviewText) + '</p>';
                html += '<ul>';
                html += '<li>' + escapeHtml(formatText(shrinkwellAdmin.proofPictureElementsAfterText, preview.pictureElementsAfter || 0)) + '</li>';
                html += '<li>' + escapeHtml(formatText(shrinkwellAdmin.proofSourceTagsAfterText, preview.webpSourceTagsAfter || 0)) + '</li>';
                html += '<li>' + escapeHtml(formatText(shrinkwellAdmin.proofCoverageAfterRewriteText, preview.coverageAfter || 0)) + '</li>';
                html += '</ul></details>';
            }

            html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(shrinkwellAdmin.proofTechnicalDetailsText) + '</summary>';
            html += '<div class="shrinkwell-proof-grid">';

            checks.forEach(function (check) {
                html += '<div class="' + (check.ok ? 'shrinkwell-proof-item is-ok' : 'shrinkwell-proof-item is-warn') + '">';
                html += '<strong>' + escapeHtml(check.value || '0') + '</strong>';
                html += '<span>' + escapeHtml(check.label) + '</span>';
                html += '</div>';
            });

            html += '</div></details>';

            if (response.data.backgroundSamples && response.data.backgroundSamples.length) {
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(formatText(shrinkwellAdmin.proofBackgroundExamplesText, response.data.backgroundSamples.length)) + '</summary><ul>';
                response.data.backgroundSamples.forEach(function (sample) {
                    html += '<li>' + escapeHtml(sample) + '</li>';
                });
                html += '</ul></details>';
            }

            if (response.data.estimate && response.data.estimate.uncoveredSamples && response.data.estimate.uncoveredSamples.length) {
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(response.data.estimate.uncoveredReady || response.data.estimate.uncoveredSamples.length) + ' ' + escapeHtml(shrinkwellAdmin.proofScanUncoveredText) + '</summary><ul>';
                response.data.estimate.uncoveredSamples.forEach(function (sample) {
                    const label = (sample.file || sample.url || '') + ' - ' + formatText(shrinkwellAdmin.proofOriginalWebpSizeText, sample.original || '0 B', sample.webp || '0 B');
                    html += '<li>' + escapeHtml(label) + '</li>';
                });
                html += '</ul></details>';
            }

            if (response.data.estimate && response.data.estimate.largerWebpSamples && response.data.estimate.largerWebpSamples.length) {
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(response.data.estimate.largerWebp || response.data.estimate.largerWebpSamples.length) + ' ' + escapeHtml(shrinkwellAdmin.proofScanLargerWebpText) + '</summary><ul>';
                response.data.estimate.largerWebpSamples.forEach(function (sample) {
                    const label = (sample.file || sample.url || '') + ' - ' + formatText(shrinkwellAdmin.proofOriginalWebpSizeText, sample.original || '0 B', sample.webp || '0 B');
                    html += '<li>' + escapeHtml(label) + '</li>';
                });
                html += '</ul></details>';
            }

            if (response.data.cacheHeaders && response.data.cacheHeaders.length) {
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(shrinkwellAdmin.proofCacheHeadersTitleText) + '</summary><ul>';
                response.data.cacheHeaders.forEach(function (header) {
                    html += '<li>' + escapeHtml((header.name || '') + ': ' + (header.value || '')) + '</li>';
                });
                html += '</ul></details>';
            }

            if (response.data.message) {
                html += '<details class="shrinkwell-proof-details"><summary>' + escapeHtml(shrinkwellAdmin.proofScanNoteText) + '</summary><p>' + escapeHtml(response.data.message) + '</p></details>';
            }
            html += '<div class="shrinkwell-proof-actions">';
            html += '<button type="button" class="button button-secondary" id="shrinkwell-copy-proof-report">' + escapeHtml(shrinkwellAdmin.copyProofReportText) + '</button>';
            html += '<button type="button" class="button button-secondary" id="shrinkwell-download-proof-report">' + escapeHtml(shrinkwellAdmin.downloadProofReportText) + '</button>';
            html += '<span class="shrinkwell-proof-copy-feedback" aria-live="polite"></span>';
            html += '</div>';
            $frontendProofResults.html(html);

            $('#shrinkwell-copy-proof-report').on('click', function () {
                copyToClipboard(buildProofReport(response.data), $('.shrinkwell-proof-copy-feedback'));
            });

            $('#shrinkwell-download-proof-report').on('click', function () {
                downloadTextFile(proofReportFilename(), buildProofReport(response.data));
                $('.shrinkwell-proof-copy-feedback').text(shrinkwellAdmin.proofReportDownloadedText);
            });
        }).fail(function () {
            $frontendProofResults.html('<p class="shrinkwell-test-error">' + shrinkwellAdmin.errorText + '</p>');
        }).always(function () {
            $frontendProofButton.prop('disabled', false);
        });
    });

    $zeroSavingsButton.on('click', function () {
        const total = parseInt($zeroSavingsPanel.data('total-images') || 0, 10);

        $zeroSavingsButton.prop('disabled', true);
        $zeroSavingsSpinner.addClass('is-active');
        $zeroSavingsStatus.removeClass('is-error').text(formatText(shrinkwellAdmin.zeroSavingsScanText, total || 0));
        $zeroSavingsResults.prop('hidden', true).empty();

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_zero_savings_report',
            nonce: shrinkwellAdmin.zeroSavingsNonce
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $zeroSavingsStatus.addClass('is-error').text(message);
                return;
            }

            zeroSavingsItems = response.data.items || [];
            renderZeroSavingsTable(zeroSavingsItems, response.data.summary || {});
            $zeroSavingsStatus.text(shrinkwellAdmin.zeroSavingsDoneText);
        }).fail(function () {
            $zeroSavingsStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $zeroSavingsButton.prop('disabled', false);
            $zeroSavingsSpinner.removeClass('is-active');
        });
    });

    $zeroSavingsResults.on('click', '.shrinkwell-zero-filter', function () {
        const $button = $(this);
        const filter = $button.data('filter') || 'all';

        $zeroSavingsResults.find('.shrinkwell-zero-filter').removeClass('is-active');
        $button.addClass('is-active');

        $zeroSavingsResults.find('.shrinkwell-zero-savings-table tbody tr').each(function () {
            const $row = $(this);
            const reason = $row.data('reason') || 'unknown';

            $row.toggle(zeroSavingsFilterMatches({ reason: reason }, filter));
        });
    });

    $zeroSavingsResults.on('click', '#shrinkwell-select-visible-zero-savings', function () {
        $zeroSavingsResults.find('.shrinkwell-zero-savings-table tbody tr:visible .shrinkwell-zero-savings-check').prop('checked', true);
        $zeroSavingsStatus.removeClass('is-error').text('');
    });

    $zeroSavingsResults.on('click', '#shrinkwell-force-reoptimize-selected', function () {
        const ids = selectedZeroSavingsIds();
        const $button = $(this);
        const $actionStatus = $zeroSavingsResults.find('.shrinkwell-zero-savings-action-status');
        const $selectedRows = $zeroSavingsResults.find('.shrinkwell-zero-savings-check:checked').closest('tr');

        if (!ids.length) {
            $zeroSavingsStatus.addClass('is-error').text(shrinkwellAdmin.forceReoptimizeNoneText);
            $actionStatus.addClass('is-error').text(shrinkwellAdmin.forceReoptimizeNoneText);
            return;
        }

        $button.prop('disabled', true).text(shrinkwellAdmin.forceReoptimizeRunningText);
        $zeroSavingsStatus.removeClass('is-error').text(shrinkwellAdmin.forceReoptimizeRunningText);
        $actionStatus.removeClass('is-error').text(shrinkwellAdmin.forceReoptimizeRunningText);
        $selectedRows.addClass('is-processing');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_force_reoptimize',
            nonce: shrinkwellAdmin.forceReoptimizeNonce,
            attachment_ids: ids
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $zeroSavingsStatus.addClass('is-error').text(message);
                $actionStatus.addClass('is-error').text(message);
                return;
            }

            const data = response.data || {};
            const message = formatText(shrinkwellAdmin.forceReoptimizeDoneText, data.processed || 0, data.savedFormatted || formatBytes(data.saved_bytes || 0));
            const processedIds = data.processedIds || [];
            $zeroSavingsStatus.removeClass('is-error').text(message);
            $actionStatus.removeClass('is-error').text(message);
            if (data.totalSavedFormatted) {
                $('.shrinkwell-stat-space strong').text(data.totalSavedFormatted);
            }

            $selectedRows.each(function () {
                const $row = $(this);
                const id = parseInt($row.find('.shrinkwell-zero-savings-check').val() || 0, 10);

                if (processedIds.indexOf(id) !== -1) {
                    $row.fadeOut(150, function () {
                        $(this).remove();
                    });
                } else {
                    $row.removeClass('is-processing');
                }
            });
        }).fail(function () {
            $zeroSavingsStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
            $actionStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $button.prop('disabled', false).text(shrinkwellAdmin.forceReoptimizeText);
        });
    });

    $zeroSavingsResults.on('click', '#shrinkwell-dismiss-zero-savings', function () {
        const ids = zeroSavingsItems.map(function (item) {
            return parseInt(item.attachment_id || 0, 10);
        }).filter(Boolean);
        const $button = $(this);

        if (!ids.length) {
            return;
        }

        $button.prop('disabled', true).text(shrinkwellAdmin.zeroSavingsDismissRunningText);
        $zeroSavingsStatus.removeClass('is-error').text(shrinkwellAdmin.zeroSavingsDismissRunningText);

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_dismiss_zero_savings',
            nonce: shrinkwellAdmin.forceReoptimizeNonce,
            attachment_ids: ids
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $zeroSavingsStatus.addClass('is-error').text(message);
                return;
            }

            const dismissed = response.data && response.data.dismissed ? response.data.dismissed : ids.length;
            zeroSavingsItems = [];
            $zeroSavingsResults.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.zeroSavingsEmptyText) + '</p>');
            $zeroSavingsStatus.text(formatText(shrinkwellAdmin.zeroSavingsDismissedText, dismissed));
        }).fail(function () {
            $zeroSavingsStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $button.prop('disabled', false).text(shrinkwellAdmin.zeroSavingsDismissAllText);
        });
    });

    $seoButton.on('click', function () {
        $seoButton.prop('disabled', true);
        $seoResults.prop('hidden', false).html('<p>' + escapeHtml(shrinkwellAdmin.seoScanText) + '</p>');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_seo_scan',
            nonce: shrinkwellAdmin.nonce
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $seoResults.html('<p class="shrinkwell-test-error">' + escapeHtml(message) + '</p>');
                return;
            }

            const data = response.data || {};
            const issues = data.issues || [];
            const missingAltCount = parseInt(data.missingAlt || 0, 10);
            const $seoTab = $('.shrinkwell-tabs .nav-tab').filter(function () {
                return this.href && this.href.indexOf('tab=seo') !== -1;
            });

            $seoTab.find('.shrinkwell-tab-badge').remove();
            if (missingAltCount > 0) {
                $seoTab.append(' <span class="shrinkwell-tab-badge">' + escapeHtml(missingAltCount) + '</span>');
            }

            let html = '<p><strong>' + escapeHtml(shrinkwellAdmin.seoDoneText) + '</strong></p>';
            html += '<div class="shrinkwell-bulk-summary">';
            html += '<span><strong>' + escapeHtml(data.scanned || 0) + '</strong> ' + escapeHtml(shrinkwellAdmin.scannedText) + '</span>';
            html += '<span><strong>' + escapeHtml(data.missingAlt || 0) + '</strong> ' + escapeHtml(shrinkwellAdmin.missingAltText) + '</span>';
            html += '<span><strong>' + escapeHtml(data.weakFilename || 0) + '</strong> ' + escapeHtml(shrinkwellAdmin.weakFilenamesText) + '</span>';
            html += '</div>';

            if (!issues.length) {
                html += '<p>' + escapeHtml(shrinkwellAdmin.seoNoIssuesText) + '</p>';
            } else {
                const seoFilterCounts = {
                    all: issues.length,
                    missing: 0,
                    weak: 0,
                    done: 0
                };

                issues.forEach(function (item) {
                    const missing = item.missingAlt || !item.alt;
                    const weak = !!item.weakFilename;

                    if (missing) {
                        seoFilterCounts.missing++;
                    }

                    if (weak) {
                        seoFilterCounts.weak++;
                    }

                    if (!missing && !weak) {
                        seoFilterCounts.done++;
                    }
                });

                html += '<p class="shrinkwell-seo-actions"><button type="button" class="button button-primary" id="shrinkwell-save-safe-seo">' + escapeHtml(shrinkwellAdmin.bulkSaveSeoText) + '</button><span class="shrinkwell-seo-bulk-status" aria-live="polite"></span></p>';
                html += '<div class="shrinkwell-seo-filters" role="group" aria-label="' + escapeHtml(shrinkwellAdmin.seoFilterImagesText) + '">';
                html += '<button type="button" class="shrinkwell-seo-filter is-active" data-filter="all">' + escapeHtml(shrinkwellAdmin.seoAllText) + '<span class="shrinkwell-tab-badge">' + escapeHtml(seoFilterCounts.all) + '</span></button>';
                html += '<button type="button" class="shrinkwell-seo-filter" data-filter="missing">' + escapeHtml(shrinkwellAdmin.seoMissingAltText) + '<span class="shrinkwell-tab-badge">' + escapeHtml(seoFilterCounts.missing) + '</span></button>';
                html += '<button type="button" class="shrinkwell-seo-filter" data-filter="weak">' + escapeHtml(shrinkwellAdmin.seoWeakFilenameText) + '<span class="shrinkwell-tab-badge shrinkwell-tab-badge--warn">' + escapeHtml(seoFilterCounts.weak) + '</span></button>';
                html += '<button type="button" class="shrinkwell-seo-filter" data-filter="done">' + escapeHtml(shrinkwellAdmin.seoAlreadyFilledText) + '<span class="shrinkwell-tab-badge">' + escapeHtml(seoFilterCounts.done) + '</span></button>';
                html += '</div>';
                html += '<table class="widefat striped shrinkwell-seo-table"><thead><tr>';
                html += '<th>' + escapeHtml(shrinkwellAdmin.imageText) + '</th><th class="shrinkwell-seo-status-heading">' + escapeHtml(shrinkwellAdmin.seoStatusText) + '</th><th>' + escapeHtml(shrinkwellAdmin.currentAltText) + '</th><th>' + escapeHtml(shrinkwellAdmin.suggestionText) + '</th><th>' + escapeHtml(shrinkwellAdmin.actionText) + '</th>';
                html += '</tr></thead><tbody>';
                issues.forEach(function (item) {
                    const statusClass = item.statusType === 'missing' ? 'shrinkwell-seo-bad' : 'shrinkwell-seo-warn';
                    const currentAlt = item.alt || '';
                    const safeSuggestion = !!(item.safeSuggestion && item.suggestion);
                    const missing = item.missingAlt || !currentAlt;
                    const weak = !!item.weakFilename;
                    html += '<tr data-attachment-id="' + escapeHtml(item.id || '') + '" data-suggestion="' + escapeHtml(safeSuggestion ? item.suggestion : '') + '" data-safe-suggestion="' + (safeSuggestion ? '1' : '0') + '" data-missing="' + (missing ? '1' : '0') + '" data-weak="' + (weak ? '1' : '0') + '">';
                    html += '<td><div class="shrinkwell-seo-image-cell">';
                    if (item.thumbnail) {
                        html += '<img src="' + escapeHtml(item.thumbnail) + '" alt="">';
                    }
                    html += '<div><strong>' + escapeHtml(item.title || '') + '</strong><span>' + escapeHtml(item.filename || '') + '</span></div></div></td>';
                    const statusText = item.status || shrinkwellAdmin.needsAttentionText;
                    const issuesText = (item.issues || []).join(', ');
                    const statusLabel = issuesText ? statusText + ': ' + issuesText : statusText;
                    html += '<td class="shrinkwell-seo-status-cell"><span class="shrinkwell-seo-status-label ' + statusClass + '" title="' + escapeHtml(statusLabel) + '">' + escapeHtml(statusText) + '</span></td>';
                    html += '<td><label class="screen-reader-text">' + escapeHtml(shrinkwellAdmin.altLabelText) + '</label><textarea class="shrinkwell-seo-alt" rows="2">' + escapeHtml(currentAlt) + '</textarea><small class="shrinkwell-seo-alt-warning" hidden>' + escapeHtml(shrinkwellAdmin.emptyAltWarningText) + '</small></td>';
                    html += '<td>';
                    html += '<span class="shrinkwell-seo-suggestion-text">' + escapeHtml(safeSuggestion ? item.suggestion : shrinkwellAdmin.writeAltManuallyText) + '</span>';
                    if (safeSuggestion) {
                        html += '<button type="button" class="button button-small shrinkwell-use-seo-suggestion">' + escapeHtml(shrinkwellAdmin.useSuggestionText) + '</button>';
                    } else {
                        html += '<button type="button" class="button button-small" disabled>' + escapeHtml(shrinkwellAdmin.noSafeSuggestionText) + '</button>';
                    }
                    html += '</td>';
                    html += '<td class="shrinkwell-seo-action-cell"><button type="button" class="button button-small shrinkwell-save-seo-row">' + escapeHtml(shrinkwellAdmin.saveText) + '</button><span class="shrinkwell-seo-save-status" aria-live="polite"></span></td>';
                    html += '</tr>';
                });
                html += '</tbody></table>';
            }

            html += '<p class="description">' + escapeHtml(data.message || '') + '</p>';
            $seoResults.html(html);
        }).fail(function () {
            $seoResults.html('<p class="shrinkwell-test-error">' + shrinkwellAdmin.errorText + '</p>');
        }).always(function () {
            $seoButton.prop('disabled', false);
        });
    });

    function validateSeoRow($row) {
        const $alt = $row.find('.shrinkwell-seo-alt');
        const $warning = $row.find('.shrinkwell-seo-alt-warning');

        $alt.prop('disabled', false);

        if (!$.trim($alt.val())) {
            $warning.prop('hidden', false);
            $row.addClass('is-seo-warning');
            return false;
        }

        $warning.prop('hidden', true);
        $row.removeClass('is-seo-warning');
        return true;
    }

    function saveSeoRow($row, $saveButton) {
        const attachmentId = $row.data('attachment-id');
        const $status = $row.find('.shrinkwell-seo-save-status');
        const deferred = $.Deferred();
        const originalButtonText = $saveButton ? $saveButton.text() : '';

        if (!attachmentId || !validateSeoRow($row)) {
            deferred.reject();
            return deferred.promise();
        }

        if ($saveButton) {
            $saveButton.prop('disabled', true).text(shrinkwellAdmin.savingText);
        }

        $status.removeClass('is-error').text('');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_save_seo_fields',
            nonce: shrinkwellAdmin.nonce,
            attachment_id: attachmentId,
            alt: $row.find('.shrinkwell-seo-alt').val(),
            title: ''
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.saveFailedText;
                $status.addClass('is-error').text(message);
                deferred.reject();
                return;
            }

            $row.addClass('is-seo-saved');
            $row.find('.shrinkwell-seo-status-label')
                .removeClass('shrinkwell-seo-bad shrinkwell-seo-warn')
                .addClass('shrinkwell-seo-good')
                .attr('title', shrinkwellAdmin.savedInlineText)
                .text(shrinkwellAdmin.savedInlineText);
            $status.text(shrinkwellAdmin.savedInlineText);
            $row.fadeOut(150, function () {
                $(this).remove();
            });
            deferred.resolve();
        }).fail(function () {
            $status.addClass('is-error').text(shrinkwellAdmin.saveFailedText);
            deferred.reject();
        }).always(function () {
            if ($saveButton) {
                $saveButton.prop('disabled', false).text(originalButtonText || shrinkwellAdmin.saveText);
            }
        });

        return deferred.promise();
    }

    $seoResults.on('click', '.shrinkwell-use-seo-suggestion', function () {
        const $button = $(this);
        const $row = $(this).closest('tr');
        const suggestion = $row.data('suggestion') || '';

        $row.find('.shrinkwell-seo-alt').prop('disabled', false).val(suggestion);
        validateSeoRow($row);
        $row.find('.shrinkwell-seo-save-status').removeClass('is-error').text(shrinkwellAdmin.readyToSaveText);
    });

    $seoResults.on('input', '.shrinkwell-seo-alt', function () {
        validateSeoRow($(this).closest('tr'));
    });

    $seoResults.on('click', '.shrinkwell-save-seo-row', function () {
        const $saveButton = $(this);
        const $row = $saveButton.closest('tr');
        saveSeoRow($row, $saveButton);
    });

    $seoResults.on('click', '#shrinkwell-save-safe-seo', function () {
        const $bulkButton = $(this);
        const $status = $seoResults.find('.shrinkwell-seo-bulk-status');
        const rows = $seoResults.find('.shrinkwell-seo-table tbody tr').toArray().map(function (row) {
            return $(row);
        }).filter(function ($row) {
            return $row.data('safe-suggestion') === 1 || $row.data('safe-suggestion') === '1';
        });
        let saved = 0;
        let chain = $.Deferred().resolve().promise();

        $bulkButton.prop('disabled', true).text(shrinkwellAdmin.bulkSavingSeoText);
        $status.removeClass('is-error').text('');

        if (!rows.length) {
            $bulkButton.prop('disabled', false).text(shrinkwellAdmin.bulkSaveSeoText);
            $status.addClass('is-error').text(shrinkwellAdmin.emptyAltWarningText);
            return;
        }

        rows.forEach(function ($row) {
            chain = chain.then(function () {
                const next = $.Deferred();
                const suggestion = $row.data('suggestion') || '';

                $row.find('.shrinkwell-seo-alt').val(suggestion);

                if (!validateSeoRow($row)) {
                    next.resolve();
                    return next.promise();
                }

                saveSeoRow($row).done(function () {
                    saved++;
                    $status.text(saved + ' / ' + rows.length + ' ' + shrinkwellAdmin.savedText);
                    next.resolve();
                }).fail(function () {
                    next.resolve();
                });

                return next.promise();
            });
        });

        chain.always(function () {
            $status.text(shrinkwellAdmin.bulkSeoSavedText + ' (' + saved + ' / ' + rows.length + ')');
            $bulkButton.text(shrinkwellAdmin.seoScanText);
            window.setTimeout(function () {
                $seoButton.trigger('click');
            }, 700);
        });
    });

    $('.shrinkwell-confirm-restore-all').on('click', function (event) {
        if (!window.confirm(shrinkwellAdmin.restoreAllConfirmText)) {
            event.preventDefault();
        }
    });

    $('#shrinkwell-settings-form').on('change input', function () {
        $stickySave.removeAttr('hidden');
    }).on('submit', function () {
        $stickySave.attr('hidden', '');
    });

    $(document).on('click', '.shrinkwell-seo-filter', function () {
        const filter = $(this).data('filter');
        const $rows = $('.shrinkwell-seo-table tbody tr');

        $('.shrinkwell-seo-filter').removeClass('is-active');
        $(this).addClass('is-active');

        if (filter === 'all') {
            $rows.show();
        } else if (filter === 'missing') {
            $rows.hide().filter('[data-missing="1"]').show();
        } else if (filter === 'weak') {
            $rows.hide().filter('[data-weak="1"]').show();
        } else if (filter === 'done') {
            $rows.hide().filter('[data-missing="0"][data-weak="0"]').show();
        }
    });

    $backupCleanupButton.on('click', function () {
        const $button = $(this);
        const originalText = $.trim($button.text());
        const days = parseInt($button.data('days') || 30, 10);

        $button.prop('disabled', true);
        $backupCleanupStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.cleanupBackupsScanText);

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_backup_cleanup_preview',
            nonce: shrinkwellAdmin.cleanupBackupsNonce,
            days: days
        }).done(function (response) {
            if (!response || !response.success) {
                const message = response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $backupCleanupStatus.addClass('is-error').text(message);
                $button.prop('disabled', false).text(originalText);
                return;
            }

            const data = response.data || {};
            backupCleanupCheck = data;

            if (!data.files) {
                $backupCleanupStatus.addClass('is-ok').text(shrinkwellAdmin.cleanupBackupsEmptyText);
                $backupCheckResult.prop('hidden', true);
                $button.prop('disabled', false).text(originalText);
                return;
            }

            $backupCheckSummary.text(formatText(shrinkwellAdmin.cleanupBackupsReadyText, data.files || 0, data.reclaimFormatted || '0 B'));
            $backupCheckResult.prop('hidden', false);
            $backupCleanupStatus.addClass('is-ok').text('');
            $button.prop('disabled', false).text(originalText);
        }).fail(function () {
            $backupCleanupStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
            $button.prop('disabled', false).text(originalText);
        });
    });

    $backupDeleteButton.on('click', function () {
        if (!backupCleanupCheck || !backupCleanupCheck.files) {
            return;
        }

        $('#shrinkwell-backup-confirm-message').text(formatText(
            shrinkwellAdmin.cleanupBackupsConfirmText,
            backupCleanupCheck.reclaimFormatted || '0 B',
            backupCleanupCheck.files || 0
        ));
        $('#shrinkwell-backup-confirm').prop('hidden', false);
    });

    $(document).on('click', '[data-backup-cancel]', function () {
        $('#shrinkwell-backup-confirm').prop('hidden', true);
    });

    $(document).on('click', '[data-backup-confirm]', function () {
        const checked = backupCleanupCheck;
        const $confirmButton = $(this);
        if (!checked) {
            return;
        }

        $('#shrinkwell-backup-confirm').prop('hidden', true);
        $confirmButton.prop('disabled', true);
        $backupDeleteButton.prop('disabled', true);
        $backupCleanupStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.cleanupBackupsRunningText);

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_cleanup_old_backups',
            nonce: shrinkwellAdmin.cleanupBackupsNonce,
            days: checked.days || 30,
            check_token: checked.checkToken || ''
        }).done(function (response) {
            if (!response || !response.success) {
                const message = response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $backupCleanupStatus.addClass('is-error').text(message);
                return;
            }
            const data = response.data || {};
            $backupCleanupStatus.addClass('is-ok').text(formatText(shrinkwellAdmin.cleanupBackupsDoneText, data.deleted_files || 0, data.freedFormatted || '0 B'));
            $backupCheckResult.prop('hidden', true);
            backupCleanupCheck = null;
        }).fail(function () {
            $backupCleanupStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $confirmButton.prop('disabled', false);
            $backupDeleteButton.prop('disabled', false);
        });
    });

    function cleanupSelectedIds() {
        return $('.shrinkwell-cleanup-item:checked').map(function () {
            return parseInt($(this).val(), 10);
        }).get().filter(Boolean);
    }

    function updateCleanupSelection() {
        if (!shrinkwellAdmin.canBulkCleanup) {
            return;
        }

        const count = cleanupSelectedIds().length;
        const available = $('.shrinkwell-cleanup-item:not(:disabled)').length;
        $cleanupSelected.text(count);
        $cleanupTrashButton.prop('disabled', count < 1);
        $cleanupSelectionHelp.prop('hidden', count > 0);
        $cleanupSelectAll.prop('checked', available > 0 && count === available).prop('indeterminate', count > 0 && count < available);
    }

    function cleanupRowHtml(item) {
        const cleanupEligible = !!(item.cleanup_eligible || item.eligible);
        const canSelect = cleanupEligible && shrinkwellAdmin.canBulkCleanup;
        const disabled = canSelect ? '' : ' disabled';
        const checked = canSelect && item.selected_by_default ? ' checked' : '';
        const detailsId = 'shrinkwell-cleanup-evidence-' + escapeHtml(item.id);
        let usage = escapeHtml(shrinkwellAdmin.mediaCleanupFoundInText) + ' ' + escapeHtml(item.found_count) + ' ' + escapeHtml(shrinkwellAdmin.mediaCleanupLocationsText);
        if (item.last_attached) {
            usage += ' · ' + escapeHtml(shrinkwellAdmin.mediaCleanupLastAttachedText) + ' ' + escapeHtml(item.last_attached);
        }
        const evidence = Array.isArray(item.evidence) ? item.evidence : [];
        const evidenceItems = evidence.map(function (entry) {
            const reason = entry.reason || entry.detail || '';
            const matchType = entry.match_type || entry.type || '';
            const sourceType = entry.source_type || '';
            return '<li><strong>' + escapeHtml(entry.source_label || shrinkwellAdmin.mediaCleanupDatabaseSourceText) + '</strong>' +
                '<span>' + escapeHtml(reason) + '</span>' +
                '<span>' + escapeHtml(matchType || sourceType) + '</span>' +
                '<span class="shrinkwell-evidence-strength is-' + escapeHtml(entry.confidence || 'low') + '">' + escapeHtml(entry.confidence_label || '') + '</span></li>';
        }).join('');
        const safetyClass = cleanupEligible ? ' is-eligible' : '';
        const safetyText = cleanupEligible ? shrinkwellAdmin.mediaCleanupEligibleEvidenceText : shrinkwellAdmin.mediaCleanupNotSelectableText;

        return '<tr class="shrinkwell-cleanup-result-row" data-status="' + escapeHtml(item.status) + '">' +
            '<th class="check-column"><input type="checkbox" class="shrinkwell-cleanup-item" value="' + escapeHtml(item.id) + '"' + disabled + checked + '></th>' +
            '<td><img class="shrinkwell-cleanup-thumb" src="' + escapeHtml(item.thumbnail || '') + '" alt=""></td>' +
            '<td><strong>' + escapeHtml(item.filename) + '</strong><small>' + usage + '</small>' +
                '<button type="button" class="button-link shrinkwell-cleanup-evidence-toggle" aria-expanded="false" aria-controls="' + detailsId + '">' + escapeHtml(shrinkwellAdmin.mediaCleanupWhyStatusText) + '</button></td>' +
            '<td><span class="shrinkwell-cleanup-pill is-' + escapeHtml(item.status) + '">' + escapeHtml(item.status_label) + '</span>' +
                '<span class="shrinkwell-confidence is-' + escapeHtml(item.confidence || 'low') + '">' + escapeHtml(item.confidence_label || '') + '</span></td>' +
            '<td>' + escapeHtml(item.size) + '</td>' +
            '<td title="' + escapeHtml(item.uploaded_at) + '">' + escapeHtml(item.uploaded_ago) + '</td>' +
            '</tr>' +
            '<tr class="shrinkwell-cleanup-evidence-row" id="' + detailsId + '" data-evidence-for="' + escapeHtml(item.id) + '" hidden><td colspan="6">' +
                '<div class="shrinkwell-cleanup-evidence">' +
                    '<div class="shrinkwell-cleanup-evidence__heading"><strong>' + escapeHtml(shrinkwellAdmin.mediaCleanupWhyStatusText) + '</strong>' +
                        '<span class="shrinkwell-confidence is-' + escapeHtml(item.confidence || 'low') + '">' + escapeHtml(item.confidence_label || '') + '</span></div>' +
                    '<p>' + escapeHtml(item.status_reason || shrinkwellAdmin.mediaCleanupEvidenceFallbackText) + '</p>' +
                    (evidenceItems ? '<ul>' + evidenceItems + '</ul>' : '') +
                    '<p class="shrinkwell-cleanup-evidence__safety' + safetyClass + '">' + escapeHtml(safetyText) + '</p>' +
                '</div></td>' +
            '</tr>';
    }

    function renderCleanupData(scan, trash) {
        const summary = scan.summary || {};
        const items = scan.items || [];
        [
            'total_scanned',
            'used',
            'protected',
            'possibly_unused_high_confidence',
            'needs_review',
            'selected_by_default'
        ].forEach(function (key) {
            $('[data-cleanup-stat="' + key + '"]').text(summary[key] || 0);
        });
        $('[data-cleanup-stat="selected_formatted"]').text(summary.selected_formatted || '0 B');
        const $cleanupTab = $('.shrinkwell-tabs [data-tab="media-cleanup"]');
        $cleanupTab.find('.shrinkwell-tab-badge').remove();
        if (summary.possibly_unused) {
            $cleanupTab.append(' <span class="shrinkwell-tab-badge shrinkwell-tab-badge--warn">' + escapeHtml(summary.possibly_unused) + '</span>');
        }
        ['used', 'possibly_unused', 'protected', 'needs_review'].forEach(function (key) {
            $('[data-cleanup-count="' + key + '"]').text(summary[key] || 0);
        });
        $('#shrinkwell-cleanup-last-scan').text(scan.scanned_at || '—');
        $('[data-cleanup-upgrade="count"]').text(summary.possibly_unused || 0);
        $('[data-cleanup-upgrade="size"]').text(summary.potential_formatted || '0 B');
        $('[data-cleanup-upgrade="old"]').text(summary.old || 0);
        $('#shrinkwell-cleanup-upgrade-button').text(
            summary.potential_bytes > 0
                ? formatText(shrinkwellAdmin.mediaCleanupUpgradeButtonText, summary.potential_formatted || '0 B')
                : shrinkwellAdmin.mediaCleanupUpgradeFallbackText
        );
        $cleanupRows.html(items.length ? items.map(cleanupRowHtml).join('') : '<tr class="shrinkwell-cleanup-empty"><td colspan="6">' + escapeHtml(shrinkwellAdmin.mediaCleanupNoImagesText) + '</td></tr>');
        $cleanupResults.prop('hidden', false);
        $cleanupSelectAll.prop('checked', false).prop('indeterminate', false);
        updateCleanupSelection();

        if (trash) {
            $('[data-trash-stat="count"]').text(trash.count || 0);
            $('[data-trash-stat="formatted"]').text(trash.formatted || '0 B');
            $('[data-trash-stat="days"]').text(trash.days || 0);
            if (shrinkwellAdmin.canBulkCleanup) {
                $('#shrinkwell-cleanup-restore-all, #shrinkwell-cleanup-delete-all').prop('disabled', !trash.count);
            }
        }
    }

    function showCleanupUpgrade() {
        const upgrade = $('#shrinkwell-cleanup-upgrade').prop('hidden', false)[0];
        if (upgrade && typeof upgrade.scrollIntoView === 'function') {
            upgrade.scrollIntoView({behavior: 'smooth', block: 'nearest'});
        }
    }

    function openCleanupModal(action, title, message, buttonText) {
        pendingCleanupAction = action;
        $('#shrinkwell-cleanup-confirm-title').text(title);
        $('#shrinkwell-cleanup-confirm-message').text(message);
        $('[data-cleanup-confirm]').text(buttonText).toggleClass('shrinkwell-button-danger', 'delete' === action);
        $('#shrinkwell-cleanup-confirm').prop('hidden', false);
    }

    $cleanupScanButton.on('click', function () {
        const originalText = $.trim($cleanupScanButton.text());
        $cleanupScanButton.prop('disabled', true);
        $cleanupSpinner.addClass('is-active');
        $cleanupProgress.prop('hidden', false).addClass('is-running');
        $cleanupStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.mediaCleanupScanningText);

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_media_cleanup_scan',
            nonce: shrinkwellAdmin.mediaCleanupNonce,
            mode: 'database'
        }).done(function (response) {
            if (!response || !response.success) {
                $cleanupStatus.addClass('is-error').text(response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText);
                return;
            }
            renderCleanupData(response.data.scan || {}, response.data.trash || {});
            $cleanupStatus.addClass('is-ok').text(shrinkwellAdmin.mediaCleanupDoneText);
        }).fail(function (xhr) {
            const message = xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message ? xhr.responseJSON.data.message : shrinkwellAdmin.errorText;
            $cleanupStatus.addClass('is-error').text(message);
        }).always(function () {
            $cleanupScanButton.prop('disabled', false).text(originalText);
            $cleanupSpinner.removeClass('is-active');
            $cleanupProgress.removeClass('is-running').prop('hidden', true);
        });
    });

    $cleanupSelectAll.on('change', function () {
        $('.shrinkwell-cleanup-item:not(:disabled)').prop('checked', $(this).prop('checked'));
        updateCleanupSelection();
    });

    $(document).on('change', '.shrinkwell-cleanup-item', updateCleanupSelection);

    $(document).on('click', '.shrinkwell-cleanup-evidence-toggle', function () {
        const $button = $(this);
        const detailsId = $button.attr('aria-controls');
        const $details = $('#' + detailsId);
        const expanded = 'true' === $button.attr('aria-expanded');
        $button.attr('aria-expanded', expanded ? 'false' : 'true');
        $details.prop('hidden', expanded);
    });

    $cleanupTrashButton.on('click', function () {
        if ($(this).data('cleanup-locked')) {
            showCleanupUpgrade();
            return;
        }

        const ids = cleanupSelectedIds();
        if (!ids.length) {
            return;
        }
        openCleanupModal('move', shrinkwellAdmin.mediaCleanupMoveTitleText, formatText(shrinkwellAdmin.mediaCleanupMoveConfirmText, ids.length), shrinkwellAdmin.mediaCleanupMoveButtonText);
    });

    function moveSelectedToCleanupTrash() {
        const ids = cleanupSelectedIds();
        if (!ids.length) {
            return;
        }
        $cleanupTrashButton.prop('disabled', true);
        $cleanupStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.mediaCleanupMovingText);
        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_media_cleanup_trash',
            nonce: shrinkwellAdmin.mediaCleanupNonce,
            ids: ids
        }).done(function (response) {
            if (!response || !response.success) {
                $cleanupStatus.addClass('is-error').text(response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText);
                return;
            }
            renderCleanupData(response.data.scan || {}, response.data.trash || {});
            $cleanupStatus.addClass('is-ok').text(formatText(shrinkwellAdmin.mediaCleanupMovedText, response.data.moved || 0));
        }).fail(function () {
            $cleanupStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(updateCleanupSelection);
    }

    $('#shrinkwell-cleanup-restore-all').on('click', function () {
        if ($(this).data('cleanup-locked')) {
            showCleanupUpgrade();
            return;
        }

        if (!window.confirm(shrinkwellAdmin.mediaCleanupRestoreConfirmText)) {
            return;
        }
        const $button = $(this).prop('disabled', true);
        $trashActionStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.mediaCleanupRestoringText);
        $.post(shrinkwellAdmin.ajaxUrl, {action: 'shrinkwell_media_cleanup_restore', nonce: shrinkwellAdmin.mediaCleanupNonce}).done(function (response) {
            if (!response || !response.success) {
                $trashActionStatus.addClass('is-error').text(response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText);
                return;
            }
            renderCleanupData(response.data.scan || {}, response.data.trash || {});
            $trashActionStatus.addClass('is-ok').text(formatText(shrinkwellAdmin.mediaCleanupRestoredText, response.data.restored || 0));
        }).fail(function () {
            $trashActionStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $button.prop('disabled', false);
        });
    });

    $('#shrinkwell-cleanup-delete-all').on('click', function () {
        if ($(this).data('cleanup-locked')) {
            showCleanupUpgrade();
            return;
        }

        const count = parseInt($('[data-trash-stat="count"]').text(), 10) || 0;
        const size = $('[data-trash-stat="formatted"]').text() || '0 B';
        openCleanupModal('delete', shrinkwellAdmin.mediaCleanupDeleteTitleText, formatText(shrinkwellAdmin.mediaCleanupDeleteConfirmText, count, size), shrinkwellAdmin.mediaCleanupDeleteButtonText);
    });

    $(document).on('click', '[data-cleanup-cancel]', function () {
        $('#shrinkwell-cleanup-confirm').prop('hidden', true);
        pendingCleanupAction = null;
    });

    $(document).on('click', '.shrinkwell-limit-modal-close, .shrinkwell-limit-modal-x', closeMonthlyLimitModal);

    $(document).on('click', '.shrinkwell-limit-modal', function (event) {
        if (event.target === this) {
            closeMonthlyLimitModal();
        }
    });

    $(document).on('click', '[data-cleanup-confirm]', function () {
        if ('move' === pendingCleanupAction) {
            $('#shrinkwell-cleanup-confirm').prop('hidden', true);
            pendingCleanupAction = null;
            moveSelectedToCleanupTrash();
            return;
        }

        if ('delete' !== pendingCleanupAction) {
            return;
        }

        const $button = $(this).prop('disabled', true);
        $('#shrinkwell-cleanup-confirm').prop('hidden', true);
        pendingCleanupAction = null;
        $trashActionStatus.removeClass('is-error is-ok').text(shrinkwellAdmin.mediaCleanupDeletingText);
        $.post(shrinkwellAdmin.ajaxUrl, {action: 'shrinkwell_media_cleanup_delete', nonce: shrinkwellAdmin.mediaCleanupNonce}).done(function (response) {
            if (!response || !response.success) {
                $trashActionStatus.addClass('is-error').text(response && response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText);
                return;
            }
            renderCleanupData(response.data.scan || {}, response.data.trash || {});
            $trashActionStatus.addClass('is-ok').text(formatText(shrinkwellAdmin.mediaCleanupDeletedText, response.data.deleted || 0, response.data.freed_formatted || '0 B'));
        }).fail(function () {
            $trashActionStatus.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $button.prop('disabled', false);
        });
    });

    $(document).on('click', '.shrinkwell-test-compression', function (event) {
        const $link = $(this);
        const attachmentId = parseInt($link.data('attachment-id'), 10);
        const originalText = $.trim($link.text());
        const $status = mediaActionStatus($link);

        if (!attachmentId || $link.data('shrinkwell-running')) {
            return;
        }

        event.preventDefault();

        $link
            .data('shrinkwell-running', 1)
            .addClass('is-busy')
            .attr('aria-disabled', 'true')
            .text(shrinkwellAdmin.testingCompressionText);
        $status.removeClass('is-ok is-error').text('');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_test_attachment_compression',
            nonce: shrinkwellAdmin.nonce,
            attachment_id: attachmentId
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $status.addClass('is-error').text(message);
                return;
            }

            const data = response.data || {};
            const savedBytes = data.savedBytes || 0;
            const testedFiles = data.testedFiles || 0;
            const message = savedBytes > 0
                ? formatText(shrinkwellAdmin.compressionTestSavingsText, formatBytes(savedBytes), testedFiles)
                : shrinkwellAdmin.compressionTestNoSavingsText;

            $status.addClass('is-ok').text(message);
        }).fail(function () {
            $status.addClass('is-error').text(shrinkwellAdmin.errorText);
        }).always(function () {
            $link
                .data('shrinkwell-running', 0)
                .removeClass('is-busy')
                .removeAttr('aria-disabled')
                .text(originalText);
        });
    });

    $(document).on('click', '.shrinkwell-optimize-attachment', function (event) {
        const $link = $(this);
        const attachmentId = parseInt($link.data('attachment-id'), 10);
        const originalText = $.trim($link.text());
        const $status = mediaActionStatus($link);

        if (!attachmentId || $link.data('shrinkwell-running')) {
            return;
        }

        event.preventDefault();

        $link
            .data('shrinkwell-running', 1)
            .addClass('is-busy')
            .attr('aria-disabled', 'true')
            .text(shrinkwellAdmin.optimizingImageText);
        $status.removeClass('is-ok is-error').text('');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_bulk_optimize',
            nonce: shrinkwellAdmin.nonce,
            ids: [attachmentId],
            webp_only: 0
        }).done(function (response) {
            if (!response.success || !response.data) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.imageActionFailedText;
                $status.addClass('is-error').text(message);
                return;
            }

            if ((response.data.errors || 0) > 0 || (response.data.skipped || 0) > 0) {
                $status.addClass('is-error').text(response.data.message || shrinkwellAdmin.imageActionFailedText);
                return;
            }

            $status.addClass('is-ok').text(shrinkwellAdmin.imageOptimizedInlineText);
        }).fail(function () {
            $status.addClass('is-error').text(shrinkwellAdmin.imageActionFailedText);
        }).always(function () {
            $link
                .data('shrinkwell-running', 0)
                .removeClass('is-busy')
                .removeAttr('aria-disabled')
                .text(originalText);
        });
    });

    $recommendationButton.on('click', function () {
        $recommendationButton.prop('disabled', true);
        $recommendationResults.prop('hidden', false).html('<p>' + shrinkwellAdmin.scanRecommendationsText + '</p>');

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_recommendation_scan',
            nonce: shrinkwellAdmin.nonce
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $recommendationResults.html('<p class="shrinkwell-test-error">' + escapeHtml(message) + '</p>');
                return;
            }

            lastRecommendedSettings = response.data.settings || null;
            let html = '<p><strong>' + escapeHtml(shrinkwellAdmin.recommendationsDoneText) + '</strong></p>';
            html += '<p>' + escapeHtml(response.data.sampled) + ' images sampled. Average file size: ' + escapeHtml(response.data.averageSize) + '.</p>';
            html += '<div class="shrinkwell-recommendation-list">';

            (response.data.recommendations || []).forEach(function (item) {
                html += '<div class="shrinkwell-recommendation-item">';
                html += '<strong>' + escapeHtml(item.label) + ': ' + escapeHtml(item.value) + '</strong>';
                html += '<p>' + escapeHtml(item.reason) + '</p>';
                html += '</div>';
            });

            html += '</div>';

            if (lastRecommendedSettings) {
                html += '<div class="shrinkwell-recommendation-actions">';
                html += '<button type="button" class="button button-primary" id="shrinkwell-apply-recommended-settings">' + escapeHtml(shrinkwellAdmin.applyRecommendationsText) + '</button>';
                html += '<a class="button" href="' + escapeHtml(shrinkwellAdmin.settingsUrl) + '">' + escapeHtml(shrinkwellAdmin.reviewSettingsText) + '</a>';
                html += '</div>';
            }

            html += '<div class="shrinkwell-delivery-readiness">';
            html += '<p><strong>' + escapeHtml(shrinkwellAdmin.deliveryReadinessTitleText) + '</strong></p>';
            html += '<div class="shrinkwell-delivery-readiness-results" hidden></div>';
            html += '</div>';

            $recommendationResults.html(html);
            runDeliveryTest($recommendationResults.find('.shrinkwell-delivery-readiness-results'));
        }).fail(function () {
            $recommendationResults.html('<p class="shrinkwell-test-error">' + shrinkwellAdmin.errorText + '</p>');
        }).always(function () {
            $recommendationButton.prop('disabled', false);
        });
    });

    $recommendationResults.on('click', '#shrinkwell-apply-recommended-settings', function () {
        const $applyButton = $(this);

        if (!lastRecommendedSettings) {
            return;
        }

        $applyButton.prop('disabled', true).text(shrinkwellAdmin.applyingRecommendationsText);

        $.post(shrinkwellAdmin.ajaxUrl, {
            action: 'shrinkwell_apply_recommendations',
            nonce: shrinkwellAdmin.nonce,
            settings: JSON.stringify(lastRecommendedSettings)
        }).done(function (response) {
            if (!response.success) {
                const message = response.data && response.data.message ? response.data.message : shrinkwellAdmin.errorText;
                $recommendationResults.append('<p class="shrinkwell-test-error">' + escapeHtml(message) + '</p>');
                $applyButton.prop('disabled', false).text(shrinkwellAdmin.applyRecommendationsText);
                return;
            }

            let html = '<div class="shrinkwell-apply-success">';
            html += '<p><strong>' + escapeHtml(shrinkwellAdmin.recommendationsAppliedText) + '</strong></p>';
            html += '<p>' + escapeHtml(response.data.message) + '</p>';
            html += '<p class="shrinkwell-recommendation-actions">';
            html += '<a class="button button-primary" href="' + escapeHtml(shrinkwellAdmin.bulkUrl) + '">' + escapeHtml(shrinkwellAdmin.bulkNextText) + '</a>';
            html += '<a class="button" href="' + escapeHtml(shrinkwellAdmin.settingsUrl) + '">' + escapeHtml(shrinkwellAdmin.reviewSettingsText) + '</a>';
            html += '</p></div>';
            $recommendationResults.append(html);
            $applyButton.remove();
        }).fail(function () {
            $recommendationResults.append('<p class="shrinkwell-test-error">' + shrinkwellAdmin.errorText + '</p>');
            $applyButton.prop('disabled', false).text(shrinkwellAdmin.applyRecommendationsText);
        });
    });

    const $licenseForm = $('#shrinkwell-license-form');

    function normalizeLicenseResponse(response) {
        if (typeof response === 'string') {
            try {
                response = JSON.parse(response);
            } catch (error) {
                const text = $('<div>').html(response).text().replace(/\s+/g, ' ').trim();

                return {
                    success: false,
                    message: text ? text.substring(0, 240) : (shrinkwellAdmin.licenseActivationFailedText || shrinkwellAdmin.errorText),
                    nextPage: ''
                };
            }
        }

        if (!response) {
            return {
                success: false,
                message: shrinkwellAdmin.licenseActivationFailedText || shrinkwellAdmin.errorText,
                nextPage: ''
            };
        }

        const data = response.data && typeof response.data === 'object' ? response.data : {};
        const error = response.error || data.error || null;
        const errorMessage = error && typeof error === 'object' && error.message ? error.message : '';
        const message = data.message || response.message || errorMessage || (typeof error === 'string' ? error : '');
        const nextPage = response.next_page || data.next_page || response.nextPage || data.nextPage || '';

        return {
            success: !!response.success,
            message: message || (response.success ? shrinkwellAdmin.licenseActivatedText : (shrinkwellAdmin.licenseActivationFailedText || shrinkwellAdmin.errorText)),
            nextPage: nextPage
        };
    }

    function normalizeLicenseAjaxError(xhr) {
        if (xhr && xhr.responseJSON) {
            const jsonResult = normalizeLicenseResponse(xhr.responseJSON);

            if (jsonResult.message && jsonResult.message !== shrinkwellAdmin.errorText) {
                return jsonResult.message;
            }
        }

        if (xhr && xhr.responseText) {
            const textResult = normalizeLicenseResponse(xhr.responseText);

            if (textResult.message) {
                return textResult.message;
            }
        }

        return shrinkwellAdmin.licenseActivationFailedText || shrinkwellAdmin.errorText;
    }

    function looksLikeMaskedLicenseKey(value) {
        return /[•●*]{2,}/.test(value) || /\.{2,}/.test(value);
    }

    if ($licenseForm.length && window.location.hash === '#shrinkwell-license-form') {
        window.setTimeout(function () {
            $licenseForm.find('input').trigger('focus');
        }, 120);
    }

    $licenseForm.on('submit', function (event) {
        event.preventDefault();

        const $form = $(this);
        const $button = $form.find('button[type="submit"]');
        const $status = $('#shrinkwell-license-status');
        const licenseKey = $.trim($('#shrinkwell-license-key').val());

        if (!licenseKey) {
            $status.removeClass('is-ok').addClass('is-error').text(shrinkwellAdmin.licenseEmptyText || shrinkwellAdmin.errorText);
            return;
        }

        if (looksLikeMaskedLicenseKey(licenseKey)) {
            $status.removeClass('is-ok').addClass('is-error').text(shrinkwellAdmin.licenseMaskedText || shrinkwellAdmin.errorText);
            return;
        }

        const isLicenseId = /^\d+$/.test(licenseKey);
        const isLicenseKey = /^sk_/i.test(licenseKey);

        if (isLicenseId) {
            $status.removeClass('is-ok').addClass('is-error').text(shrinkwellAdmin.licenseIdUnavailableText || shrinkwellAdmin.errorText);
            return;
        }

        if (!isLicenseKey) {
            $status.removeClass('is-ok').addClass('is-error').text(shrinkwellAdmin.licenseFormatText || shrinkwellAdmin.errorText);
            return;
        }

        $button.prop('disabled', true);
        $status.removeClass('is-error is-ok').text(shrinkwellAdmin.licenseActivatingText);

        const data = {
            action: 'shrinkwell_activate_license',
            nonce: shrinkwellAdmin.licenseNonce
        };

        data.license_key = licenseKey;

        $.post(shrinkwellAdmin.ajaxUrl, data).done(function (response) {
            const result = normalizeLicenseResponse(response);

            if (!result.success) {
                $status.addClass('is-error').text(result.message);
                $button.prop('disabled', false);
                return;
            }

            $status.addClass('is-ok').text(result.message);

            if (result.nextPage) {
                window.location.href = result.nextPage;
                return;
            }

            window.setTimeout(function () {
                window.location.reload();
            }, 1200);
        }).fail(function (xhr) {
            $status.addClass('is-error').text(normalizeLicenseAjaxError(xhr));
            $button.prop('disabled', false);
        });
    });

    $('.shrinkwell-resize-presets button').on('click', function () {
        const $preset = $(this);
        $('#shrinkwell-max-width').val($preset.data('width'));
        $('#shrinkwell-max-height').val($preset.data('height'));
        $('.shrinkwell-resize-presets button').removeClass('button-primary');
        $preset.addClass('button-primary');
    });

})(jQuery);
