<?php
/**
 * File State Renderer - Assets (CSS + JavaScript)
 *
 * Contains all styling and JavaScript for the File State Scanner UI.
 *
 * @package StaticQ
 */

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

class SQMedia_File_State_Renderer_Assets {

    /**
     * Render CSS styles
     */
    public function render_styles(): void {
        wp_enqueue_style('sqmedia-file-state', SQMEDIA_PLUGIN_URL . 'admin/css/sqmedia-file-state.css', [], SQMEDIA_VERSION);
    }


    /**
     * Render JavaScript
     *
     * Captures the inline JS template into an output buffer (ob_start at the
     * top, ob_get_clean at the bottom of this function), then hands the
     * captured string to wp_add_inline_script(). The ob_start / ob_get_clean
     * pair is intentionally scoped to this single function.
     */
    public function render_scripts(array $state): void {
        ob_start();
        ?>
        (function($) {
            'use strict';

            var SQMediaHealthCheck = {
                // State
                scanId: <?php echo wp_json_encode($state['scan_id'] ?? null); ?>,
                status: <?php echo wp_json_encode($state['status']); ?>,
                filterType: '',
                currentPage: 1,
                pollInterval: null,
                startTime: <?php
                    $scan_start_ms = null;
                    $fix_start_ms = null;
                    if (!empty($state['started_at'])) {
                        // Convert WP local time to UTC milliseconds for reliable JS comparison
                        $ts = strtotime($state['started_at']) - (int) (get_option('gmt_offset', 0) * HOUR_IN_SECONDS);
                        $ms = $ts * 1000;
                        if (in_array($state['status'] ?? '', ['scanning', 'building_index'], true)) {
                            $scan_start_ms = $ms;
                        }
                    }
                    // Fix timer uses its own start time, not the scan start time
                    if (($state['status'] ?? '') === 'fixing' && !empty($state['results']['fix_started_at'])) {
                        $fix_ts = strtotime($state['results']['fix_started_at']) - (int) (get_option('gmt_offset', 0) * HOUR_IN_SECONDS);
                        $fix_start_ms = $fix_ts * 1000;
                    }
                    echo wp_json_encode($scan_start_ms);
                ?>,
                scanPolling: false,
                fixPollInterval: null,
                fixStartTime: <?php echo wp_json_encode($fix_start_ms); ?>,
                fixCompleted: false,
                fixPolling: false,

                // Render smart pagination buttons
                renderPaginationButtons: function(current, totalPages) {
                    if (totalPages <= 1) return '';

                    var html = '';
                    var prevDisabled = current <= 1 ? ' disabled' : '';
                    html += '<button type="button" class="sqmedia-pagination-btn sqmedia-pagination-prev' + prevDisabled + '" data-page="' + Math.max(1, current - 1) + '"' + prevDisabled + '>‹</button>';

                    var pagesToShow = [];
                    if (totalPages <= 7) {
                        for (var i = 1; i <= totalPages; i++) pagesToShow.push(i);
                    } else {
                        pagesToShow.push(1);
                        var rangeStart = Math.max(2, current - 1);
                        var rangeEnd = Math.min(totalPages - 1, current + 1);
                        if (rangeStart <= 3) { rangeStart = 2; rangeEnd = Math.min(4, totalPages - 1); }
                        if (rangeEnd >= totalPages - 2) { rangeEnd = totalPages - 1; rangeStart = Math.max(2, totalPages - 3); }
                        if (rangeStart > 2) pagesToShow.push('...');
                        for (var j = rangeStart; j <= rangeEnd; j++) pagesToShow.push(j);
                        if (rangeEnd < totalPages - 1) pagesToShow.push('...');
                        pagesToShow.push(totalPages);
                    }

                    for (var k = 0; k < pagesToShow.length; k++) {
                        if (pagesToShow[k] === '...') {
                            html += '<span class="sqmedia-pagination-ellipsis">…</span>';
                        } else {
                            html += '<button type="button" class="sqmedia-pagination-btn' + (pagesToShow[k] === current ? ' active' : '') + '" data-page="' + pagesToShow[k] + '">' + pagesToShow[k] + '</button>';
                        }
                    }

                    var nextDisabled = current >= totalPages ? ' disabled' : '';
                    html += '<button type="button" class="sqmedia-pagination-btn sqmedia-pagination-next' + nextDisabled + '" data-page="' + Math.min(totalPages, current + 1) + '"' + nextDisabled + '>›</button>';
                    return html;
                },

                init: function() {
                    if (typeof sqmediaAdmin === 'undefined' || !sqmediaAdmin.nonce) {
                        console.error('SQMediaHealthCheck: sqmediaAdmin.nonce is not available!');
                        return;
                    }
                    this.bindEvents();
                    this.resumeIfNeeded();
                },

                bindEvents: function() {
                    var self = this;

                    // Start scan
                    $(document).on('click', '.sqmedia-start-scan-btn', function(e) {
                        e.preventDefault();
                        self.startScan();
                    });

                    // Cancel scan
                    $(document).on('click', '.sqmedia-cancel-scan-btn', function() {
                        if (confirm('<?php esc_html_e('Cancel this scan? Progress will be lost and you will need to start over.', 'staticq-media'); ?>')) {
                            self.cancelScan();
                        }
                    });

                    // Pause scan
                    $(document).on('click', '.sqmedia-pause-scan-btn', function() {
                        self.pauseScan();
                    });

                    // Resume scan
                    $(document).on('click', '.sqmedia-resume-scan-btn', function() {
                        self.resumeScan($(this).data('scan-id'));
                    });

                    // Resume fix
                    $(document).on('click', '.sqmedia-resume-fix-btn', function() {
                        self.resumeFix($(this).data('scan-id'));
                    });

                    // Fix all
                    $(document).on('click', '.sqmedia-fix-all-btn', function() {
                        self.fixAll($(this).data('scan-id'));
                    });

                    // Backup tables
                    $(document).on('click', '.sqmedia-backup-tables-btn', function() {
                        var $btn = $(this);
                        var $section = $btn.closest('.sqmedia-backup-section');
                        var $status = $section.find('.sqmedia-backup-status');
                        var action = $btn.data('action');
                        var hasExisting = $status.text().trim() !== '<?php echo esc_js(__('No backup yet', 'staticq-media')); ?>';

                        if (hasExisting && !confirm('<?php echo esc_js(__('This will replace the existing backup. Continue?', 'staticq-media')); ?>')) {
                            return;
                        }

                        $btn.prop('disabled', true).text('<?php echo esc_js(__('Creating backup...', 'staticq-media')); ?>');

                        $.post(sqmediaAdmin.ajaxurl, {
                            action: action,
                            nonce: sqmediaAdmin.nonce
                        }, function(response) {
                            $btn.prop('disabled', false).text('<?php echo esc_js(__('Backup Tables', 'staticq-media')); ?>');
                            if (response.success) {
                                $status.text(response.data.message);
                            } else {
                                $status.text('<?php echo esc_js(__('Backup failed', 'staticq-media')); ?>');
                            }
                        }).fail(function() {
                            $btn.prop('disabled', false).text('<?php echo esc_js(__('Backup Tables', 'staticq-media')); ?>');
                            $status.text('<?php echo esc_js(__('Backup failed', 'staticq-media')); ?>');
                        });
                    });

                    // Pause fix
                    $(document).on('click', '.sqmedia-pause-fix-btn', function() {
                        self.pauseFix($(this).data('scan-id'));
                    });

                    // Stop fix
                    $(document).on('click', '.sqmedia-stop-fix-btn', function() {
                        self.stopFix($(this).data('scan-id'));
                    });

                    // View/Hide details toggle
                    $(document).on('click', '.sqmedia-view-details-btn', function() {
                        var $btn = $(this);
                        var $details = $('#sqmedia-scanner-details');

                        if ($details.is(':visible')) {
                            $details.slideUp();
                            $btn.html('👁 <?php esc_html_e("View Details", "staticq-media"); ?>');
                        } else {
                            $details.slideDown();
                            $btn.html('👁 <?php esc_html_e("Hide Details", "staticq-media"); ?>');
                        }
                    });

                    // Fix single attachment
                    $(document).on('click', '.sqmedia-fix-single-btn', function() {
                        var attachmentId = $(this).data('attachment-id');
                        var scanId = $('#sqmedia-scanner-card').data('scan-id');
                        self.fixSingle(attachmentId, scanId, $(this));
                    });

                    // Tab clicks
                    $(document).on('click', '.sqmedia-tab-btn', function() {
                        var $btn = $(this);
                        var type = $btn.data('type');

                        // Update active state
                        $btn.closest('.sqmedia-tabs-nav').find('.sqmedia-tab-btn').removeClass('active');
                        $btn.addClass('active');

                        // Get tab data
                        var tabDataJson = $('#sqmedia-tab-data').text();
                        var tabData = tabDataJson ? JSON.parse(tabDataJson) : {};
                        var currentTab = tabData[type] || {};
                        var totalScanned = parseInt($('#sqmedia-total-scanned').val()) || 0;

                        var $descEl = $('#sqmedia-scanner-tab-desc');
                        var $successEl = $('#sqmedia-scanner-success-msg');
                        var $tableEl = $('#sqmedia-scanner-table');
                        var $searchEl = $('#sqmedia-scanner-search');

                        // Always show description
                        if (currentTab.description) {
                            if (currentTab.allow_html) {
                                $descEl.html(currentTab.description).show();
                            } else {
                                $descEl.text(currentTab.description).show();
                            }
                        } else {
                            $descEl.hide();
                        }

                        // Show success message or table based on count
                        if (type !== '' && currentTab.count === 0) {
                            $successEl.find('.sqmedia-success-text').text(currentTab.success_message);
                            $successEl.show();
                            $tableEl.hide();
                            $searchEl.hide();
                        } else {
                            $successEl.hide();
                            $tableEl.show();
                            if (type === '' || currentTab.count > 0) {
                                $searchEl.show();
                            }
                            self.filterType = type;
                            self.loadDetails(1);
                        }
                    });

                    // Pagination
                    $(document).on('click', '.sqmedia-pagination-btn', function() {
                        var page = $(this).data('page');
                        if (page) {
                            self.loadDetails(page);
                        }
                    });

                    // Search (debounced)
                    var searchTimeout;
                    $(document).on('input', '.sqmedia-filter-search', function() {
                        clearTimeout(searchTimeout);
                        searchTimeout = setTimeout(function() {
                            self.loadDetails(1);
                        }, 300);
                    });

                    // Expand row to see file details
                    $(document).on('click', '.sqmedia-expand-row', function() {
                        var $btn = $(this);
                        var $row = $btn.closest('tr');
                        var $detailRow = $row.next('.sqmedia-file-details-row');
                        var attachmentId = $btn.data('attachment-id');
                        var scanId = $btn.data('scan-id');

                        if ($detailRow.length) {
                            $detailRow.toggle();
                            $btn.text($detailRow.is(':visible') ? '▼' : '▶');
                        } else {
                            $btn.text('⏳');
                            self.loadFileDetails(attachmentId, scanId, $row, $btn);
                        }
                    });
                },

                resumeIfNeeded: function() {
                    if (this.status === 'scanning' || this.status === 'building_index') {
                        if (!window.sqActiveOperation) window.sqActiveOperation = '<?php esc_html_e('Media Library Scan', 'staticq-media'); ?>';
                        this.startPolling();
                    }
                    if (this.status === 'fixing') {
                        if (!window.sqActiveOperation) window.sqActiveOperation = '<?php esc_html_e('Repair All', 'staticq-media'); ?>';
                        this.startFixPolling(this.scanId);
                    }
                },

                startScan: function() {
                    if (!window.sqStartOperation('<?php esc_html_e('Media Library Scan', 'staticq-media'); ?>')) return;
                    var self = this;
                    var $card = $('#sqmedia-scanner-card');
                    var $btn = $card.find('.sqmedia-start-scan-btn');
                    var overwrite = $('#sqmedia-overwrite-existing').is(':checked') ? 1 : 0;

                    $btn.prop('disabled', true).text('<?php esc_html_e('Starting...', 'staticq-media'); ?>');

                    $.post(ajaxurl, {
                        action: 'sqmedia_start_health_scan',
                        nonce: sqmediaAdmin.nonce,
                        overwrite_existing: overwrite
                    }, function(response) {
                        if (response.success) {
                            self.scanId = response.data.scan_id;
                            self.status = response.data.status || 'building_index';
                            self.showScanningUI(response.data.status || 'scanning');
                            self.startPolling();
                        } else {
                            alert(response.data || '<?php esc_html_e('Failed to start scan', 'staticq-media'); ?>');
                            window.sqEndOperation();
                            $btn.prop('disabled', false).text('🔍 <?php esc_html_e('Scan Media Library', 'staticq-media'); ?>');
                        }
                    }).fail(function() {
                        alert('<?php esc_html_e('Request failed', 'staticq-media'); ?>');
                        window.sqEndOperation();
                        $btn.prop('disabled', false);
                    });
                },

                showScanningUI: function(status) {
                    var $card = $('#sqmedia-scanner-card');
                    var $body = $card.find('.sqmedia-phase-body');

                    $card.attr('data-status', status);

                    $body.find('.sqmedia-progress-container, .sqmedia-scan-controls, .sqmedia-button-group, .sqmedia-details-panel, .sqmedia-summary-grid, .sqmedia-last-scan, .sqmedia-paused-actions, .sqmedia-alert, .sqmedia-hint, .sqmedia-start-scan-btn, .sqmedia-verification-row, .sqmedia-critical-section, .sqmedia-cascade-report, .sqmedia-overwrite-option, .sqmedia-fix-progress').remove();

                    var statusText = status === 'building_index'
                        ? '<?php esc_html_e('Building file index...', 'staticq-media'); ?>'
                        : '<?php esc_html_e('Starting scan...', 'staticq-media'); ?>';

                    var html = '<div class="sqmedia-progress-container" id="sqmedia-scanner-progress">';
                    html += '<div class="sqmedia-progress-text">';
                    html += '<span class="sqmedia-spinner"></span>';
                    html += '<span id="sqmedia-scanner-progress-text">' + statusText + '</span>';
                    html += '<span id="sqmedia-scanner-elapsed"></span>';
                    html += '</div></div>';
                    html += '<div class="sqmedia-scan-controls">';
                    html += '<button type="button" class="button button-secondary sqmedia-pause-scan-btn">⏸️ <?php esc_html_e('Pause', 'staticq-media'); ?></button>';
                    html += '<button type="button" class="button button-link sqmedia-cancel-scan-btn">✔ <?php esc_html_e('Cancel', 'staticq-media'); ?></button>';
                    html += '</div>';

                    $body.append(html);

                    var $badge = $card.find('.sqmedia-status-badge');
                    $badge.removeClass('sqmedia-status-not-scanned sqmedia-status-clean sqmedia-status-issues sqmedia-status-critical sqmedia-status-paused')
                          .addClass('sqmedia-status-scanning')
                          .html('⏳ <?php esc_html_e('In Progress', 'staticq-media'); ?>');

                    $('#sqmedia-scanner-subtitle').text(status === 'building_index'
                        ? '<?php esc_html_e('Building file index...', 'staticq-media'); ?>'
                        : '<?php esc_html_e('Scanning...', 'staticq-media'); ?>');
                },

                startPolling: function() {
                    var self = this;
                    // startTime is a UTC millisecond timestamp from PHP, or null
                    if (!this.startTime) {
                        this.startTime = Date.now();
                    }
                    this.pollInterval = setInterval(function() {
                        self.pollProgress();
                    }, 3000);
                    this.pollProgress();
                },

                pollProgress: function() {
                    var self = this;

                    if (!this.scanId) {
                        self.stopPolling();
                        return;
                    }

                    if (this.scanPolling) return;
                    this.scanPolling = true;

                    $.post(ajaxurl, {
                        action: 'sqmedia_process_health_batch',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: this.scanId
                    }, function(response) {
                        self.scanPolling = false;
                        if (response.success) {
                            self.updateProgress(response.data);
                            if (response.data.done || response.data.status === 'completed') {
                                self.stopPolling();
                                window.sqEndOperation();
                                setTimeout(function() { location.reload(); }, 500);
                            }
                        }
                    }).fail(function() {
                        self.scanPolling = false;
                    });
                },

                updateProgress: function(data) {
                    var $text = $('#sqmedia-scanner-progress-text');
                    var $elapsed = $('#sqmedia-scanner-elapsed');

                    if (data.status === 'building_index') {
                        var message = data.phase_message || '<?php esc_html_e('Building file index...', 'staticq-media'); ?>';
                        var html = message.replace(/\n/g, '<br><small style="color:#666;">') + (message.indexOf('\n') > -1 ? '</small>' : '');
                        $text.html(html);
                    } else {
                        $text.text('<?php esc_html_e('Processing attachment', 'staticq-media'); ?> ' + (data.processed || 0).toLocaleString() + ' <?php esc_html_e('of', 'staticq-media'); ?> ' + (data.total || 0).toLocaleString());
                    }

                    if (this.startTime) {
                        var elapsed = Math.floor((Date.now() - this.startTime) / 1000);
                        var minutes = Math.floor(elapsed / 60);
                        var seconds = elapsed % 60;
                        $elapsed.text('<?php esc_html_e('Elapsed:', 'staticq-media'); ?> ' + minutes + 'm ' + seconds + 's');
                    }
                },

                stopPolling: function() {
                    if (this.pollInterval) {
                        clearInterval(this.pollInterval);
                        this.pollInterval = null;
                    }
                },

                cancelScan: function() {
                    var self = this;
                    $.post(ajaxurl, {
                        action: 'sqmedia_cancel_health_scan',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: this.scanId
                    }, function() {
                        self.stopPolling();
                        window.sqEndOperation();
                        location.reload();
                    });
                },

                pauseScan: function() {
                    $.post(ajaxurl, {
                        action: 'sqmedia_pause_health_scan',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: this.scanId
                    }, function(response) {
                        if (response.success) {
                            window.sqEndOperation();
                            location.reload();
                        } else {
                            alert(response.data || '<?php esc_html_e('Failed to pause scan', 'staticq-media'); ?>');
                        }
                    });
                },

                resumeScan: function(scanId) {
                    if (!window.sqStartOperation('<?php esc_html_e('Media Library Scan', 'staticq-media'); ?>')) return;
                    var self = this;
                    var $btn = $('.sqmedia-resume-scan-btn');
                    $btn.prop('disabled', true).text('<?php esc_html_e('Resuming...', 'staticq-media'); ?>');

                    $.post(ajaxurl, {
                        action: 'sqmedia_resume_health_scan',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) {
                            self.scanId = scanId;
                            self.status = 'scanning';
                            location.reload();
                        } else {
                            alert(response.data || '<?php esc_html_e('Failed to resume scan', 'staticq-media'); ?>');
                            window.sqEndOperation();
                            $btn.prop('disabled', false).text('<?php esc_html_e('Resume Scan', 'staticq-media'); ?>');
                        }
                    }).fail(function() {
                        window.sqEndOperation();
                        $btn.prop('disabled', false).text('<?php esc_html_e('Resume Scan', 'staticq-media'); ?>');
                    });
                },

                fixAll: function(scanId) {
                    if (!window.sqStartOperation('<?php esc_html_e('Repair All', 'staticq-media'); ?>')) return;
                    var self = this;
                    scanId = scanId || this.scanId;

                    if (!scanId) {
                        alert('<?php esc_html_e('No scan ID available. Please run a scan first.', 'staticq-media'); ?>');
                        window.sqEndOperation();
                        return;
                    }

                    if (!confirm('<?php esc_html_e('This will fix all issues. Continue?', 'staticq-media'); ?>')) {
                        window.sqEndOperation();
                        return;
                    }

                    // Show progress UI immediately so user sees feedback
                    self.showFixingUI('...');

                    $.post(ajaxurl, {
                        action: 'sqmedia_start_health_fix',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) {
                            self.scanId = scanId;
                            self.showFixingUI(response.data.total);
                            self.startFixPolling(scanId);
                        } else {
                            alert(response.data || '<?php esc_html_e('Failed to start fix', 'staticq-media'); ?>');
                            window.sqEndOperation();
                            location.reload();
                        }
                    });
                },

                showFixingUI: function(total) {
                    var $card = $('#sqmedia-scanner-card');
                    var $body = $card.find('.sqmedia-phase-body');

                    $card.attr('data-status', 'fixing');

                    $body.find('.sqmedia-progress-container, .sqmedia-scan-controls, .sqmedia-button-group, .sqmedia-details-panel, .sqmedia-summary-grid, .sqmedia-last-scan, .sqmedia-paused-actions, .sqmedia-alert, .sqmedia-hint, .sqmedia-start-scan-btn, .sqmedia-fix-progress, .sqmedia-cascade-report').remove();

                    var html = '<div class="sqmedia-fix-progress">';
                    html += '<div class="sqmedia-progress-container" id="sqmedia-scanner-fix-progress">';
                    html += '<div class="sqmedia-progress-bar"><div class="sqmedia-progress-fill" style="width: 0%;"></div></div>';
                    html += '<div class="sqmedia-progress-text">';
                    html += '<span class="sqmedia-spinner"></span>';
                    html += '<span id="sqmedia-scanner-fix-text"><?php echo esc_js(__('Fixing attachment 0 of', 'staticq-media')); ?> ' + total + '</span>';
                    html += '<span id="sqmedia-scanner-fix-elapsed"></span>';
                    html += '</div></div>';
                    html += '<div class="sqmedia-fix-stats" id="sqmedia-scanner-fix-stats" style="margin-top: 10px; font-size: 13px; color: #646970;">';
                    html += '<span class="sqmedia-fix-success">✓ 0 <?php echo esc_js(__('fixed', 'staticq-media')); ?></span>';
                    html += ' &nbsp; ';
                    html += '<span class="sqmedia-fix-errors">✔ 0 <?php echo esc_js(__('errors', 'staticq-media')); ?></span>';
                    html += '</div>';
                    html += '<div class="sqmedia-scan-controls" style="margin-top: 15px;">';
                    html += '<button type="button" class="button button-secondary sqmedia-pause-fix-btn" data-scan-id="' + this.scanId + '">⏸️ <?php esc_html_e('Pause', 'staticq-media'); ?></button>';
                    html += ' ';
                    html += '<button type="button" class="button button-link sqmedia-stop-fix-btn" data-scan-id="' + this.scanId + '">⏹️ <?php esc_html_e('Stop', 'staticq-media'); ?></button>';
                    html += '</div>';
                    html += '</div>';

                    $body.append(html);

                    var $badge = $card.find('.sqmedia-status-badge');
                    $badge.removeClass('sqmedia-status-not-scanned sqmedia-status-clean sqmedia-status-issues sqmedia-status-critical sqmedia-status-paused sqmedia-status-scanning')
                          .addClass('sqmedia-status-fixing')
                          .html('🔧 <?php esc_html_e('Fixing...', 'staticq-media'); ?>');

                    $('#sqmedia-scanner-subtitle').text('<?php esc_html_e('Fixing issues...', 'staticq-media'); ?>');
                },

                startFixPolling: function(scanId) {
                    var self = this;
                    // fixStartTime is a UTC millisecond timestamp from PHP, or null
                    if (!this.fixStartTime) {
                        this.fixStartTime = Date.now();
                    }
                    this.fixCompleted = false;
                    this.fixPolling = false;
                    this.fixPollInterval = setInterval(function() {
                        self.pollFixProgress(scanId);
                    }, 3000);
                    this.pollFixProgress(scanId);
                },

                stopFixPolling: function() {
                    if (this.fixPollInterval) {
                        clearInterval(this.fixPollInterval);
                        this.fixPollInterval = null;
                    }
                },

                pollFixProgress: function(scanId) {
                    var self = this;
                    if (this.fixCompleted) { this.stopFixPolling(); return; }
                    if (this.fixPolling) return;

                    this.fixPolling = true;

                    $.post(ajaxurl, {
                        action: 'sqmedia_process_fix_batch',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        self.fixPolling = false;
                        if (self.fixCompleted) return;

                        if (response.success) {
                            var data = response.data;
                            if (data.done || data.status === 'completed') {
                                self.stopFixPolling();
                                self.onFixComplete(data.fixed || 0, data.errors || 0);
                            } else if (data.status === 'paused') {
                                self.stopFixPolling();
                                window.sqEndOperation();
                                location.reload();
                            } else {
                                self.updateFixProgress(data.processed || 0, data.total || 0, data.fixed || 0, data.errors || 0);
                            }
                        }
                    }).fail(function() {
                        self.fixPolling = false;
                    });
                },

                updateFixProgress: function(processed, total, fixed, errorCount) {
                    var progress = total > 0 ? Math.round((processed / total) * 100) : 0;
                    var $container = $('#sqmedia-scanner-fix-progress');

                    $container.find('.sqmedia-progress-fill').css('width', progress + '%').text(progress > 5 ? progress + '%' : '');
                    $('#sqmedia-scanner-fix-text').text('<?php echo esc_js(__('Fixing attachment', 'staticq-media')); ?> ' + processed + ' <?php echo esc_js(__('of', 'staticq-media')); ?> ' + total);

                    if (this.fixStartTime) {
                        var elapsed = Math.floor((Date.now() - this.fixStartTime) / 1000);
                        var minutes = Math.floor(elapsed / 60);
                        var seconds = elapsed % 60;
                        var timeStr = minutes > 0 ? minutes + 'm ' + seconds + 's' : seconds + 's';
                        $('#sqmedia-scanner-fix-elapsed').text(timeStr);
                    }

                    var $stats = $('#sqmedia-scanner-fix-stats');
                    $stats.find('.sqmedia-fix-success').text('✓ ' + fixed + ' <?php echo esc_js(__('fixed', 'staticq-media')); ?>');
                    $stats.find('.sqmedia-fix-errors').text('✔ ' + errorCount + ' <?php echo esc_js(__('errors', 'staticq-media')); ?>');
                    if (errorCount > 0) $stats.find('.sqmedia-fix-errors').css('color', '#d63638');
                },

                onFixComplete: function(fixed, errors) {
                    if (this.fixCompleted) return;
                    this.fixCompleted = true;
                    window.sqEndOperation();
                    var message = '<?php echo esc_js(__('Fix complete!', 'staticq-media')); ?>\n';
                    message += fixed + ' <?php echo esc_js(__('attachments fixed', 'staticq-media')); ?>';
                    if (errors > 0) message += '\n' + errors + ' <?php echo esc_js(__('errors occurred', 'staticq-media')); ?>';
                    alert(message);
                    location.reload();
                },

                pauseFix: function(scanId) {
                    var self = this;
                    if (!scanId) { alert('<?php esc_html_e('No scan ID available', 'staticq-media'); ?>'); return; }
                    $.post(ajaxurl, {
                        action: 'sqmedia_pause_fix',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) { self.stopFixPolling(); window.sqEndOperation(); location.reload(); }
                        else { alert(response.data || '<?php esc_html_e('Failed to pause', 'staticq-media'); ?>'); }
                    });
                },

                stopFix: function(scanId) {
                    var self = this;
                    if (!scanId) { alert('<?php esc_html_e('No scan ID available', 'staticq-media'); ?>'); return; }
                    if (!confirm('<?php esc_html_e('Stop fixing? Progress so far will be kept but remaining issues will not be fixed.', 'staticq-media'); ?>')) return;
                    $.post(ajaxurl, {
                        action: 'sqmedia_stop_fix',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) { self.stopFixPolling(); self.fixCompleted = true; window.sqEndOperation(); location.reload(); }
                        else { alert(response.data || '<?php esc_html_e('Failed to stop', 'staticq-media'); ?>'); }
                    });
                },

                resumeFix: function(scanId) {
                    if (!window.sqStartOperation('<?php esc_html_e('Repair All', 'staticq-media'); ?>')) return;
                    $.post(ajaxurl, {
                        action: 'sqmedia_resume_fix',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) location.reload();
                        else { window.sqEndOperation(); alert(response.data || '<?php esc_html_e('Failed to resume', 'staticq-media'); ?>'); }
                    });
                },

                fixSingle: function(attachmentId, scanId, $btn) {
                    var self = this;
                    var $row = $btn.closest('tr');
                    $btn.prop('disabled', true).text('...');

                    $.post(ajaxurl, {
                        action: 'sqmedia_fix_single_attachment',
                        nonce: sqmediaAdmin.nonce,
                        attachment_id: attachmentId,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success) {
                            $row.addClass('sqmedia-row-fixed');
                            $btn.text('✓');
                            setTimeout(function() {
                                var $nextRow = $row.next('.sqmedia-file-details-row');
                                if ($nextRow.length) $nextRow.remove();
                                $row.fadeOut(300, function() {
                                    $row.remove();
                                    self.loadDetails(self.currentPage);
                                });
                            }, 500);
                        } else {
                            var errMsg = response.data || '<?php esc_html_e('Fix failed', 'staticq-media'); ?>';
                            $row.addClass('sqmedia-row-error');
                            $btn.replaceWith('<span class="sqmedia-fix-error-msg" style="color: #721c24; font-size: 11px;">' + $('<span>').text(errMsg).html() + '</span>');
                        }
                    }).fail(function() {
                        $row.addClass('sqmedia-row-error');
                        $btn.replaceWith('<span class="sqmedia-fix-error-msg" style="color: #721c24; font-size: 11px;"><?php esc_html_e('Network error', 'staticq-media'); ?></span>');
                    });
                },

                loadDetails: function(page) {
                    var self = this;
                    var $details = $('#sqmedia-scanner-details');
                    var $table = $('#sqmedia-scanner-table');
                    var search = $details.find('.sqmedia-filter-search').val() || '';

                    self.currentPage = page;

                    if (!this.scanId) return;

                    $table.css('opacity', '0.5');

                    $.post(ajaxurl, {
                        action: 'sqmedia_get_scan_details',
                        nonce: sqmediaAdmin.nonce,
                        scan_id: this.scanId,
                        filter_type: this.filterType || '',
                        search: search,
                        page: page
                    }, function(response) {
                        $table.css('opacity', '1');
                        if (response.success) {
                            self.renderDetailsTable(response.data, self.scanId);
                        }
                    }).fail(function() {
                        $table.css('opacity', '1');
                    });
                },

                renderDetailsTable: function(data, scanId) {
                    var self = this;
                    var $table = $('#sqmedia-scanner-table');
                    var items = data.items || [];
                    var total = data.total || 0;
                    var page = data.page || 1;
                    var perPage = data.per_page || 25;
                    var totalPages = data.total_pages || 1;

                    if (items.length === 0 && total > 0 && page > 1) {
                        self.currentPage = 1;
                        self.loadDetails(1);
                        return;
                    }

                    self.currentPage = page;

                    var html = '<table class="sqmedia-details-table">';
                    html += '<thead><tr>';
                    html += '<th style="width: 30px;"></th>';
                    html += '<th style="width: 70px;"><?php esc_html_e('ID', 'staticq-media'); ?></th>';
                    html += '<th style="width: 180px;"><?php esc_html_e('Filename', 'staticq-media'); ?></th>';
                    html += '<th><?php esc_html_e('Issues', 'staticq-media'); ?></th>';
                    html += '<th style="width: 70px;"><?php esc_html_e('Actions', 'staticq-media'); ?></th>';
                    html += '</tr></thead><tbody>';

                    if (items.length === 0) {
                        html += '<tr><td colspan="5" style="text-align: center; color: #646970;"><?php esc_html_e('No issues found.', 'staticq-media'); ?></td></tr>';
                    } else {
                        items.forEach(function(item) {
                            html += '<tr data-attachment-id="' + item.attachment_id + '">';
                            html += '<td><button type="button" class="sqmedia-expand-row" data-attachment-id="' + item.attachment_id + '" data-scan-id="' + scanId + '">▶</button></td>';
                            html += '<td class="sqmedia-attachment-id"><a href="' + (item.edit_link || '#') + '" target="_blank">#' + item.attachment_id + '</a></td>';
                            html += '<td class="sqmedia-filename">' + (item.filename || 'Unknown') + '</td>';
                            html += '<td class="sqmedia-issues-cell"><div class="sqmedia-issues-compact">';

                            var issuesByType = {};
                            (item.issues || []).forEach(function(issue) {
                                if (!issuesByType[issue.type]) {
                                    issuesByType[issue.type] = { label: issue.label, css_class: issue.css_class, count: 0 };
                                }
                                issuesByType[issue.type].count++;
                            });

                            Object.keys(issuesByType).forEach(function(type) {
                                var group = issuesByType[type];
                                html += '<span class="sqmedia-issue-badge sqmedia-issue-' + (group.css_class || 'default') + '">';
                                html += group.label;
                                if (group.count > 1) html += '<span class="sqmedia-badge-count">' + group.count + '</span>';
                                html += '</span>';
                            });

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

                            var hasCriticalOnly = issuesByType['critical_missing'] && Object.keys(issuesByType).length === 1;
                            if (hasCriticalOnly) {
                                html += '<td><span class="sqmedia-unfixable" style="color: #999; font-size: 11px;" title="<?php esc_attr_e('Master file missing - cannot be fixed automatically', 'staticq-media'); ?>"><?php esc_html_e('N/A', 'staticq-media'); ?></span></td>';
                            } else {
                                html += '<td><button type="button" class="button button-secondary sqmedia-fix-single-btn" data-attachment-id="' + item.attachment_id + '" style="padding: 4px 10px; font-size: 12px;"><?php esc_html_e('Fix', 'staticq-media'); ?></button></td>';
                            }
                            html += '</tr>';
                        });
                    }

                    html += '</tbody></table>';

                    if (total > perPage) {
                        html += '<div class="sqmedia-pagination" data-total-pages="' + totalPages + '" data-current-page="' + page + '">';
                        html += '<div class="sqmedia-pagination-info">';
                        var start = (page - 1) * perPage + 1;
                        var end = Math.min(page * perPage, total);
                        html += '<?php esc_html_e('Showing', 'staticq-media'); ?> ' + start + '-' + end + ' <?php esc_html_e('of', 'staticq-media'); ?> ' + total + ' <?php esc_html_e('attachments', 'staticq-media'); ?>';
                        html += '</div>';
                        html += '<div class="sqmedia-pagination-buttons">';
                        html += SQMediaHealthCheck.renderPaginationButtons(page, totalPages);
                        html += '</div></div>';
                    }

                    $table.html(html);
                },

                loadFileDetails: function(attachmentId, scanId, $row, $btn) {
                    $.post(ajaxurl, {
                        action: 'sqmedia_get_attachment_file_details',
                        nonce: sqmediaAdmin.nonce,
                        attachment_id: attachmentId,
                        scan_id: scanId
                    }, function(response) {
                        if (response.success && response.data.files) {
                            var html = '<tr class="sqmedia-file-details-row"><td colspan="5">';
                            html += '<div class="sqmedia-file-details">';
                            html += '<table class="sqmedia-file-details-table">';

                            var masterCorrupted = response.data.master_dimensions_corrupted || false;
                            var view = response.data.view || response.data.phase;

                            if (view === 'metadata' || view === 1) {
                                // Metadata view (sizes, dimensions, status)
                                html += '<thead><tr>';
                                html += '<th><?php esc_html_e('Size', 'staticq-media'); ?></th>';
                                html += '<th><?php esc_html_e('Dimensions', 'staticq-media'); ?></th>';
                                html += '<th><?php esc_html_e('Status', 'staticq-media'); ?></th>';
                                html += '</tr></thead>';
                                html += '<tbody>';

                                var webpStarted = false;

                                response.data.files.forEach(function(file) {
                                    var hasIssues = file.issues && file.issues.length > 0;
                                    var rowClass = hasIssues ? 'sqmedia-row-has-issues' : 'sqmedia-row-ok';
                                    var isMaster = (file.size_name === 'master' || file.size_name === 'master-webp');

                                    if (file.is_webp && !webpStarted) {
                                        webpStarted = true;
                                        html += '<tr class="sqmedia-webp-separator"><td colspan="3"><span class="sqmedia-webp-section-label">WebP versions</span></td></tr>';
                                    }
                                    if (file.is_webp) rowClass += ' sqmedia-webp-row';

                                    html += '<tr class="' + rowClass + '">';

                                    // Size name with badge
                                    html += '<td class="sqmedia-file-size-name">';
                                    var badgeClass = file.is_webp ? 'sqmedia-size-badge sqmedia-webp-badge' : 'sqmedia-size-badge';
                                    html += '<span class="' + badgeClass + '">' + (file.display_name || file.size_name) + '</span>';
                                    if (file.is_webp) html += '<span class="sqmedia-webp-ext">.webp</span>';
                                    if (!file.in_metadata && file.in_theme) html += ' <span class="sqmedia-missing-badge"><?php esc_html_e('missing', 'staticq-media'); ?></span>';
                                    else if (file.in_metadata && !file.in_theme) html += ' <span class="sqmedia-deprecated-badge"><?php esc_html_e('deprecated', 'staticq-media'); ?></span>';
                                    else if (file.is_preserved) html += ' <span class="sqmedia-custom-badge"><?php esc_html_e('custom', 'staticq-media'); ?></span>';
                                    html += '</td>';

                                    // Dimensions
                                    html += '<td class="sqmedia-file-dimensions">';
                                    if (file.width && file.height) html += '<span class="sqmedia-dimensions">' + file.width + '×' + file.height + '</span>';
                                    else if (file.expected_width && file.expected_height) html += '<span class="sqmedia-dimensions sqmedia-expected">' + file.expected_width + '×' + file.expected_height + '</span> <span class="sqmedia-to-create"><?php esc_html_e('(to create)', 'staticq-media'); ?></span>';
                                    else html += '<span class="sqmedia-no-dimensions">—</span>';
                                    html += '</td>';

                                    // Status
                                    html += '<td class="sqmedia-file-status">';
                                    if (!hasIssues) {
                                        if (masterCorrupted && !isMaster) {
                                            html += '<span class="sqmedia-status-ok sqmedia-status-unverified">✓ <?php esc_html_e('OK', 'staticq-media'); ?></span>';
                                            html += '<span class="sqmedia-unverified-note"><?php esc_html_e('(unverified - fix master first)', 'staticq-media'); ?></span>';
                                        } else {
                                            html += '<span class="sqmedia-status-ok">✓ <?php esc_html_e('OK', 'staticq-media'); ?></span>';
                                        }
                                    } else {
                                        file.issues.forEach(function(issue) {
                                            var issueType = issue.type || issue;
                                            var details = issue.details || {};
                                            html += '<span class="sqmedia-status-issue">';
                                            if (issueType === 'wrong_dimensions') {
                                                html += '⚠️ ' + (details.current_width || '?') + '×' + (details.current_height || '?') + ' <span class="sqmedia-arrow">→</span> ' + (details.expected_width || '?') + '×' + (details.expected_height || '?');
                                            } else if (issueType === 'missing_sizes') {
                                                html += '➔ <?php esc_html_e('Add to metadata', 'staticq-media'); ?>';
                                            } else if (issueType === 'deprecated_sizes') {
                                                html += '🔘️ <?php esc_html_e('Remove from metadata', 'staticq-media'); ?>';
                                            } else if (issueType === 'corrupted') {
                                                html += '🔴 ';
                                                var reason = details.reason || 'unknown';
                                                var reasons = {
                                                    'invalid_dimensions': '<?php esc_html_e('Invalid dimensions (width/height = 0)', 'staticq-media'); ?>',
                                                    'invalid_filesize': '<?php esc_html_e('Invalid filesize (= 0)', 'staticq-media'); ?>',
                                                    'missing_file_path': '<?php esc_html_e('Missing file path', 'staticq-media'); ?>',
                                                    'file_path_mismatch': '<?php esc_html_e('File path mismatch', 'staticq-media'); ?>',
                                                    'invalid_file_path': '<?php esc_html_e('Invalid file path', 'staticq-media'); ?>',
                                                    'no_metadata': '<?php esc_html_e('No metadata', 'staticq-media'); ?>'
                                                };
                                                html += reasons[reason] || '<?php esc_html_e('Corrupted', 'staticq-media'); ?>';
                                            } else if (issueType === 'missing_webp') {
                                                html += '📼 <?php esc_html_e('Create WebP', 'staticq-media'); ?>';
                                            } else if (issueType === 'critical_missing') {
                                                html += '🔴 <?php esc_html_e('Master file missing — cannot recover', 'staticq-media'); ?>';
                                            } else if (issueType === 'post_content_ref') {
                                                html += '🔗 <?php esc_html_e('Remove from post content', 'staticq-media'); ?>';
                                            } else if (issueType === 'post_content_add') {
                                                html += '🔗 <?php esc_html_e('Add to post content', 'staticq-media'); ?>';
                                            } else if (issueType === 'post_content_update') {
                                                html += '🔗 <?php esc_html_e('Update in post content', 'staticq-media'); ?>';
                                            } else {
                                                html += '⚠️ ' + issueType;
                                            }
                                            html += '</span> ';
                                        });
                                    }
                                    html += '</td>';
                                    html += '</tr>';
                                });

                            } else {
                                // File location view (file, size, location, issues)
                                html += '<thead><tr>';
                                html += '<th><?php esc_html_e('File', 'staticq-media'); ?></th>';
                                html += '<th><?php esc_html_e('Size', 'staticq-media'); ?></th>';
                                html += '<th><?php esc_html_e('Location', 'staticq-media'); ?></th>';
                                html += '<th><?php esc_html_e('Issues', 'staticq-media'); ?></th>';
                                html += '</tr></thead>';
                                html += '<tbody>';

                                response.data.files.forEach(function(file) {
                                    html += '<tr>';
                                    html += '<td class="sqmedia-file-name">' + file.file + '</td>';
                                    html += '<td class="sqmedia-file-size-name">' + (file.size_name || 'master') + '</td>';
                                    html += '<td class="sqmedia-file-location">';
                                    html += file.local
                                        ? '<span class="sqmedia-loc-local">✓ Local</span>'
                                        : '<span class="sqmedia-loc-missing">✗ Local</span>';
                                    html += ' ';
                                    html += file.bucket
                                        ? '<span class="sqmedia-loc-bucket">✓ Bucket</span>'
                                        : '<span class="sqmedia-loc-missing">✗ Bucket</span>';
                                    html += '</td>';
                                    html += '<td class="sqmedia-file-issues">';
                                    (file.issues || []).forEach(function(issue) {
                                        html += '<span class="sqmedia-issue-tag">' + issue + '</span> ';
                                    });
                                    html += '</td>';
                                    html += '</tr>';
                                });
                            }

                            html += '</tbody></table>';
                            html += '</div></td></tr>';

                            $row.after(html);
                            $btn.text('▼');
                        } else {
                            $btn.text('▶');
                        }
                    }).fail(function() {
                        $btn.text('▶');
                    });
                }
            };

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

        })(jQuery);
        <?php
        $inline_script = ob_get_clean();
        wp_add_inline_script('sqmedia-admin', $inline_script);
    }
}
