/**
 * Pro Media Manager - Admin JavaScript
 *
 * @package PackshotPhotoAI
 */

(function () {
    'use strict';

    function init() {
        initInlineEditing();
        initAIGeneration();
        initRevertAIMetadata();
        initConvertModal();
        initResizeFeature();
        initImageComparison();
        initBulkActions(); // New Feature: Sequential Bulk
        initSettingsPage();
        initBannerDismissal();
        initToastContainer();
        window.pmmBulkProgress = new BulkProgressManager();
        pollQueueStatus();
        pollProcessingRows();
        initDeactivationSurvey();
        updateLogNotification();
        initEuAiAct();
    }

    function cleanUrlBulkParams() {
        if (window.history && window.history.replaceState) {
            try {
                const url = new URL(window.location.href);
                if (url.searchParams.has('packshotphoto_bulk_queued') || url.searchParams.has('packshotphoto_bulk_count')) {
                    url.searchParams.delete('packshotphoto_bulk_queued');
                    url.searchParams.delete('packshotphoto_bulk_count');
                    window.history.replaceState({}, document.title, url.pathname + (url.search ? url.search : ''));
                }
            } catch (e) {}
        }
    }

    function pollQueueStatus() {
        const notice = document.querySelector('.packshotphoto-queue-notice');
        if (!notice) {
            cleanUrlBulkParams();
            return;
        }

        const statusSpan = notice.querySelector('.packshotphoto-queue-live-status');
        
        const check = async () => {
            try {
                const response = await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'packshotphoto_get_queue_status',
                        nonce: packshotphotoConfig.nonce
                    })
                });
                
                const data = await response.json();
                if (data.success && data.data) {
                    const q = data.data;
                    
                    if (q.status === 'processing') {
                        const percent = Math.round((q.processed / q.total) * 100);
                        statusSpan.textContent = ` (${packshotphotoConfig.i18n.progress || 'Progress'}: ${q.processed}/${q.total} - ${percent}%)`;
                        
                        // If it's a fresh redirect, show the big progress bar too
                        if (!window.pmmBulkProgress.overlay.classList.contains('active')) {
                            window.pmmBulkProgress.show(q.total, packshotphotoConfig.i18n.processingInBackground || 'Processing in background', packshotphotoConfig.i18n.completingTasks || 'Completing batch tasks...');
                        }
                        window.pmmBulkProgress.update(q.processed - q.errors, q.errors, q.total - q.processed);
                        
                        setTimeout(check, 3000);
                    } else if (q.status === 'completed') {
                        cleanUrlBulkParams();
                        statusSpan.textContent = ' — ' + (packshotphotoConfig.i18n.done || 'Done!');
                        notice.classList.remove('notice-info');
                        notice.classList.add('notice-success');
                        
                        window.pmmBulkProgress.update(q.processed - q.errors, q.errors, 0);
                        setTimeout(() => {
                            window.pmmBulkProgress.hide();
                        }, 3000);
                    } else {
                        // Idle
                        cleanUrlBulkParams();
                        window.pmmBulkProgress.hide();
                    }
                }
            } catch (err) {
                console.error('Queue poll error', err);
            }
        };

        check();
    }

    function pollProcessingRows() {
        const findLoadingRows = () => {
            const rows = new Set();
            document.querySelectorAll('.packshotphoto-processing-badge').forEach(el => {
                const row = el.closest('tr');
                if (row) {
                    rows.add(row);
                }
            });
            return Array.from(rows);
        };

        const activePolls = new Set();

        const pollRow = async (row) => {
            const idInput = row.querySelector('[data-id]');
            let id = idInput ? idInput.dataset.id : null;
            if (!id && row.id && row.id.startsWith('post-')) {
                id = row.id.replace('post-', '');
            }
            if (!id) return;
            
            if (activePolls.has(id)) return;
            activePolls.add(id);

            const checkStatus = async () => {
                try {
                    const response = await fetch(packshotphotoConfig.ajaxUrl, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                        body: new URLSearchParams({
                            action: 'packshotphoto_check_item_status',
                            id: id,
                            nonce: packshotphotoConfig.nonce
                        })
                    });
                    
                    const data = await response.json();
                    if (data.success && data.data) {
                        const status = data.data;
                        if (status.processing) {
                            setTimeout(checkStatus, 3000);
                        } else {
                            // Finished! Update row.
                            
                            // Check if filename changed (extension or name)
                            const filenameInput = row.querySelector('.packshotphoto-filename-input');
                            const oldFilename = filenameInput ? filenameInput.value : '';
                            const hasFileChange = oldFilename && status.filename && (oldFilename.toLowerCase() !== status.filename.toLowerCase());
                            
                            if (hasFileChange && filenameInput) {
                                filenameInput.value = status.filename;
                                filenameInput.dataset.lastValue = status.filename;
                            }

                            // Refresh row thumbnails in-place with new filename and cache busting
                            row.querySelectorAll('.column-primary img, .media-icon img, .thumbnail img').forEach(img => {
                                if (img) {
                                    img.removeAttribute('srcset');
                                    const newSrc = status.thumb_url || (img.src ? img.src.split('?')[0] : '');
                                    if (newSrc) {
                                        img.src = newSrc + (newSrc.includes('?') ? '&' : '?') + 'v=' + Date.now();
                                    }
                                }
                            });

                            // 1. Remove loading class
                            row.querySelectorAll('.packshotphoto-loading').forEach(w => {
                                w.classList.remove('packshotphoto-loading');
                            });
                            
                            // 2. Enable inputs
                            row.querySelectorAll('.packshotphoto-editable').forEach(input => {
                                input.removeAttribute('disabled');
                            });

                            // 3. Update field values
                            const fields = {
                                alt: status.alt,
                                caption: status.caption,
                                description: status.desc,
                                filename: status.filename
                            };
                            
                            for (const [field, val] of Object.entries(fields)) {
                                const input = row.querySelector(`[data-field="${field}"]`);
                                if (input) {
                                    input.value = val;
                                    input.dataset.lastValue = val;
                                    input.classList.add('packshotphoto-flash');
                                    setTimeout(() => input.classList.remove('packshotphoto-flash'), 1000);
                                }
                            }

                            // 4. Rebuild the action buttons in tools column
                            const toolsWrapper = row.querySelector('.packshotphoto-tools-actions');
                            if (toolsWrapper) {
                                toolsWrapper.innerHTML = '';
                                const rowNonce = status.edit_nonce || packshotphotoConfig.nonce;
                                
                                // Generate button
                                const genBtn = document.createElement('button');
                                genBtn.type = 'button';
                                genBtn.className = 'button button-small packshotphoto-ai-btn';
                                genBtn.dataset.id = id;
                                genBtn.dataset.nonce = rowNonce;
                                genBtn.dataset.language = row.dataset.language || '';
                                genBtn.innerHTML = `<span class="packshotphoto-ai-text">${packshotphotoConfig.i18n.generate || 'Generate'}</span>`;
                                toolsWrapper.appendChild(genBtn);

                                // Convert button
                                const isWebP = status.mime_type === 'image/webp';
                                const isAvif = status.mime_type === 'image/avif';
                                const isConvertible = status.mime_type && ['image/jpeg', 'image/png', 'image/gif'].includes(status.mime_type);
                                if (isWebP || isAvif || isConvertible) {
                                    const convBtn = document.createElement('button');
                                    convBtn.type = 'button';
                                    convBtn.className = 'button button-small packshotphoto-convert-btn';
                                    convBtn.dataset.id = id;
                                    convBtn.dataset.nonce = rowNonce;
                                    convBtn.dataset.filesize = '0';
                                    convBtn.dataset.target_format = isWebP ? 'avif' : (isAvif ? 'webp' : '');
                                    convBtn.innerHTML = `<span class="packshotphoto-btn-text">${packshotphotoConfig.i18n.convertBtn || 'Convert'}</span>`;
                                    toolsWrapper.appendChild(convBtn);
                                }

                                // Resize button
                                const resizeBtn = document.createElement('button');
                                resizeBtn.type = 'button';
                                resizeBtn.className = 'button button-small packshotphoto-manual-resize-trigger';
                                resizeBtn.dataset.id = id;
                                resizeBtn.dataset.nonce = rowNonce;
                                resizeBtn.innerHTML = `<span class="packshotphoto-btn-text">${packshotphotoConfig.i18n.resizeBtn || 'Resize'}</span>`;
                                toolsWrapper.appendChild(resizeBtn);

                                // EU AI Act button
                                const euAiBtn = document.createElement('button');
                                euAiBtn.type = 'button';
                                euAiBtn.className = 'button button-small packshotphoto-eu-ai-btn';
                                euAiBtn.dataset.id = id;
                                euAiBtn.dataset.nonce = rowNonce;
                                euAiBtn.style.borderColor = '#3b82f6';
                                euAiBtn.style.color = '#2563eb';
                                euAiBtn.innerHTML = `<span class="packshotphoto-btn-text">🇪🇺 ${packshotphotoConfig.i18n.labelAi || 'Label AI'}</span>`;
                                toolsWrapper.appendChild(euAiBtn);

                                // Restore button
                                if (status.show_restore) {
                                    const restoreBtn = document.createElement('button');
                                    restoreBtn.type = 'button';
                                    restoreBtn.className = 'button button-small packshotphoto-restore-btn';
                                    restoreBtn.dataset.id = id;
                                    restoreBtn.dataset.nonce = rowNonce;
                                    restoreBtn.dataset.hasAiBackup = '1';
                                    restoreBtn.dataset.hasFileBackup = '1';
                                    restoreBtn.dataset.hasOriginalFilename = '1';
                                    restoreBtn.innerHTML = `<span class="packshotphoto-btn-text">${packshotphotoConfig.i18n.restore || 'Restore'}</span>`;
                                    toolsWrapper.appendChild(restoreBtn);
                                }
                            }

                            activePolls.delete(id);
                        }
                    } else {
                        activePolls.delete(id);
                    }
                } catch (err) {
                    console.error('Row poll error', err);
                    activePolls.delete(id);
                }
            };

            checkStatus();
        };

        const checkAll = () => {
            const loadingRows = findLoadingRows();
            loadingRows.forEach(row => {
                pollRow(row);
            });
        };

        setInterval(checkAll, 4000);
        checkAll();
    }

    // ===== TOAST NOTIFICATIONS =====

    let toastContainer = null;

    function initToastContainer() {
        toastContainer = document.createElement('div');
        toastContainer.className = 'packshotphoto-toast-container';
        document.body.appendChild(toastContainer);
    }

    function showToast(message, type = 'info') {
        const toast = document.createElement('div');
        toast.className = `packshotphoto-toast packshotphoto-toast-${type}`;
        toast.textContent = message;

        toastContainer.appendChild(toast);

        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(100%)';
            setTimeout(() => toast.remove(), 300);
        }, 3000);
    }

    function getErrorMessage(data) {
        if (!data) return packshotphotoConfig.i18n.error || 'Error';
        if (typeof data === 'string') return data;
        if (data.data) {
            if (typeof data.data === 'string') return data.data;
            if (data.data.message) return data.data.message;
        }
        if (data.message) return data.message;
        return packshotphotoConfig.i18n.error || 'Error';
    }

    // ===== INLINE EDITING =====

    function initInlineEditing() {
        // Debounce timer
        let saveTimers = new Map();

        document.addEventListener('input', function (e) {
            if (!e.target.classList.contains('packshotphoto-editable')) return;
            // Skip filename input here, handled separately
            if (e.target.classList.contains('packshotphoto-filename-input')) return;

            const textarea = e.target;
            const wrapper = textarea.closest('.packshotphoto-cell-wrapper');

            // Clear existing timer
            const timerId = saveTimers.get(textarea);
            if (timerId) clearTimeout(timerId);

            // Set new timer (debounce 800ms)
            saveTimers.set(textarea, setTimeout(() => {
                saveField(textarea, wrapper);
            }, 800));
        });

        // Also save on blur immediately
        document.addEventListener('blur', function (e) {
            if (!e.target.classList.contains('packshotphoto-editable')) return;
            if (e.target.classList.contains('packshotphoto-filename-input')) return;

            const textarea = e.target;
            const wrapper = textarea.closest('.packshotphoto-cell-wrapper');

            // Clear any pending save
            const timerId = saveTimers.get(textarea);
            if (timerId) {
                clearTimeout(timerId);
                saveTimers.delete(textarea);
            }

            saveField(textarea, wrapper);
        }, true);

        // Filename field - input with debounce
        let filenameTimer = null;
        document.addEventListener('input', function (e) {
            if (!e.target.classList.contains('packshotphoto-filename-input')) return;

            if (filenameTimer) clearTimeout(filenameTimer);
            filenameTimer = setTimeout(() => {
                saveFilenameField(e.target);
            }, 1000);
        });

        // Filename field - save on blur immediately  
        document.addEventListener('blur', function (e) {
            if (!e.target.classList.contains('packshotphoto-filename-input')) return;

            if (filenameTimer) {
                clearTimeout(filenameTimer);
                filenameTimer = null;
            }
            saveFilenameField(e.target);
        }, true);
    }

    function saveField(textarea, wrapper) {
        const id = textarea.dataset.id;
        const field = textarea.dataset.field;
        const nonce = textarea.dataset.nonce;
        const value = textarea.value;

        // Skip if unchanged
        if (textarea.dataset.lastValue === value) return;
        textarea.dataset.lastValue = value;

        // Show saving state
        if (wrapper) {
            wrapper.classList.remove('packshotphoto-saved', 'packshotphoto-error');
            wrapper.classList.add('packshotphoto-saving');
            const indicator = wrapper.querySelector('.packshotphoto-save-indicator');
            if (indicator) indicator.textContent = packshotphotoConfig.i18n.saving;
        }

        fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_save_field',
                id: id,
                field: field,
                value: value,
                nonce: nonce,
            }),
        })
            .then(response => response.json())
            .then(data => {
                if (wrapper) {
                    wrapper.classList.remove('packshotphoto-saving');
                }

                if (data.success) {
                    showToast(data.data.message || packshotphotoConfig.i18n.saved, 'success');
                } else {
                    if (wrapper) {
                        wrapper.classList.add('packshotphoto-error');
                        const indicator = wrapper.querySelector('.packshotphoto-save-indicator');
                        if (indicator) indicator.textContent = packshotphotoConfig.i18n.error;
                    }
                    showToast(data.data.message || packshotphotoConfig.i18n.error, 'error');
                }
            })
            .catch(error => {
                if (wrapper) {
                    wrapper.classList.remove('packshotphoto-saving');
                    wrapper.classList.add('packshotphoto-error');
                }
                showToast(packshotphotoConfig.i18n.error, 'error');
            });
    }

    function saveFilenameField(input) {
        const id = input.dataset.id;
        const nonce = input.dataset.nonce;
        const value = input.value.trim();
        const wrapper = input.closest('.packshotphoto-filename-wrapper');
        const indicator = wrapper ? wrapper.querySelector('.packshotphoto-save-indicator') : null;

        // Skip if unchanged
        if (input.dataset.lastValue === value) return;

        // Check if this is a significant change from original name
        const originalName = input.dataset.originalName || '';
        if (originalName && value !== originalName && !input.dataset.warned) {
            modalManager.confirm({
                title: packshotphotoConfig.i18n.renameWarningTitle || 'Warning: URL Change',
                icon: '⚠️',
                message: `<p>${packshotphotoConfig.i18n.renameWarningDesc || 'Changing the file name of published media may break existing links (404 errors) if not updated on the site.'}</p>
                          <p><strong>${packshotphotoConfig.i18n.renameOldPrefix || 'Old:'}</strong> ${escHtml(originalName)}<br>
                          <strong>${packshotphotoConfig.i18n.renameNewPrefix || 'New:'}</strong> ${escHtml(value)}</p>
                          <label class="packshotphoto-field-check" style="margin-top: 10px;">
                              <input type="checkbox" id="packshotphoto-slug-only-check" checked>
                              <strong>${packshotphotoConfig.i18n.renameSlugOnly || 'Update Title & Slug ONLY (preserves file URL)'}</strong>
                          </label>`,
                buttons: [
                    { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                    { label: packshotphotoConfig.i18n.apply || 'Apply', value: 'apply', class: 'packshotphoto-btn-primary' }
                ]
            }).then(result => {
                if (result.value !== 'apply') {
                    input.value = originalName;
                    input.dataset.lastValue = originalName;
                    return;
                }

                input.dataset.warned = 'true';
                const slugOnlyCb = document.getElementById('packshotphoto-slug-only-check');
                if (slugOnlyCb && slugOnlyCb.checked) {
                    input.dataset.slugOnly = 'true';
                } else {
                    input.dataset.slugOnly = 'false';
                }
                
                // Call again after warning
                saveFilenameField(input);
            });
            return;
        }

        input.dataset.lastValue = value;

        // Show saving state
        if (wrapper) {
            wrapper.classList.remove('packshotphoto-saved', 'packshotphoto-error');
            wrapper.classList.add('packshotphoto-saving');
        }
        if (indicator) {
            indicator.textContent = packshotphotoConfig.i18n.saving || 'Saving...';
        }

        fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_save_field',
                id: id,
                field: 'filename', // NEW FIELD NAME
                value: value,
                nonce: nonce,
                slug_only: input.dataset.slugOnly === 'true' ? '1' : '0'
            }),
        })
            .then(response => response.json())
            .then(data => {
                if (wrapper) {
                    wrapper.classList.remove('packshotphoto-saving');
                }

                if (data.success) {
                    if (indicator) {
                        indicator.textContent = packshotphotoConfig.i18n.saved || 'Renamed!';
                    }
                    showToast(data.data.message || (packshotphotoConfig.i18n.saved || 'Renamed!'), 'success');
                    setTimeout(() => {
                        if (wrapper) {
                            wrapper.classList.remove('packshotphoto-saved');
                        }
                    }, 2000);
                } else {
                    console.error('PackshotPhoto AI Rename error:', data);
                    if (wrapper) {
                        wrapper.classList.add('packshotphoto-error');
                    }
                    if (indicator) {
                        indicator.textContent = packshotphotoConfig.i18n.error + ': ' + (data.data.message || 'Unknown');
                    }
                    showToast('Rename error: ' + (data.data.message || 'Unknown'), 'error');
                }
            })
            .catch(error => {
                console.error('PackshotPhoto AI Rename network error:', error);
                if (wrapper) {
                    wrapper.classList.remove('packshotphoto-saving');
                    wrapper.classList.add('packshotphoto-error');
                }
                if (indicator) {
                    indicator.textContent = 'Network error';
                }
                showToast(packshotphotoConfig.i18n.error || 'Network error', 'error');
            });
    }

    // ===== MODAL MANAGER =====

    class ModalManager {
        constructor() {
            this.overlay = null;
            this.resolvePromise = null;
            this.init();
        }

        init() {
            // Create DOM elements
            this.overlay = document.createElement('div');
            this.overlay.className = 'packshotphoto-modal-overlay';
            this.overlay.innerHTML = `
                <div class="packshotphoto-modal">
                    <div class="packshotphoto-modal-header">
                        <h3 class="packshotphoto-modal-title"></h3>
                        <button type="button" class="packshotphoto-btn packshotphoto-btn-secondary packshotphoto-modal-close" style="padding: 4px 8px;">✕</button>
                    </div>
                    <div class="packshotphoto-modal-body"></div>
                    <div class="packshotphoto-modal-actions"></div>
                </div>
            `;
            document.body.appendChild(this.overlay);

            // Bind events
            this.overlay.addEventListener('click', (e) => {
                if (e.target === this.overlay) this.close(null);
            });
            this.overlay.addEventListener('click', (e) => {
                if (e.target.closest('.packshotphoto-modal-close')) this.close(null);
            });
        }

        /**
         * Show a custom confirmation modal
         * @param {Object} options
         */
        confirm(options) {
            return new Promise((resolve) => {
                this.resolvePromise = resolve;

                const titleEl = this.overlay.querySelector('.packshotphoto-modal-title');
                const bodyEl = this.overlay.querySelector('.packshotphoto-modal-body');
                const actionsEl = this.overlay.querySelector('.packshotphoto-modal-actions');

                titleEl.textContent = options.title || 'Confirm';
                titleEl.innerHTML = (options.icon || '⚠️') + ' ' + titleEl.textContent;
                bodyEl.innerHTML = options.message || '';

                if (options.input) {
                    const inputHtml = `
                        <div class="packshotphoto-modal-input-wrapper" style="margin-top:15px; margin-bottom:5px;">
                            <label style="display:block; margin-bottom:5px; font-weight:600; font-size:13px;">${options.input.label}</label>
                            <input type="${options.input.type || 'text'}" 
                                   class="packshotphoto-input-field" 
                                   value="${options.input.value || ''}" 
                                   style="width:100%; padding:8px; border:1px solid #ccc; border-radius:4px; font-size:14px;">
                        </div>
                    `;
                    bodyEl.insertAdjacentHTML('beforeend', inputHtml);
                }

                actionsEl.innerHTML = '';

                if (options.buttons) {
                    options.buttons.forEach(btn => {
                        const button = document.createElement('button');
                        button.className = `packshotphoto-btn ${btn.class || 'packshotphoto-btn-secondary'}`;
                        button.textContent = btn.label;
                        button.onclick = () => this.close(btn.value);
                        actionsEl.appendChild(button);
                    });
                } else {
                    const cancel = document.createElement('button');
cancel.className = 'packshotphoto-btn packshotphoto-btn-secondary';
                    cancel.textContent = packshotphotoConfig.i18n.cancel || 'Cancel';
                    
                    const ok = document.createElement('button');
                    ok.className = 'packshotphoto-btn packshotphoto-btn-primary';
                    ok.textContent = packshotphotoConfig.i18n.ok || 'OK';
                    ok.onclick = () => this.close('ok');

                    actionsEl.appendChild(cancel);
                    actionsEl.appendChild(ok);
                }

                this.overlay.classList.add('active');

                if (options.input) {
                    setTimeout(() => {
                        const input = this.overlay.querySelector('.packshotphoto-input-field');
                        if (input) {
                            input.focus();
                            input.select();
                        }
                    }, 100);
                }

                setTimeout(() => initComparisonSlider(), 50);
            });
        }

        alert(options) {
            return this.confirm(options);
        }

        close(value) {
            this.overlay.classList.remove('active');

            const input = this.overlay.querySelector('.packshotphoto-input-field');
            const inputValue = input ? input.value : null;

            if (this.resolvePromise) {
                this.resolvePromise({ value, inputValue });
                this.resolvePromise = null;
            }
        }
    }

    const modalManager = new ModalManager();

    // ===== BULK PROGRESS MANAGER =====

    class BulkProgressManager {
        constructor() {
            this.total = 0;
            this.success = 0;
            this.error = 0;
            this.init();
        }

        init() {
            const overlay = document.createElement('div');
            overlay.className = 'packshotphoto-bulk-progress-overlay';
            overlay.innerHTML = `
                <div class="packshotphoto-bulk-progress-card">
                    <div class="packshotphoto-bulk-progress-title">${packshotphotoConfig.i18n.processingAI || 'Processing AI'}</div>
                    <div class="packshotphoto-bulk-progress-subtitle">${packshotphotoConfig.i18n.optimizingLibrary || 'Optimizing media library...'}</div>
                    <div class="packshotphoto-progress-track">
                        <div class="packshotphoto-progress-fill"></div>
                    </div>
                    <div class="packshotphoto-bulk-stats">
                        <div class="packshotphoto-stat-success">
                            <span>${packshotphotoConfig.i18n.success || 'Success'}</span>
                            <strong id="packshotphoto-bulk-success">0</strong>
                        </div>
                        <div class="packshotphoto-stat-error">
                            <span>${packshotphotoConfig.i18n.errors || 'Errors'}</span>
                            <strong id="packshotphoto-bulk-error">0</strong>
                        </div>
                        <div class="packshotphoto-stat-remaining">
                            <span>${packshotphotoConfig.i18n.remaining || 'Remaining'}</span>
                            <strong id="packshotphoto-bulk-remaining">0</strong>
                        </div>
                    </div>
                </div>
            `;
            document.body.appendChild(overlay);
            this.overlay = overlay;
            this.titleEl = overlay.querySelector('.packshotphoto-bulk-progress-title');
            this.subTitleEl = overlay.querySelector('.packshotphoto-bulk-progress-subtitle');
            this.fill = overlay.querySelector('.packshotphoto-progress-fill');
            this.successEl = overlay.querySelector('#packshotphoto-bulk-success');
            this.errorEl = overlay.querySelector('#packshotphoto-bulk-error');
            this.remainEl = overlay.querySelector('#packshotphoto-bulk-remaining');
        }

        setTitle(title, subtitle) {
            if (title) this.titleEl.textContent = title;
            if (subtitle) this.subTitleEl.textContent = subtitle;
        }

        show(total, title = null, subtitle = null) {
            if (this.overlay.classList.contains('active')) {
                // Already running, add to total
                this.total += total;
                if (title) this.setTitle(title, packshotphotoConfig.i18n.additionalTasks || 'Additional tasks added...');
            } else {
                this.total = total;
                this.success = 0;
                this.error = 0;
                if (title) this.setTitle(title, subtitle);
                this.update(0, 0, total);
            }
            this.overlay.classList.add('active');
        }

        update(success, error, remaining) {
            // we use the counters provided by the caller or keep our own
            // For standardization, let's keep internal track of incrementals
            
            const processed = success + error;
            
            // Adjust total if needed
            this.total = Math.max(this.total, processed + remaining);
            
            const percent = this.total > 0 ? (processed / this.total) * 100 : 0;
            
            this.fill.style.width = `${percent}%`;
            this.successEl.textContent = success;
            this.errorEl.textContent = error;
            this.remainEl.textContent = remaining;

            if (remaining === 0 && processed > 0) {
                // If this was part of something bigger, we might not want to hide yet,
                // but usually the caller provides the correct 'remaining' across all their items.
                setTimeout(() => {
                    if (this.remainEl.textContent === '0') {
                        this.hide();
                    }
                }, 2000);
            }
        }

        hide() {
            this.overlay.classList.remove('active');
        }
    }


    // ===== AI GENERATION (Queue System) =====

    const aiQueue = [];
    let isProcessingQueue = false;
    let isBulkAI = false;

    function initAIGeneration() {
        document.addEventListener('click', function (e) {
            const btn = e.target.closest('.packshotphoto-ai-btn');
            if (!btn) return;

            e.preventDefault();
            addToQueue(btn);
        });
    }

    // Revert AI metadata button
    function initRevertAIMetadata() {
        document.addEventListener('click', async function (e) {
            const btn = e.target.closest('.packshotphoto-restore-btn');
            if (!btn) return;

            e.preventDefault();

            const id = btn.dataset.id;
            const nonce = btn.dataset.nonce;
            const row = btn.closest('tr');

            btn.classList.add('packshotphoto-loading');
            btn.querySelector('.packshotphoto-btn-text').textContent = '...';

            let options;
            try {
                const resp = await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({ action: 'packshotphoto_get_restore_options', id, nonce })
                });
                const data = await resp.json();
                btn.classList.remove('packshotphoto-loading');
                btn.querySelector('.packshotphoto-btn-text').textContent = packshotphotoConfig.i18n.restore || 'Restore';
                if (!data.success) {
                    showToast(data.data?.message || packshotphotoConfig.i18n.error, 'error');
                    return;
                }
                options = data.data;
            } catch (err) {
                btn.classList.remove('packshotphoto-loading');
                btn.querySelector('.packshotphoto-btn-text').textContent = packshotphotoConfig.i18n.restore || 'Restore';
                showToast(packshotphotoConfig.i18n.error, 'error');
                return;
            }

            const o = options;
            const bVal = o.backup_values || {};
            const cVal = o.current_values || {};
            const fieldOptionsHtml = [];
            const backupVersions = o.backup_versions || [];

            if (o.has_ai_backup && backupVersions.length > 1) {
                fieldOptionsHtml.push(`<div class="packshotphoto-version-selector" style="margin-bottom:8px;color:#666;font-size:11px;">
                    ${backupVersions.length} ${packshotphotoConfig.i18n.versionsAvailable || 'versions available'}
                </div>`);
            }

            if (o.has_ai_backup) {
                const fields = [
                    { key: 'alt', label: packshotphotoConfig.i18n.altText || 'Alt Text' },
                    { key: 'caption', label: packshotphotoConfig.i18n.captionLabel || 'Caption' },
                    { key: 'description', label: packshotphotoConfig.i18n.descriptionLabel || 'Description' },
                ];
                fields.forEach(f => {
                    const prev = bVal[f.key] || '';
                    const curr = cVal[f.key] || '';
                    const prevShort = prev.length > 30 ? prev.substring(0, 30) + '…' : prev;
                    const currShort = curr.length > 30 ? curr.substring(0, 30) + '…' : curr;
                    const prevDisplay = escHtml(prevShort || '(' + (packshotphotoConfig.i18n.empty || 'empty') + ')');
                    const currDisplay = escHtml(currShort || '(' + (packshotphotoConfig.i18n.empty || 'empty') + ')');
                    fieldOptionsHtml.push(`<label class="packshotphoto-field-check packshotphoto-field-check-compact">
                        <input type="checkbox" class="packshotphoto-restore-checkbox" data-field="${f.key}" checked>
                        <span class="packshotphoto-field-label">${f.label}</span>
                        <span class="packshotphoto-field-diff"><span class="packshotphoto-diff-old">${currDisplay}</span> <span class="packshotphoto-diff-arrow">→</span> <span class="packshotphoto-diff-new">${prevDisplay}</span></span>
                    </label>`);
                });
            }

            if (o.has_original_filename) {
                const prevF = bVal.filename || '';
                const currF = cVal.filename || '';
                const prevShort = prevF.length > 30 ? prevF.substring(0, 30) + '…' : prevF;
                const currShort = currF.length > 30 ? currF.substring(0, 30) + '…' : currF;
                fieldOptionsHtml.push(`<label class="packshotphoto-field-check packshotphoto-field-check-compact">
                    <input type="checkbox" class="packshotphoto-restore-checkbox" data-field="filename" checked>
                    <span class="packshotphoto-field-label">${packshotphotoConfig.i18n.filenameLabel || 'Filename'}</span>
                    <span class="packshotphoto-field-diff"><span class="packshotphoto-diff-old">${escHtml(currShort)}</span> <span class="packshotphoto-diff-arrow">→</span> <span class="packshotphoto-diff-new">${escHtml(prevShort)}</span></span>
                </label>`);
            }

            if (o.has_file_backup && o.comparison) {
                const c = o.comparison;
                const savingsColor = c.savings > 0 ? '#00a32a' : '#d63638';
                const savingsText = c.savings > 0 ? `${c.savings}% ${packshotphotoConfig.i18n.smaller || 'smaller'}` : `${Math.abs(c.savings)}% ${packshotphotoConfig.i18n.larger || 'larger'}`;
                fieldOptionsHtml.push(`<label class="packshotphoto-field-check packshotphoto-field-check-compact">
                    <input type="checkbox" class="packshotphoto-restore-checkbox" data-field="restore_file" checked>
                    <span class="packshotphoto-field-label">${packshotphotoConfig.i18n.restoreOriginalFile || 'Restore original file (format + size)'}</span>
                    <span class="packshotphoto-field-diff"><span class="packshotphoto-diff-old">${escHtml(c.before_format)} ${escHtml(c.before_size)}</span> <span class="packshotphoto-diff-arrow">→</span> <span class="packshotphoto-diff-new">${escHtml(c.after_format)} ${escHtml(c.after_size)}</span> <span style="color:${savingsColor};font-weight:600;font-size:11px;">${savingsText}</span></span>
                </label>`);
            }

            // "Restore original size only" — resize to backup dimensions, keep current format
            if (o.has_size_restore && o.has_file_backup && o.comparison && o.comparison.format_changed) {
                const c = o.comparison;
                fieldOptionsHtml.push(`<label class="packshotphoto-field-check packshotphoto-field-check-compact">
                    <input type="checkbox" class="packshotphoto-restore-checkbox" data-field="restore_size_only">
                    <span class="packshotphoto-field-label">${packshotphotoConfig.i18n.restoreOriginalSize || 'Restore original size only (keep current format)'}</span>
                    <span class="packshotphoto-field-diff"><span class="packshotphoto-diff-old">${c.current_width}×${c.current_height}</span> <span class="packshotphoto-diff-arrow">→</span> <span class="packshotphoto-diff-new">${c.backup_width}×${c.backup_height}</span></span>
                </label>`);
            }

            if (fieldOptionsHtml.length === 0) {
                showToast(packshotphotoConfig.i18n.noRestoreAvailable || 'Nothing to restore', 'error');
                return;
            }

            let comparisonHtml = '';
            if (o.has_file_backup && o.comparison) {
                const c = o.comparison;
                comparisonHtml = `<div class="packshotphoto-restore-comparison" style="margin-top:10px;">
                    <div class="packshotphoto-comparison-slider" style="position:relative;width:100%;aspect-ratio:4/3;background:#1a1a2e;overflow:hidden;user-select:none;border-radius:6px;cursor:ew-resize;">
                        <div class="packshotphoto-img-before" style="position:absolute;top:0;left:0;width:100%;height:100%;background-size:contain;background-position:center;background-repeat:no-repeat;background-image:url('${c.before_url}');"></div>
                        <div class="packshotphoto-img-after" style="position:absolute;top:0;left:0;width:100%;height:100%;background-size:contain;background-position:center;background-repeat:no-repeat;background-image:url('${c.after_url}');clip-path:inset(0 0 0 50%);"></div>
                        <div class="packshotphoto-slider-handle" style="position:absolute;top:0;left:50%;width:2px;height:100%;background:#fff;transform:translateX(-50%);pointer-events:none;z-index:5;">
                            <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;color:#1a1a2e;width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:12px;pointer-events:auto;cursor:ew-resize;box-shadow:0 2px 6px rgba(0,0,0,0.4);">↔</div>
                        </div>
                        <span style="position:absolute;top:6px;left:6px;padding:2px 6px;background:rgba(0,0,0,0.75);color:#fff;font-size:10px;border-radius:3px;z-index:3;line-height:1.3;">${packshotphotoConfig.i18n.original || 'Original'} ${escHtml(c.before_format)}</span>
                        <span style="position:absolute;top:6px;right:6px;padding:2px 6px;background:rgba(99,102,241,0.85);color:#fff;font-size:10px;border-radius:3px;z-index:3;line-height:1.3;">${packshotphotoConfig.i18n.current || 'Current'} ${escHtml(c.after_format)}</span>
                    </div>
                </div>`;
            }

            const result = await modalManager.confirm({
                title: packshotphotoConfig.i18n.restoreTitle || 'Restore',
                icon: '↩️',
                message: `<div class="packshotphoto-field-checkboxes">${fieldOptionsHtml.join('')}</div>${comparisonHtml}`,
                buttons: [
                    { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                    { label: packshotphotoConfig.i18n.restore || 'Restore', value: 'restore', class: 'packshotphoto-btn-primary' }
                ]
            });

            if (result.value === 'cancel' || !result.value) {
                return;
            }

            const fields = {};
            modalManager.overlay.querySelectorAll('.packshotphoto-restore-checkbox').forEach(cb => {
                fields[cb.dataset.field] = cb.checked;
            });

            const restoreFile = fields.restore_file ? '1' : '0';
            delete fields.restore_file;
            const restoreSizeOnly = fields.restore_size_only ? '1' : '0';
            delete fields.restore_size_only;

            // Always restore latest version for now
            const versionIndex = -1;

            const hasAnyChecked = Object.values(fields).some(v => v);
            if (!hasAnyChecked && restoreFile !== '1' && restoreSizeOnly !== '1') {
                showToast(packshotphotoConfig.i18n.noRestoreAvailable || 'Nothing selected', 'error');
                return;
            }

            btn.classList.add('packshotphoto-loading');
            btn.querySelector('.packshotphoto-btn-text').textContent = '...';

            try {
                const response = await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'packshotphoto_revert_ai_metadata',
                        id: id,
                        nonce: nonce,
                        fields: JSON.stringify(fields),
                        restore_file: restoreFile,
                        restore_size_only: restoreSizeOnly,
                        version_index: versionIndex,
                    }),
                });

                const data = await response.json();
                btn.classList.remove('packshotphoto-loading');
                btn.querySelector('.packshotphoto-btn-text').textContent = packshotphotoConfig.i18n.restore || 'Restore';

                if (data.success) {
                    showToast(data.data.message || 'Restored!', 'success');
                    const restored = data.data.restored || {};

                    if (row) {
                        if (restored.alt !== undefined) {
                            const el = row.querySelector('[data-field="alt"]');
                            if (el) { el.value = restored.alt; el.classList.add('packshotphoto-flash'); setTimeout(() => el.classList.remove('packshotphoto-flash'), 1000); }
                        }
                        if (restored.caption !== undefined) {
                            const el = row.querySelector('[data-field="caption"]');
                            if (el) { el.value = restored.caption; el.classList.add('packshotphoto-flash'); setTimeout(() => el.classList.remove('packshotphoto-flash'), 1000); }
                        }
                        if (restored.description !== undefined) {
                            const el = row.querySelector('[data-field="description"]');
                            if (el) { el.value = restored.description; el.classList.add('packshotphoto-flash'); setTimeout(() => el.classList.remove('packshotphoto-flash'), 1000); }
                        }
                        if (restored.filename !== undefined) {
                            const el = row.querySelector('[data-field="filename"]');
                            if (el) { el.value = restored.filename; el.classList.add('packshotphoto-flash'); setTimeout(() => el.classList.remove('packshotphoto-flash'), 1000); }
                        }
                        if (restored.file_restored || restored.size_restored) {
                            setTimeout(() => location.reload(), 1000);
                        }
                    }

                    if (!restored.file_restored && !restored.size_restored && !restored.alt && !restored.caption && !restored.description && !restored.filename) {
                        btn.style.display = 'none';
                    }
                } else {
                    showToast(getErrorMessage(data), 'error');
                }
            } catch (error) {
                btn.classList.remove('packshotphoto-loading');
                btn.querySelector('.packshotphoto-btn-text').textContent = packshotphotoConfig.i18n.restore || 'Restore';
                showToast(packshotphotoConfig.i18n.error, 'error');
            }
        });
    }

    function escHtml(str) {
        const div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

function initComparisonSlider() {
        const overlay = document.querySelector('.packshotphoto-modal-overlay.active');
        if (!overlay) return;
        const container = overlay.querySelector('.packshotphoto-comparison-slider');
        if (!container) return;

        const afterDiv = container.querySelector('.packshotphoto-img-after');
        const handle = container.querySelector('.packshotphoto-slider-handle');
        if (!afterDiv || !handle) return;

        let isDragging = false;

        const move = (clientX) => {
            const rect = container.getBoundingClientRect();
            let x = clientX - rect.left;
            if (x < 0) x = 0;
            if (x > rect.width) x = rect.width;
            const pct = (x / rect.width) * 100;
            afterDiv.style.clipPath = `inset(0 0 0 ${pct}%)`;
            handle.style.left = `${pct}%`;
        };

        const onMove = (e) => {
            if (!isDragging) return;
            const clientX = e.touches ? e.touches[0].clientX : e.clientX;
            move(clientX);
        };

        const onStart = (e) => {
            // Start dragging on any click within the container
            isDragging = true;
            const clientX = e.touches ? e.touches[0].clientX : e.clientX;
            move(clientX);
            if (e.touches) e.preventDefault();
        };
        const onStop = () => { isDragging = false; };

        container.addEventListener('mousedown', onStart);
        container.addEventListener('touchstart', onStart, { passive: false });
        window.addEventListener('mousemove', onMove);
        window.addEventListener('touchmove', onMove, { passive: false });
        window.addEventListener('mouseup', onStop);
        window.addEventListener('touchend', onStop);
    }

    function ensureActionButtons(row, postId, nonce, flags) {
        if (!row) return;
        const toolsWrapper = row.querySelector('.packshotphoto-tools-actions');
        if (!toolsWrapper) return;

        const hasAiBackup = flags?.hasAiBackup ? '1' : '0';
        const hasFileBackup = flags?.hasFileBackup ? '1' : '0';
        const hasOriginalFilename = flags?.hasOriginalFilename ? '1' : '0';

        // 1. Manage Restore Button
        let restoreBtn = toolsWrapper.querySelector('.packshotphoto-restore-btn');
        if (restoreBtn) {
            restoreBtn.dataset.hasAiBackup = hasAiBackup;
            restoreBtn.dataset.hasFileBackup = hasFileBackup;
            restoreBtn.dataset.hasOriginalFilename = hasOriginalFilename;
            restoreBtn.style.display = '';
            restoreBtn.classList.remove('packshotphoto-loading');
        } else if (hasAiBackup === '1' || hasFileBackup === '1' || hasOriginalFilename === '1') {
            const btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'button button-small packshotphoto-restore-btn';
            btn.dataset.id = postId;
            btn.dataset.nonce = nonce;
            btn.dataset.hasAiBackup = hasAiBackup;
            btn.dataset.hasFileBackup = hasFileBackup;
            btn.dataset.hasOriginalFilename = hasOriginalFilename;
            btn.innerHTML = '<span class="packshotphoto-btn-text">' + (packshotphotoConfig.i18n.restore || 'Restore') + '</span>';
            toolsWrapper.appendChild(btn);
        }
    }

    function addToQueue(btn) {
        if (btn.classList.contains('packshotphoto-queued') || btn.classList.contains('packshotphoto-loading')) return;

        btn.classList.add('packshotphoto-queued');
        btn.querySelector('.packshotphoto-ai-text').textContent = '⏳';

        aiQueue.push(btn);
        updateQueueBadges();
        processQueue();
    }

    function updateQueueBadges() {
        aiQueue.forEach((btn, index) => {
            if (!btn.classList.contains('packshotphoto-loading')) {
                btn.querySelector('.packshotphoto-ai-text').textContent = `${packshotphotoConfig.i18n.generate || 'Generate'} (${index + 1})`;
            }
        });
    }

    async function processQueue() {
        if (isProcessingQueue || aiQueue.length === 0) return;

        isProcessingQueue = true;
        
        const totalAtStart = aiQueue.length;
        let success = 0;
        let error = 0;
        let bulkDecision = null;

        if (totalAtStart > 1) {
            pmmBulkProgress.show(totalAtStart, packshotphotoConfig.i18n.processingAI || 'Processing AI', packshotphotoConfig.i18n.optimizingLibrary || 'Optimizing media library...');
        }

        while (aiQueue.length > 0) {
            const btn = aiQueue[0];

            await new Promise(r => setTimeout(r, 500));

            if (aiQueue.length === 0) break;
            if (aiQueue[0] !== btn) continue;

            const row = btn.closest('tr');
            let resultRecord = { success: false };

            if (row) {
                let decision;
                if ((totalAtStart > 1 || isBulkAI) && bulkDecision !== null) {
                    decision = { action: 'apply', fields: bulkDecision };
                } else {
                    decision = await checkFieldsToOverwrite(row);
                    if (decision.action === 'cancel') {
                        // If in bulk mode, cancel the entire queue!
                        if (totalAtStart > 1 || isBulkAI) {
                            aiQueue.forEach(qBtn => {
                                qBtn.classList.remove('packshotphoto-queued');
                                qBtn.querySelector('.packshotphoto-ai-text').textContent = packshotphotoConfig.i18n.generate || 'Generate';
                                const qRow = qBtn.closest('tr');
                                if (qRow) {
                                    const qWrappers = qRow.querySelectorAll('.packshotphoto-cell-wrapper');
                                    qWrappers.forEach(w => w.classList.remove('packshotphoto-loading'));
                                }
                            });
                            aiQueue.length = 0; // Clear queue
                            if (window.pmmBulkProgress) window.pmmBulkProgress.hide();
                            break;
                        }
                        btn.classList.remove('packshotphoto-queued');
                        btn.querySelector('.packshotphoto-ai-text').textContent = packshotphotoConfig.i18n.generate || 'Generate';
                        aiQueue.shift();
                        updateQueueBadges();
                        continue;
                    }
                    if (totalAtStart > 1 || isBulkAI) {
                        bulkDecision = decision.fields;
                    }
                }

                resultRecord = await generateAI(btn, decision.fields);
                if (resultRecord.success) {
                    success++;
                    let filename = 'ID ' + btn.dataset.id;
                    const titleElement = row.querySelector('.title a, .row-title');
                    if (titleElement) filename = titleElement.textContent.trim();
                    const details = 'Alt: ' + (resultRecord.data?.alt || '-') + ' | Caption: ' + (resultRecord.data?.caption || '-');
                    addSessionLogEntry(btn.dataset.id, filename, "AI_BULK", "Success", details);
                } else {
                    error++;
                    let filename = 'ID ' + btn.dataset.id;
                    const titleElement = row.querySelector('.title a, .row-title');
                    if (titleElement) filename = titleElement.textContent.trim();
                    addSessionLogEntry(btn.dataset.id, filename, "AI_BULK", "Error", "AI generation failed");
                }
            }

            aiQueue.shift();
            updateQueueBadges();
            
            if (totalAtStart > 1 || isBulkAI) {
                pmmBulkProgress.update(success, error, aiQueue.length);
            }
        }

        isProcessingQueue = false;
        isBulkAI = false;
    }

async function checkFieldsToOverwrite(row) {
        const allFields = [
            { key: 'alt', label: packshotphotoConfig.i18n.altText || 'Alt Text' },
            { key: 'caption', label: packshotphotoConfig.i18n.captionLabel || 'Caption' },
            { key: 'description', label: packshotphotoConfig.i18n.descriptionLabel || 'Description' },
            { key: 'filename', label: packshotphotoConfig.i18n.filenameLabel || 'Filename' },
        ];

        let hasAnyData = false;
        let fieldOptionsHtml = '';

        allFields.forEach(field => {
            const el = row.querySelector(`[data-field="${field.key}"]`);
            const hasValue = el && el.value.trim();
            if (hasValue) hasAnyData = true;
            const preview = hasValue ? el.value.trim().substring(0, 35) + '...' : '(' + (packshotphotoConfig.i18n.empty || 'empty') + ')';
            let extraHtml = '';
            if (field.key === 'filename' && hasValue) {
                extraHtml = `
                    <div class="packshotphoto-warning-box">
                        <strong class="packshotphoto-warning-box-title">⚠️ ${packshotphotoConfig.i18n.renameWarningTitle || 'URL Change Risk'}</strong> 
                        <span class="packshotphoto-warning-box-text">${packshotphotoConfig.i18n.filenameWarning || 'Changing the file name will break the image URL. If this image is already used in posts, it will disappear (404).'}</span>
                        <label class="packshotphoto-field-check packshotphoto-warning-box-card">
                            <input type="checkbox" class="packshotphoto-field-sub-checkbox" data-subfield="slug_only" checked> 
                            <div>
                                <span class="packshotphoto-warning-box-card-title">${packshotphotoConfig.i18n.renameSlugOnly || 'Safe Rename: Title & Slug ONLY'}</span>
                                <small class="packshotphoto-warning-box-card-desc">${packshotphotoConfig.i18n.renameSafeDesc || 'Keep original URL. Safe for images already published in posts.'}</small>
                            </div>
                        </label>
                        <p class="packshotphoto-warning-box-footer">
                            ${packshotphotoConfig.i18n.renameUnsafeWarn || '* Uncheck "Safe Rename" only for new images that are not yet linked anywhere on your site.'}
                        </p>
                    </div>
                `;
            }
            fieldOptionsHtml += `<div class="packshotphoto-field-check-wrapper" style="margin-bottom: 8px;">
                <label class="packshotphoto-field-check">
                    <input type="checkbox" class="packshotphoto-field-checkbox" data-field="${field.key}" checked> 
                    <span class="packshotphoto-field-label">${field.label}</span> <small class="packshotphoto-field-preview">${preview}</small>
                </label>
                ${extraHtml}
            </div>`;
        });

        // Image context textarea — always shown so user can provide context
        const contextLabel = packshotphotoConfig.i18n.imageContextLabel || 'Image context (optional)';
        const contextPlaceholder = packshotphotoConfig.i18n.imageContextPlaceholder || 'e.g. "This is an espresso machine for home use" — additional info for AI';
        const contextHtml = `
            <div class="packshotphoto-field-check-wrapper" style="margin-top: 12px; margin-bottom: 8px; padding-top: 10px; border-top: 1px solid #eee;">
                <label class="packshotphoto-field-label" style="display:block; margin-bottom:4px; font-weight:600;">${contextLabel}</label>
                <textarea class="packshotphoto-image-context-input" rows="2" placeholder="${contextPlaceholder}" style="width:100%; padding:6px; border:1px solid #ccc; border-radius:4px; font-size:13px; resize:vertical;"></textarea>
            </div>`;

        // If no existing data, still show modal with context field (no field checkboxes needed)
        if (!hasAnyData) {
            const result = await modalManager.confirm({
                title: packshotphotoConfig.i18n.generateTitle || 'Generate AI Description',
                icon: '🤖',
                message: contextHtml,
                buttons: [
                    { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                    { label: packshotphotoConfig.i18n.generateBtn || 'Generate', value: 'apply', class: 'packshotphoto-btn-primary' }
                ]
            });

            if (result.value === 'cancel' || !result.value) {
                return { action: 'cancel' };
            }

            const modal = modalManager.overlay;
            const contextInput = modal.querySelector('.packshotphoto-image-context-input');
            const imageContext = contextInput ? contextInput.value.trim() : '';

            const decision = {
                action: 'apply',
                fields: { alt: true, caption: true, description: true, filename: true, renameFile: true, imageContext: imageContext }
            };

            return decision;
        }

        const result = await modalManager.confirm({
            title: packshotphotoConfig.i18n.existingDataTitle || 'Existing data found',
            icon: '⚠️',
            message: `<p>${packshotphotoConfig.i18n.selectFieldsToOverwrite || 'Select which fields to overwrite with AI:'}</p>
                <div class="packshotphoto-field-checkboxes">${fieldOptionsHtml}</div>${contextHtml}`,
            buttons: [
                { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                { label: packshotphotoConfig.i18n.apply || 'Apply', value: 'apply', class: 'packshotphoto-btn-primary' }
            ]
        });

        if (result.value === 'cancel' || !result.value) {
            return { action: 'cancel' };
        }

        const selectedFields = { alt: false, caption: false, description: false, filename: false, renameFile: false, renameSlugOnly: false, imageContext: '' };
        const modal = modalManager.overlay;
        const checkboxes = modal.querySelectorAll('.packshotphoto-field-checkbox');
        checkboxes.forEach(cb => {
            selectedFields[cb.dataset.field] = cb.checked;
        });

        const slugOnlyCb = modal.querySelector('[data-subfield="slug_only"]');
        if (slugOnlyCb && slugOnlyCb.checked) {
            selectedFields.renameSlugOnly = true;
        }

        // Get image context from textarea
        const contextInput = modal.querySelector('.packshotphoto-image-context-input');
        if (contextInput) {
            selectedFields.imageContext = contextInput.value.trim();
        }

        selectedFields.renameFile = selectedFields.filename;

        const decision = { action: 'apply', fields: selectedFields };

        return decision;
    }

    function generateAI(btn, fieldsOverride = null) {
        return new Promise((resolve) => {
            const id = btn.dataset.id;
            const nonce = btn.dataset.nonce;
            const row = btn.closest('tr');

            btn.classList.remove('packshotphoto-queued');
            btn.classList.add('packshotphoto-loading');
            btn.querySelector('.packshotphoto-ai-text').textContent = '...';

            const wrappers = row.querySelectorAll('.packshotphoto-cell-wrapper');
            wrappers.forEach(w => w.classList.add('packshotphoto-loading'));

            const imageContext = fieldsOverride && fieldsOverride.imageContext ? fieldsOverride.imageContext : '';

            fetch(packshotphotoConfig.ajaxUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    action: 'packshotphoto_generate_ai',
                    id: id,
                    nonce: nonce,
                    language: row ? (row.dataset.language || '') : '',
                    image_context: imageContext
                }),
            })
                .then(async response => {
                    const text = await response.text();
                    try {
                        return JSON.parse(text);
                    } catch (e) {
                        console.error('PackshotPhoto AI AI Error: Invalid JSON', text.substring(0, 200));
                        return { success: false, data: { message: packshotphotoConfig.i18n.serverInvalidResponse || 'Invalid server response' } };
                    }
                })
                .then(data => {
                    btn.classList.remove('packshotphoto-loading');
                    btn.querySelector('.packshotphoto-ai-text').textContent = packshotphotoConfig.i18n.generate || 'Generate';
                    wrappers.forEach(w => w.classList.remove('packshotphoto-loading'));

                    if (data.success) {
                        updateFields(row, data.data, fieldsOverride);
                        showToast(data.data?.message || (packshotphotoConfig.i18n.aiGenerated || 'AI generated!'), 'success');
                        ensureActionButtons(row, btn.dataset.id, btn.dataset.nonce, { hasAiBackup: true, hasOriginalFilename: true });
                        resolve({ success: true, data: data.data });
                    } else {
                        let errMsg = packshotphotoConfig.i18n.error || 'AI generation failed';
                        if (data) {
                            if (typeof data === 'string') {
                                errMsg = data;
                            } else if (data.data) {
                                if (typeof data.data === 'string') {
                                    errMsg = data.data;
                                } else if (typeof data.data === 'object') {
                                    errMsg = data.data.message || data.data.error || data.data.data || packshotphotoConfig.i18n.error || 'AI generation failed';
                                }
                            } else if (data.message) {
                                errMsg = data.message;
                            }
                        }

                        const lowerMsg = errMsg.toLowerCase();
                        const isCreditError = (data && data.credit_error) || (data && data.data && data.data.credit_error) ||
                                              lowerMsg.includes('kredyt') || lowerMsg.includes('credit') ||
                                              lowerMsg.includes('insufficient') || lowerMsg.includes('depleted') ||
                                              lowerMsg.includes('fund');

                        const isConnError = (data && data.connection_error) || (data && data.data && data.data.connection_error) ||
                                            lowerMsg.includes('połączenia') || lowerMsg.includes('connection') ||
                                            lowerMsg.includes('połącz') || lowerMsg.includes('missing pmm') ||
                                            lowerMsg.includes('brak pmm') || lowerMsg.includes('api key') ||
                                            lowerMsg.includes('licence') || lowerMsg.includes('licencji') ||
                                            lowerMsg.includes('cloud api') || lowerMsg.includes('cannot reach') ||
                                            lowerMsg.includes('server returned error') || lowerMsg.includes('unauthorized') ||
                                            lowerMsg.includes('forbidden') || lowerMsg.includes('reach pmm') ||
                                            lowerMsg.includes('empty response');

                        if (isCreditError || isConnError) {
                            showConnectionRequiredModal(errMsg, isCreditError);
                        } else {
                            showToast(errMsg, 'error');
                        }
                        resolve({ success: false });
                    }
                })
                .catch(error => {
                    btn.classList.remove('packshotphoto-loading');
                    btn.querySelector('.packshotphoto-ai-text').textContent = packshotphotoConfig.i18n.generate || 'Generate';
                    wrappers.forEach(w => w.classList.remove('packshotphoto-loading'));
                    showToast(packshotphotoConfig.i18n.networkError || 'Network error', 'error');
                    resolve({ success: false });
                });
        });
    }

    function saveMultipleFields(row, fieldsToSave) {
        const id = row.querySelector('[data-id]')?.dataset.id || row.dataset.id;
        let nonce = packshotphotoConfig.nonce;
        const firstInput = row.querySelector('[data-nonce]');
        if (firstInput) {
            nonce = firstInput.dataset.nonce;
        }

        const wrappers = [];
        const filenameWrapper = row.querySelector('.packshotphoto-filename-wrapper');

        for (const field of Object.keys(fieldsToSave)) {
            if (field === 'slug_only') continue;
            if (field === 'filename') {
                if (filenameWrapper) {
                    filenameWrapper.classList.remove('packshotphoto-saved', 'packshotphoto-error');
                    filenameWrapper.classList.add('packshotphoto-saving');
                    const indicator = filenameWrapper.querySelector('.packshotphoto-save-indicator');
                    if (indicator) indicator.textContent = packshotphotoConfig.i18n.saving || 'Saving...';
                }
            } else {
                const input = row.querySelector(`[data-field="${field}"]`);
                const wrapper = input ? input.closest('.packshotphoto-cell-wrapper') : null;
                if (wrapper) {
                    wrapper.classList.remove('packshotphoto-saved', 'packshotphoto-error');
                    wrapper.classList.add('packshotphoto-saving');
                    const indicator = wrapper.querySelector('.packshotphoto-save-indicator');
                    if (indicator) indicator.textContent = packshotphotoConfig.i18n.saving;
                    wrappers.push(wrapper);
                }
            }
        }

        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_save_field',
                id: id,
                nonce: nonce,
                fields: JSON.stringify(fieldsToSave)
            }),
        })
            .then(response => response.json())
            .then(data => {
                wrappers.forEach(w => {
                    w.classList.remove('packshotphoto-saving');
                });
                if (filenameWrapper) {
                    filenameWrapper.classList.remove('packshotphoto-saving');
                }

                if (data.success) {
                    wrappers.forEach(w => {
                        w.classList.add('packshotphoto-saved');
                        const indicator = w.querySelector('.packshotphoto-save-indicator');
                        if (indicator) indicator.textContent = packshotphotoConfig.i18n.saved;
                        setTimeout(() => w.classList.remove('packshotphoto-saved'), 2000);
                    });

                    if (fieldsToSave.filename && filenameWrapper) {
                        filenameWrapper.classList.add('packshotphoto-saved');
                        const indicator = filenameWrapper.querySelector('.packshotphoto-save-indicator');
                        if (indicator) indicator.textContent = packshotphotoConfig.i18n.saved || 'Renamed!';
                        setTimeout(() => filenameWrapper.classList.remove('packshotphoto-saved'), 2000);
                    }

                    showToast(data.data.message || packshotphotoConfig.i18n.saved, 'success');

                    if (data.data?.data?.filename) {
                        const newFilename = data.data.data.filename.new_filename;
                        const input = row.querySelector('.packshotphoto-filename-input');
                        if (input && newFilename) {
                            input.value = newFilename;
                            input.dataset.lastValue = newFilename;
                        }

                        if (data.data.data.filename.new_url) {
                            const thumbs = row.querySelectorAll('.column-thumbnail img, img.wp-image-' + id);
                            thumbs.forEach(thumb => {
                                const src = thumb.src || thumb.dataset.src;
                                if (src) {
                                    const separator = src.includes('?') ? '&' : '?';
                                    thumb.src = src + separator + 't=' + Date.now();
                                }
                            });
                        }
                    }
                } else {
                    wrappers.forEach(w => {
                        w.classList.add('packshotphoto-error');
                        const indicator = w.querySelector('.packshotphoto-save-indicator');
                        if (indicator) indicator.textContent = packshotphotoConfig.i18n.error;
                    });
                    if (filenameWrapper) {
                        filenameWrapper.classList.add('packshotphoto-error');
                        const indicator = filenameWrapper.querySelector('.packshotphoto-save-indicator');
                        if (indicator) indicator.textContent = packshotphotoConfig.i18n.error;
                    }
                    showToast(data.data?.message || packshotphotoConfig.i18n.error, 'error');
                }
            })
            .catch(error => {
                wrappers.forEach(w => {
                    w.classList.remove('packshotphoto-saving');
                    w.classList.add('packshotphoto-error');
                });
                if (filenameWrapper) {
                    filenameWrapper.classList.remove('packshotphoto-saving');
                    filenameWrapper.classList.add('packshotphoto-error');
                }
                showToast(packshotphotoConfig.i18n.error || 'Network error', 'error');
            });
    }

    function updateFields(row, data, fieldsOverride = null) {
        const allFields = {
            'alt': data.alt,
            'caption': data.caption,
            'description': data.desc || data.description,
        };

        const shouldRename = fieldsOverride ? fieldsOverride.renameFile : true;
        const shouldIncludeFilename = fieldsOverride ? fieldsOverride.filename : true;

        if (shouldRename && shouldIncludeFilename && data.slug) {
            allFields['filename'] = data.slug;
        }

        const fieldsToSave = {};
        const slugOnly = !!(fieldsOverride && fieldsOverride.renameSlugOnly);

        for (const [field, value] of Object.entries(allFields)) {
            if (!value) continue;
            if (fieldsOverride && !fieldsOverride[field]) continue;

            let input = row.querySelector(`textarea[data-field="${field}"]`);
            if (!input) {
                input = row.querySelector(`input[data-field="${field}"]`);
            }
            if (!input) continue;

            input.value = value;
            input.dataset.lastValue = value; // Prevent local editor triggers

            input.classList.add('packshotphoto-flash');
            setTimeout(() => input.classList.remove('packshotphoto-flash'), 1000);

            if (field === 'filename') {
                input.dataset.warned = 'true';
                input.dataset.slugOnly = slugOnly ? 'true' : 'false';
                fieldsToSave['filename'] = value;
                fieldsToSave['slug_only'] = slugOnly;
            } else {
                fieldsToSave[field] = value;
            }
        }

        if (Object.keys(fieldsToSave).length > 0) {
            saveMultipleFields(row, fieldsToSave);
        }
    }


    // ===== BANNER DISMISSAL =====

    function initBannerDismissal() {
        document.addEventListener('click', function (e) {
            const banner = e.target.closest('.packshotphoto-info-banner');
            const dismissBtn = e.target.closest('.notice-dismiss');

            if (banner && dismissBtn) {
                // Persist dismissal in user meta
                fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: new URLSearchParams({
                        action: 'packshotphoto_dismiss_banner',
                        nonce: packshotphotoConfig.nonce,
                    }),
                });
            }
        });
    }


    // ===== UNIFIED CONVERT POPOVER =====

    function formatBytes(bytes, decimals = 1) {
        if (!bytes || isNaN(bytes) || bytes === 0) return '0 KB';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }

    function showProRequiredModal() {
        modalManager.alert({
            title: packshotphotoConfig.i18n.proRequiredTitle || 'PRO Feature Required',
            icon: '🚀',
            message: packshotphotoConfig.i18n.proRequiredMessage || 'Bulk operations (resizing, format conversion, and AI metadata generation) are exclusively available to our clients with an active PackshotPhoto AI subscription and connection to our server.',
            buttons: [
                { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'close', class: 'packshotphoto-btn-secondary' },
                { label: packshotphotoConfig.i18n.goToSettings || 'Go to Settings', value: 'settings', class: 'packshotphoto-btn-primary' }
            ]
        }).then(result => {
            if (result && result.value === 'settings') {
                window.location.href = packshotphotoConfig.settingsUrl;
            }
        });
    }

    function showConnectionRequiredModal(msg, forceCredits = false) {
        const isDepleted = forceCredits || msg.toLowerCase().includes('kredyt') || msg.toLowerCase().includes('credit') || msg.toLowerCase().includes('insufficient');
        
        let title = packshotphotoConfig.i18n.missingConnectionTitle || 'No Connection to PackshotPhoto AI';
        let icon = '🔌';
        let message = packshotphotoConfig.i18n.missingConnectionMessage || msg || 'No connection to PackshotPhoto AI server.';
        let buttons = [
            { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'close', class: 'packshotphoto-btn-secondary' },
            { label: packshotphotoConfig.i18n.settings || 'Settings', value: 'settings', class: 'packshotphoto-btn-primary' }
        ];

        if (isDepleted) {
            title = packshotphotoConfig.i18n.insufficientCreditsTitle || 'Insufficient AI Credits';
            icon = '🪙';
            message = packshotphotoConfig.i18n.insufficientCreditsMessage || 'You have exhausted your free starter credits or do not have enough funds in your account. You can purchase a package of additional credits in the settings page.';
            buttons = [
                { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'close', class: 'packshotphoto-btn-secondary' },
                { label: packshotphotoConfig.i18n.buyCredits || 'Buy Credits', value: 'billing', class: 'packshotphoto-btn-primary' }
            ];
        }

        modalManager.alert({
            title: title,
            icon: icon,
            message: message,
            buttons: buttons
        }).then(result => {
            if (result) {
                if (result.value === 'settings' || result.value === 'billing') {
                    window.location.href = packshotphotoConfig.settingsUrl + '&tab=dev';
                }
            }
        });
    }

    function initConvertModal() {
        document.addEventListener('click', async function (e) {
            const btn = e.target.closest('.packshotphoto-convert-btn');
            if (!btn) return;

            e.preventDefault();

            const filesize = parseInt(btn.dataset.filesize, 10) || 0;
            const targetFormat = btn.dataset.target_format || null;

            // If target format is known (webp→avif or avif→webp), skip modal and convert directly
            if (targetFormat === 'avif') {
                convertToAvif(btn);
                return;
            } else if (targetFormat === 'webp') {
                convertToWebP(btn);
                return;
            }

            // For jpeg/png/gif — show format selection modal
            let webpSimSize = '';
            let avifSimSize = '';

            const estSizePrefix = packshotphotoConfig.i18n.estimatedSize || 'Estimated size:';
            if (filesize > 0) {
                webpSimSize = `${estSizePrefix} ~${formatBytes(filesize * 0.7)}`;
                avifSimSize = `${estSizePrefix} ~${formatBytes(filesize * 0.5)}`;
            } else {
                const savingsWebp = packshotphotoConfig.i18n.webpSavings || '30% savings';
                const savingsAvif = packshotphotoConfig.i18n.avifSavings || '50% savings';
                webpSimSize = `${estSizePrefix} ~${savingsWebp}`;
                avifSimSize = `${estSizePrefix} ~${savingsAvif}`;
            }

            const result = await modalManager.confirm({
                title: packshotphotoConfig.i18n.convertTitle || 'Convert Image Format',
                icon: '🔄',
                message: `
                    <p class="packshotphoto-modal-prompt">
                        ${packshotphotoConfig.i18n.convertPrompt || 'Select target compression format to reduce file size:'}
                    </p>
                    <div class="packshotphoto-convert-modal-options">
                        <label class="packshotphoto-convert-card active" data-format="webp">
                            <input type="radio" name="packshotphoto_convert_format" value="webp" checked style="display:none;">
                            <div class="packshotphoto-card-content">
                                <span class="packshotphoto-option-title">🖼️ WebP</span>
                                <span class="packshotphoto-option-desc">${packshotphotoConfig.i18n.webpDesc || 'Standard for modern websites. Reduces size without visible quality loss.'}</span>
                                <div class="packshotphoto-option-stats">
                                    <span class="packshotphoto-option-sim-size">${webpSimSize}</span>
                                    <span class="packshotphoto-savings-badge">${packshotphotoConfig.i18n.webpSavingsBadge || '-30% size'}</span>
                                </div>
                            </div>
                        </label>
                        <label class="packshotphoto-convert-card" data-format="avif">
                            <input type="radio" name="packshotphoto_convert_format" value="avif" style="display:none;">
                            <div class="packshotphoto-card-content">
                                <span class="packshotphoto-option-title">⚡ AVIF</span>
                                <span class="packshotphoto-option-desc">${packshotphotoConfig.i18n.avifDesc || 'Next generation compression. Extreme file size reduction while preserving perfect details.'}</span>
                                <div class="packshotphoto-option-stats">
                                    <span class="packshotphoto-option-sim-size">${avifSimSize}</span>
                                    <span class="packshotphoto-savings-badge">${packshotphotoConfig.i18n.avifSavingsBadge || '-50% size'}</span>
                                </div>
                            </div>
                        </label>
                    </div>
                `,
                buttons: [
                    { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                    { label: packshotphotoConfig.i18n.convertBtn || 'Convert', value: 'convert', class: 'packshotphoto-btn-primary' }
                ]
            });

            if (result.value === 'convert') {
                const selectedRadio = modalManager.overlay.querySelector('input[name="packshotphoto_convert_format"]:checked');
                const format = selectedRadio ? selectedRadio.value : 'webp';
                
                if (format === 'webp') {
                    convertToWebP(btn);
                } else if (format === 'avif') {
                    convertToAvif(btn);
                }
            }
        });

        // Click handler to select convert cards in modal
        document.addEventListener('click', function (e) {
            const card = e.target.closest('.packshotphoto-convert-card');
            if (!card) return;

            const wrapper = card.closest('.packshotphoto-convert-modal-options');
            if (wrapper) {
                wrapper.querySelectorAll('.packshotphoto-convert-card').forEach(c => {
                    c.classList.remove('active');
                    const radio = c.querySelector('input[type="radio"]');
                    if (radio) radio.checked = false;
                });
            }

            card.classList.add('active');
            const radio = card.querySelector('input[type="radio"]');
            if (radio) radio.checked = true;
        });

        // Double click handler to automatically submit
        document.addEventListener('dblclick', function (e) {
            const card = e.target.closest('.packshotphoto-convert-card');
            if (!card) return;

            const wrapper = card.closest('.packshotphoto-convert-modal-options');
            if (wrapper) {
                wrapper.querySelectorAll('.packshotphoto-convert-card').forEach(c => {
                    c.classList.remove('active');
                    const radio = c.querySelector('input[type="radio"]');
                    if (radio) radio.checked = false;
                });
            }

            card.classList.add('active');
            const radio = card.querySelector('input[type="radio"]');
            if (radio) radio.checked = true;

            const convertBtn = modalManager.overlay.querySelector('.packshotphoto-btn-primary');
            if (convertBtn) {
                convertBtn.click();
            }
        });
    }

    function convertToWebP(btn) {
        if (btn.classList.contains('packshotphoto-loading')) return Promise.resolve({ success: false, message: 'Already loading' });

        const id = btn.dataset.id;
        const nonce = btn.dataset.nonce;

        btn.classList.add('packshotphoto-loading');
        
        const textSpan = btn.querySelector('.packshotphoto-btn-text, .packshotphoto-webp-text, .packshotphoto-avif-text');
        const originalText = textSpan ? textSpan.textContent : '';
        if (textSpan) textSpan.textContent = '...';

        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_convert_webp',
                id: id,
                nonce: nonce,
            }),
        })
            .then(async response => {
                const text = await response.text();
                try {
                    return JSON.parse(text);
                } catch (e) {
                    return { success: false, data: { message: packshotphotoConfig.i18n.serverInvalidResponse || 'Invalid server response' } };
                }
            })
            .then(data => {
                btn.classList.remove('packshotphoto-loading');
                
                console.log('PackshotPhoto AI WebP Convert Response:', data);

                if (data.success) {
                    console.log('PackshotPhoto AI WebP Debug Info:', data.data?.debug);
                    const row = btn.closest('tr');
                    
                    // Replace button with new Convert button (WebP → AVIF)
                    const newBtn = document.createElement('button');
                    newBtn.type = 'button';
                    newBtn.className = 'button button-small packshotphoto-convert-btn';
                    newBtn.dataset.id = id;
                    newBtn.dataset.nonce = nonce;
                    newBtn.dataset.filesize = '0';
                    newBtn.dataset.targetFormat = 'avif';
                    newBtn.innerHTML = '<span class="packshotphoto-btn-text">' + (packshotphotoConfig.i18n.convertBtn || 'Convert') + '</span>';
                    
                    const dropdownContainer = btn.closest('.packshotphoto-convert-dropdown-container');
                    if (dropdownContainer) {
                        dropdownContainer.replaceWith(newBtn);
                    } else {
                        btn.replaceWith(newBtn);
                    }
                    
                    if (row && data.data && data.data.new_filename) {
                        const filenameInput = row.querySelector('.packshotphoto-filename-input');
                        if (filenameInput) {
                            filenameInput.value = data.data.new_filename;
                            filenameInput.classList.add('packshotphoto-flash');
                            setTimeout(() => filenameInput.classList.remove('packshotphoto-flash'), 1000);
                        }
                    }
                    if (row && data.data && data.data.new_url) {
                        const thumbs = row.querySelectorAll('.column-thumbnail img, img.wp-image-' + id);
                        thumbs.forEach(thumb => {
                            const src = thumb.src || thumb.dataset.src;
                            if (src) {
                                const separator = src.includes('?') ? '&' : '?';
                                thumb.src = src + separator + 't=' + Date.now();
                            }
                        });
                    }
                    if (row) {
                        ensureActionButtons(row, id, nonce, { hasFileBackup: true, hasOriginalFilename: true });
                    }
                    showToast(data.data.message || (packshotphotoConfig.i18n.done || 'Converted!'), 'success');
                    return { success: true, data: data.data };
                } else {
                    if (textSpan) textSpan.textContent = originalText;
                    const msg = getErrorMessage(data);
                    showToast(msg, 'error');
                    return { success: false, message: msg };
                }
            })
            .catch(error => {
                btn.classList.remove('packshotphoto-loading');
                if (textSpan) textSpan.textContent = originalText;
                showToast(packshotphotoConfig.i18n.networkError || 'Network error', 'error');
                return { success: false, message: packshotphotoConfig.i18n.error };
            });
    }

    function convertToAvif(btn) {
        if (btn.classList.contains('packshotphoto-loading')) return Promise.resolve({ success: false, message: 'Already loading' });

        const id = btn.dataset.id;
        const nonce = btn.dataset.nonce;

        btn.classList.add('packshotphoto-loading');
        
        const textSpan = btn.querySelector('.packshotphoto-btn-text, .packshotphoto-webp-text, .packshotphoto-avif-text');
        const originalText = textSpan ? textSpan.textContent : '';
        if (textSpan) textSpan.textContent = '...';

        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_convert_avif',
                id: id,
                nonce: nonce,
            }),
        })
            .then(async response => {
                const text = await response.text();
                try {
                    return JSON.parse(text);
                } catch (e) {
                    return { success: false, data: { message: packshotphotoConfig.i18n.serverInvalidResponse || 'Invalid server response' } };
                }
            })
            .then(data => {
                btn.classList.remove('packshotphoto-loading');
                
                console.log('PackshotPhoto AI AVIF Convert Response:', data);

                if (data.success) {
                    console.log('PackshotPhoto AI AVIF Debug Info:', data.data?.debug);
                    const row = btn.closest('tr');
                    
                    // Replace button with new Convert button (AVIF → WebP)
                    const newBtn = document.createElement('button');
                    newBtn.type = 'button';
                    newBtn.className = 'button button-small packshotphoto-convert-btn';
                    newBtn.dataset.id = id;
                    newBtn.dataset.nonce = nonce;
                    newBtn.dataset.filesize = '0';
                    newBtn.dataset.targetFormat = 'webp';
                    newBtn.innerHTML = '<span class="packshotphoto-btn-text">' + (packshotphotoConfig.i18n.convertBtn || 'Convert') + '</span>';
                    
                    const dropdownContainer = btn.closest('.packshotphoto-convert-dropdown-container');
                    if (dropdownContainer) {
                        dropdownContainer.replaceWith(newBtn);
                    } else {
                        btn.replaceWith(newBtn);
                    }
                    
                    if (row && data.data && data.data.new_filename) {
                        const filenameInput = row.querySelector('.packshotphoto-filename-input');
                        if (filenameInput) {
                            filenameInput.value = data.data.new_filename;
                            filenameInput.classList.add('packshotphoto-flash');
                            setTimeout(() => filenameInput.classList.remove('packshotphoto-flash'), 1000);
                        }
                    }
                    if (row && data.data && data.data.new_url) {
                        const thumbs = row.querySelectorAll('.column-thumbnail img, img.wp-image-' + id);
                        thumbs.forEach(thumb => {
                            const src = thumb.src || thumb.dataset.src;
                            if (src) {
                                const separator = src.includes('?') ? '&' : '?';
                                thumb.src = src + separator + 't=' + Date.now();
                            }
                        });
                    }
                    if (row) {
                        ensureActionButtons(row, id, nonce, { hasFileBackup: true, hasOriginalFilename: true });
                    }
                    showToast(data.data.message || (packshotphotoConfig.i18n.done || 'Converted!'), 'success');
                    return { success: true, data: data.data };
                } else {
                    if (textSpan) textSpan.textContent = originalText;
                    const msg = getErrorMessage(data);
                    showToast(msg, 'error');
                    return { success: false, message: msg };
                }
            })
            .catch(error => {
                btn.classList.remove('packshotphoto-loading');
                if (textSpan) textSpan.textContent = originalText;
                showToast(packshotphotoConfig.i18n.networkError || 'Network error', 'error');
                return { success: false, message: packshotphotoConfig.i18n.error };
            });
    }

    // ===== RESIZE FEATURE =====

    function initResizeFeature() {
        document.addEventListener('click', async function (e) {
            // Handle AUTO Resize Button (Standard)
            const autoBtn = e.target.closest('.packshotphoto-resize-btn');
            if (autoBtn) {
                e.preventDefault();
                resizeImage(autoBtn, null);
                return;
            }

            // Handle MANUAL Resize Button (When limit is 0)
            const manualBtn = e.target.closest('.packshotphoto-manual-resize-trigger');
            if (manualBtn) {
                e.preventDefault();

                // Prompt for size
                const result = await modalManager.confirm({
                    title: packshotphotoConfig.i18n.resizeTitle || 'Resize image',
                    icon: '📉',
                    message: packshotphotoConfig.i18n.resizePrompt || 'Enter target width (px):',
                    input: {
                        label: packshotphotoConfig.i18n.widthPx || 'Width (px)',
                        value: '1600',
                        type: 'number'
                    },
                    buttons: [
                        { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                        { label: packshotphotoConfig.i18n.resizeBtn || 'Resize', value: 'resize', class: 'packshotphoto-btn-primary' }
                    ]
                });

                if (result.value === 'resize' && result.inputValue) {
                    const width = parseInt(result.inputValue, 10);
                    if (width && width > 100) {
                        resizeImage(manualBtn, width);
                    } else {
                        showToast(packshotphotoConfig.i18n.invalidSize || 'Invalid size', 'error');
                    }
                }
            }
        });
    }

    function resizeImage(btn, targetWidth = null) {
        if (btn.classList.contains('packshotphoto-loading')) return Promise.resolve({ success: false, message: 'Already loading' });

        const row = btn.closest('tr');
        if (!row) return Promise.resolve({ success: false, message: 'No row found' });

        const id = btn.dataset.id;
        const nonce = btn.dataset.nonce;

        // Loading State
        btn.classList.add('packshotphoto-loading');

        const wrappers = row.querySelectorAll('.packshotphoto-cell-wrapper');
        wrappers.forEach(w => w.classList.add('packshotphoto-loading'));

        let textSpan = btn.querySelector('.packshotphoto-btn-text');
        let originalText = '';

        if (textSpan) {
            originalText = textSpan.textContent;
            textSpan.textContent = '...';
        } else {
            originalText = btn.textContent;
            btn.textContent = '...';
        }

        const params = {
            action: 'packshotphoto_resize_image',
            id: id,
            nonce: nonce,
        };
        if (targetWidth) {
            params.target_width = targetWidth;
        }

        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams(params),
        })
            .then(async response => {
                const text = await response.text();
                try {
                    return JSON.parse(text);
                } catch (e) {
                    return { success: false, data: { message: packshotphotoConfig.i18n.serverInvalidResponse || 'Invalid server response' } };
                }
            })
        .then(data => {
            btn.classList.remove('packshotphoto-loading');
            if (row) wrappers.forEach(w => w.classList.remove('packshotphoto-loading'));
            if (data.success) {
                if (textSpan) {
                    textSpan.textContent = '✓';
                } else {
                    btn.textContent = '✓';
                }
                
                const msg = data.data.message || (packshotphotoConfig.i18n.done || 'Done');
                showToast(msg, 'success');
                
                // Update button text to show new actual width if available
                if (data.data.new_width && textSpan) {
                    textSpan.textContent = `Resize (${data.data.new_width}px)`;
                    originalText = textSpan.textContent; 
                }
                
                // Add/Update buttons after resize
                ensureActionButtons(row, id, nonce, { hasFileBackup: true });
                
                setTimeout(() => {
                    if (textSpan) {
                        textSpan.textContent = originalText;
                    } else {
                        btn.textContent = originalText;
                    }
                }, 3000);
                return { success: true, data: data.data };
            } else {
                const msg = getErrorMessage(data);
                if (textSpan) textSpan.textContent = originalText;
                else btn.textContent = originalText;
                
                showToast(msg, 'error');
                return { success: false, message: msg };
            }
        })
            .catch(error => {
                btn.classList.remove('packshotphoto-loading');
                if (textSpan) textSpan.textContent = originalText;
                else btn.textContent = originalText;
                showToast(packshotphotoConfig.i18n.error, 'error');
                return { success: false, message: packshotphotoConfig.i18n.error };
            });
    }

    // ===== BULK ACTIONS =====

    function initBulkActions() {
        const bulkButtons = ['doaction', 'doaction2'];
        bulkButtons.forEach(id => {
            const btn = document.getElementById(id);
            if (!btn) return;

            btn.addEventListener('click', async function (e) {
                const selector = id === 'doaction' ? '#bulk-action-selector-top' : '#bulk-action-selector-bottom';
                const select = document.querySelector(selector);
                if (!select) return;

                const value = select.value;
                if (!['packshotphoto_bulk_ai', 'packshotphoto_bulk_eu_ai', 'packshotphoto_bulk_webp', 'packshotphoto_bulk_avif', 'packshotphoto_bulk_resize'].includes(value)) return;

                e.preventDefault();

                const checked = Array.from(document.querySelectorAll('input[name="media[]"]:checked'));
                if (!checked.length) return;

                let extraArgs = null;

                // Bulk Resize Logic with Modal
                if (value === 'packshotphoto_bulk_resize') {
                    const result = await modalManager.confirm({
                        title: packshotphotoConfig.i18n.resizeTitle || 'Resize',
                        icon: '📉',
                        message: (packshotphotoConfig.i18n.resizeImages || 'Resize %d images?').replace('%d', checked.length),
                        input: {
                            label: (packshotphotoConfig.i18n.width || 'Width') + ' (' + (packshotphotoConfig.i18n.px || 'px') + ')',
                            value: '1600',
                            type: 'number'
                        },
                        buttons: [
                            { label: packshotphotoConfig.i18n.cancel || 'Cancel', value: 'cancel', class: 'packshotphoto-btn-secondary' },
                            { label: packshotphotoConfig.i18n.resizeBtn || 'Resize', value: 'resize', class: 'packshotphoto-btn-primary' }
                        ]
                    });

                    if (result.value !== 'resize' || !result.inputValue) return;
                    extraArgs = parseInt(result.inputValue, 10);
                }

                showToast((packshotphotoConfig.i18n.startingProcessing || 'Starting processing of %d items...').replace('%d', checked.length), 'info');

                processGenericQueue(checked, value, extraArgs);
            });
        });
    }

    async function processGenericQueue(checkboxes, action, extraArgs = null) {
        const total = checkboxes.length;
        
        // Map UI actions to API actions
        const actionMap = {
            'packshotphoto_bulk_ai': 'ai',
            'packshotphoto_bulk_eu_ai': 'eu_ai',
            'packshotphoto_bulk_webp': 'webp',
            'packshotphoto_bulk_avif': 'avif',
            'packshotphoto_bulk_resize': 'resize'
        };

        const batchAction = actionMap[action];
        const ids = checkboxes.map(c => parseInt(c.value, 10));

        // HYBRID LOGIC: 
        // If more than 10 items, use the BACKGROUND queue (Phase 5.1)
        if (total > 10) {
            showToast(packshotphotoConfig.i18n.movingToBackground || 'Large batch - moving to background processing...', 'info');
            // Form submission will trigger handle_bulk_actions filter in PHP
            const form = document.getElementById('posts-filter');
            if (form) {
                // We need to set the value in the selector first to match what PHP expects
                const selector = document.querySelector('#bulk-action-selector-top');
                if (selector) selector.value = action;
                form.submit();
                return;
            }
        }

        // AI is still handled by specialized queue for granular feedback per row
        if (action === 'packshotphoto_bulk_ai') {
            isBulkAI = true;
            checkboxes.forEach(checkbox => {
                const row = checkbox.closest('tr');
                if (row) {
                    const btn = row.querySelector('.packshotphoto-ai-btn');
                    if (btn) addToQueue(btn);
                }
            });
            return;
        }

        // FOREGROUND BATCHING (Phase 5.2)
        // Process one by one (safer for memory limits and execution time)
        let successCount = 0;
        let errorCount = 0;
        const BATCH_SIZE = 1;

        let title = packshotphotoConfig.i18n.processing || 'Processing...';
        let sub = packshotphotoConfig.i18n.workInProgress || 'Work in progress...';

        if (action === 'packshotphoto_bulk_webp') {
            title = packshotphotoConfig.i18n.webpConversion || 'WebP Conversion';
            sub = packshotphotoConfig.i18n.convertingImages || 'Converting images to modern format...';
        } else if (action === 'packshotphoto_bulk_avif') {
            title = packshotphotoConfig.i18n.avifConversion || 'AVIF Conversion';
            sub = packshotphotoConfig.i18n.convertingImages || 'Converting images to modern format...';
        } else if (action === 'packshotphoto_bulk_eu_ai') {
            title = 'EU AI Act Watermark';
            sub = 'Stamping EU AI Act transparency labels on images...';
        } else if (action === 'packshotphoto_bulk_resize') {
            title = packshotphotoConfig.i18n.resizing || 'Resizing';
            sub = packshotphotoConfig.i18n.adjustingDimensions || 'Adjusting image dimensions...';
        }

        window.pmmBulkProgress.show(total, title, sub);

        for (let i = 0; i < ids.length; i += BATCH_SIZE) {
            const chunk = ids.slice(i, i + BATCH_SIZE);
            const remaining = ids.length - (i + chunk.length);

            try {
                const response = await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'packshotphoto_process_batch',
                        nonce: packshotphotoConfig.nonce,
                        ids: JSON.stringify(chunk),
                        batch_action: batchAction,
                        args: extraArgs
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP_${response.status}`);
                }

                const json = await response.json();
                if (json.success) {
                    const results = (json.data && json.data.results) ? json.data.results : (json.data || {});
                    Object.entries(results).forEach(([postId, r]) => {
                        let filename = 'ID ' + postId;
                        const row = document.querySelector('#post-' + postId);
                        if (row) {
                            const titleElement = row.querySelector('.title a, .row-title');
                            if (titleElement) filename = titleElement.textContent.trim();
                        }
                        
                        if (r.success) {
                            successCount++;
                            let details = r.data || {};

                            // If this was an EU AI stamp, WebP, AVIF or resize, live cache-bust the thumbnail in the table
                            if (row) {
                                const thumb = row.querySelector('.column-primary img, .media-icon img, .thumbnail img');
                                if (thumb && thumb.src) {
                                    const baseSrc = thumb.src.split('?')[0];
                                    thumb.src = baseSrc + '?t=' + Date.now();
                                }
                                const restoreBtn = row.querySelector('.packshotphoto-restore-btn');
                                if (restoreBtn) restoreBtn.style.display = 'inline-block';
                            }

                            addSessionLogEntry({
                                id: postId,
                                original_filename: filename,
                                new_filename: details.new_filename || filename,
                                action: batchAction.toUpperCase(),
                                status: 'Success',
                                original_size: details.before_size || '-',
                                new_size: details.after_size || '-',
                                savings: details.savings !== undefined ? (details.savings + '%') : '-',
                                width_change: details.old_width ? (details.old_width + 'px -> ' + details.new_width + 'px') : '-',
                                height_change: details.old_height ? (details.old_height + 'px -> ' + details.new_height + 'px') : '-',
                                alt: details.alt || '-',
                                caption: details.caption || '-',
                                message: r.message || 'Success'
                            });
                        } else {
                            errorCount++;
                            addSessionLogEntry({
                                id: postId,
                                original_filename: filename,
                                new_filename: '-',
                                action: batchAction.toUpperCase(),
                                status: 'Error',
                                original_size: '-',
                                new_size: '-',
                                savings: '-',
                                width_change: '-',
                                height_change: '-',
                                alt: '-',
                                caption: '-',
                                message: r.message || 'Failed'
                            });
                        }
                    });
                } else {
                    errorCount += chunk.length;
                    chunk.forEach(postId => {
                        let filename = 'ID ' + postId;
                        const row = document.querySelector('#post-' + postId);
                        if (row) {
                            const titleElement = row.querySelector('.title a, .row-title');
                            if (titleElement) filename = titleElement.textContent.trim();
                        }
                        addSessionLogEntry({
                            id: postId,
                            original_filename: filename,
                            new_filename: '-',
                            action: batchAction.toUpperCase(),
                            status: 'Error',
                            original_size: '-',
                            new_size: '-',
                            savings: '-',
                            width_change: '-',
                            height_change: '-',
                            alt: '-',
                            caption: '-',
                            message: 'Server error'
                        });
                    });
                }
            } catch (err) {
                errorCount += chunk.length;
                console.error('Batch error', err);
                
                chunk.forEach(postId => {
                    let filename = 'ID ' + postId;
                    const row = document.querySelector('#post-' + postId);
                    if (row) {
                        const titleElement = row.querySelector('.title a, .row-title');
                        if (titleElement) filename = titleElement.textContent.trim();
                    }
                    addSessionLogEntry({
                        id: postId,
                        original_filename: filename,
                        new_filename: '-',
                        action: batchAction.toUpperCase(),
                        status: 'Error',
                        original_size: '-',
                        new_size: '-',
                        savings: '-',
                        width_change: '-',
                        height_change: '-',
                        alt: '-',
                        caption: '-',
                        message: err.message || 'Network error'
                    });
                });

                // Detect server overload/crash (503, 500, 504)
                const isServerCrash = err.message && (
                    err.message.includes('503') || 
                    err.message.includes('500') || 
                    err.message.includes('504') || 
                    err.message.includes('HTTP_5')
                );

                if (isServerCrash) {
                    window.pmmBulkProgress.hide();
                    showToast(packshotphotoConfig.i18n.serverError503 || 'Server error (503/500). The process was stopped to prevent server overload. Please resize the images first!', 'error');
                    break; // STOP the bulk loop!
                }
            }

            window.pmmBulkProgress.update(successCount, errorCount, remaining);
        }

        setTimeout(() => {
            window.pmmBulkProgress.hide();
            const msg = (packshotphotoConfig.i18n.doneBatch || 'Done: %1$s success, %2$s errors.')
                .replace('%1$s', successCount)
                .replace('%2$s', errorCount)
                .replace('%s', successCount)
                .replace('%e', errorCount);
            showToast(msg, errorCount > 0 ? 'warning' : 'success');
        }, 1500);
    }


    // ===== SETTINGS PAGE (Restored & Improved) =====

    function initSettingsPage() {
        const form = document.getElementById('packshotphoto-settings-form');

        // Auto-save API Key on blur
        const apiKeyInput = document.getElementById('packshotphoto_api_key');
        if (apiKeyInput) {
            apiKeyInput.addEventListener('blur', function () {
                saveApiKey(this.value);
            });
        }

        const contextInput = document.getElementById('packshotphoto_site_context');

        // Test API Connection
        const testBtn = document.getElementById('packshotphoto-test-api');
        if (testBtn) {
            testBtn.addEventListener('click', async (e) => {
                e.preventDefault();

                // Auto-save before testing if key is present
                if (apiKeyInput) {
                    testBtn.textContent = packshotphotoConfig.i18n.saving || 'Saving...';
                    await saveApiKey(apiKeyInput.value);
                    testBtn.textContent = packshotphotoConfig.i18n.testConnection || 'Test connection';
                }
                testApiConnection();
            });
        }

        // Fetch Site Context
        const fetchBtn = document.getElementById('packshotphoto-fetch-context');
        if (fetchBtn) {
            fetchBtn.addEventListener('click', async function (e) {
                e.preventDefault();
                await fetchSiteContext();
            });
        }

        // Reset All Settings
        const resetBtn = document.getElementById('packshotphoto-reset-settings');
        if (resetBtn) {
            resetBtn.addEventListener('click', function(e) {
                e.preventDefault();
                ajaxResetSettings(resetBtn);
            });
        }
    }

    async function ajaxResetSettings(btn) {
        if (!confirm(packshotphotoConfig.i18n.resetConfirm || 'Are you sure you want to reset all settings to factory defaults? This action cannot be undone.')) {
            return;
        }

        const originalText = btn.textContent;
        btn.disabled = true;
        btn.textContent = packshotphotoConfig.i18n.resetting || '⏳ Resetting...';

        const nonce = packshotphotoConfig.global_nonce || packshotphotoConfig.nonce;

        try {
            const response = await fetch(packshotphotoConfig.ajaxUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'packshotphoto_reset_settings',
                    nonce: nonce
                })
            });

            const data = await response.json();
            if (data.success) {
                showToast(data.data, 'success');
                setTimeout(() => window.location.reload(), 1500);
            } else {
            showToast(data.data || (packshotphotoConfig.i18n.error || 'Reset error'), 'error');
                btn.disabled = false;
                btn.textContent = originalText;
            }
        } catch (err) {
            showToast(packshotphotoConfig.i18n.networkError || 'Network error', 'error');
            btn.disabled = false;
            btn.textContent = originalText;
        }
    }

    async function saveApiKey(key) {
        const nonce = packshotphotoConfig.global_nonce || packshotphotoConfig.nonce;

        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                action: 'packshotphoto_save_api_key',
                api_key: key,
                nonce: nonce
            })
        })
            .then(r => r.json())
            .then(data => {
                if (data.success) {
                    showToast(packshotphotoConfig.i18n.saved || 'API key saved', 'success');
                } else {
                    showToast(data.data, 'error');
                }
            });
    }

    function saveSiteContext(context) {
        const nonce = packshotphotoConfig.global_nonce || packshotphotoConfig.nonce;
        fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                action: 'packshotphoto_save_site_context',
                context: context,
                nonce: nonce
            })
        })
            .then(r => r.json())
            .then(data => {
                if (data.success) showToast(packshotphotoConfig.i18n.saved || 'Context saved', 'success');
            });
    }

    function testApiConnection() {
        const resultSpan = document.querySelector('.packshotphoto-test-result');
        const apiKeyInput = document.getElementById('packshotphoto_api_key');

        if (resultSpan) {
            resultSpan.textContent = '⏳ ' + (packshotphotoConfig.i18n.checking || 'Checking...');
            resultSpan.className = 'packshotphoto-test-result';
        }

        const nonce = packshotphotoConfig.global_nonce || packshotphotoConfig.nonce;
        const key = apiKeyInput ? apiKeyInput.value : '';

        fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                action: 'packshotphoto_test_api',
                api_key: key, // Pass explicitly
                nonce: nonce
            })
        })
            .then(r => r.json())
            .then(data => {
                if (resultSpan) {
                    if (data.success) {
                        resultSpan.textContent = '✅ ' + data.data;
                        resultSpan.className = 'packshotphoto-success';
                        resultSpan.classList.add('packshotphoto-success');
                    } else {
                        resultSpan.textContent = '❌ ' + data.data;
                        resultSpan.className = 'packshotphoto-test-result';
                        resultSpan.classList.add('packshotphoto-error');
                    }
                }
            })
            .catch(err => {
                if (resultSpan) {
                    resultSpan.textContent = '❌ Network error: ' + err.message;
                    resultSpan.className = 'packshotphoto-test-result packshotphoto-error';
                }
            });
    }

async function fetchSiteContext() {
        const contextInput = document.getElementById('packshotphoto_site_context');
        const fetchBtn = document.getElementById('packshotphoto-fetch-context');

        if (fetchBtn) {
            fetchBtn.disabled = true;
            fetchBtn.textContent = '⏳ ' + (packshotphotoConfig.i18n.analyzing || 'Analyzing...');
        }
        if (contextInput) contextInput.classList.add('packshotphoto-loading');

        const nonce = packshotphotoConfig.global_nonce || packshotphotoConfig.nonce;

        const langInput = document.getElementById('packshotphoto_language');
        const langValue = langInput ? langInput.value : 'auto';

        try {
            const response = await fetch(packshotphotoConfig.ajaxUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'packshotphoto_fetch_context',
                    nonce: nonce,
                    language: langValue
                })
            });

            // Guard against non-JSON responses (PHP fatal errors return HTML)
            const rawText = await response.text();
            let data;
            try {
                data = JSON.parse(rawText);
            } catch (parseErr) {
                console.error('PackshotPhoto AI: Non-JSON response from packshotphoto_fetch_context', rawText.substring(0, 200));
                showToast(packshotphotoConfig.i18n.error || 'Server returned invalid response', 'error');
                if (contextInput) contextInput.classList.remove('packshotphoto-loading');
                return;
            }

            if (data.success) {
                showToast(packshotphotoConfig.i18n.done || 'Done!', 'success');
                if (contextInput) {
                    contextInput.value = data.data.context || data.data || '';
                    contextInput.classList.remove('packshotphoto-loading');
                    contextInput.classList.add('packshotphoto-flash');
                    setTimeout(() => contextInput.classList.remove('packshotphoto-flash'), 1500);
                }
                // Auto-save the generated context
                await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'packshotphoto_save_site_context',
                        context: contextInput ? contextInput.value : '',
                        nonce: nonce
                    })
                });
            } else {
                showToast(data.data || packshotphotoConfig.i18n.error || 'Error', 'error');
                if (contextInput) contextInput.classList.remove('packshotphoto-loading');
            }
        } catch (err) {
            showToast((packshotphotoConfig.i18n.networkError || 'Network error') + ': ' + err.message, 'error');
            if (contextInput) contextInput.classList.remove('packshotphoto-loading');
        } finally {
            if (fetchBtn) {
                fetchBtn.disabled = false;
                fetchBtn.textContent = (packshotphotoConfig.i18n.generateContext || 'Generate Context with AI');
            }
        }
    }


    function initImageComparison() {
        document.addEventListener('click', function (e) {
            const btn = e.target.closest('.packshotphoto-compare-btn');
            if (!btn) return;

            e.preventDefault();
            handleComparison(btn);
        });
    }

    async function handleComparison(btn) {
        if (btn.classList.contains('packshotphoto-loading')) return;

        const id = btn.dataset.id;
        const nonce = btn.dataset.nonce;

        btn.classList.add('packshotphoto-loading');
        const originalIcon = btn.querySelector('.packshotphoto-btn-text').textContent;
        btn.querySelector('.packshotphoto-btn-text').textContent = '⏳';

        try {
            const response = await fetch(packshotphotoConfig.ajaxUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'packshotphoto_get_comparison_data',
                    id: id,
                    nonce: nonce
                })
            });

            const data = await response.json();
            btn.classList.remove('packshotphoto-loading');
            btn.querySelector('.packshotphoto-btn-text').textContent = originalIcon;

            if (data.success) {
                data.data.id = id;
                data.data.nonce = nonce;
                showComparisonModal(data.data);
            } else {
                showToast(data.data.message || 'Error fetching comparison data', 'error');
            }
        } catch (err) {
            btn.classList.remove('packshotphoto-loading');
            btn.querySelector('.packshotphoto-btn-text').textContent = originalIcon;
            showToast(packshotphotoConfig.i18n.networkError || 'Network error', 'error');
        }
    }

    function showComparisonModal(data) {
        const modal = modalManager.overlay.querySelector('.packshotphoto-modal');
        const body = modal.querySelector('.packshotphoto-modal-body');
        const actions = modal.querySelector('.packshotphoto-modal-actions');
        const title = modal.querySelector('.packshotphoto-modal-title');

        title.textContent = packshotphotoConfig.i18n.compareTitle || 'Compare';
        actions.innerHTML = `
            <button class="packshotphoto-btn packshotphoto-btn-secondary" id="packshotphoto-restore-btn" data-id="${data.id}" data-nonce="${data.nonce}">↩️ ${packshotphotoConfig.i18n.restore || 'Restore'}</button>
            <button class="packshotphoto-btn packshotphoto-btn-primary" onclick="this.closest('.packshotphoto-modal-overlay').classList.remove('active')">${packshotphotoConfig.i18n.close || 'Close'}</button>
        `;
        
        // Attach restore handler
        const restoreBtn = document.getElementById('packshotphoto-restore-btn');
        restoreBtn.addEventListener('click', handleRestoreOriginal);
        
        const savingsClass = data.after.savings > 0 ? 'packshotphoto-text-success' : 'packshotphoto-text-error';
        
        body.innerHTML = `
            <div class="packshotphoto-comparison-container">
                <div class="packshotphoto-comparison-slider">
                    <div class="packshotphoto-img-before" style="background-image: url('${data.before.url}')">
                        <span class="packshotphoto-label packshotphoto-label-before">Original (${data.before.size})</span>
                    </div>
                    <div class="packshotphoto-img-after" style="background-image: url('${data.after.url}'); clip-path: inset(0 0 0 50%)">
                        <span class="packshotphoto-label packshotphoto-label-after">Optimized (${data.after.size})</span>
                    </div>
                    <div class="packshotphoto-slider-handle" style="left: 50%">
                        <div class="packshotphoto-handle-line"></div>
                        <div class="packshotphoto-handle-circle">↔️</div>
                    </div>
                </div>
                <div class="packshotphoto-comparison-stats">
                    Savings:<strong class="${savingsClass}">${data.after.savings}%</strong> 
                    (${data.before.size} → ${data.after.size})
                </div>
            </div>
        `;

        modalManager.overlay.classList.add('active');

        // Init Slider Logic - using clip-path for proper overlay sliding
        const container = body.querySelector('.packshotphoto-comparison-slider');
        const beforeImg = body.querySelector('.packshotphoto-img-before');
        const afterImg = body.querySelector('.packshotphoto-img-after');
        const handle = body.querySelector('.packshotphoto-slider-handle');

        let isDragging = false;

        const move = (e) => {
            const rect = container.getBoundingClientRect();
            let x = (e.pageX || e.touches[0].pageX) - rect.left - window.scrollX;
            
            // Constrain
            if (x < 0) x = 0;
            if (x > rect.width) x = rect.width;

            const percentage = (x / rect.width) * 100;
            // Use clip-path instead of width - this overlays images properly
            afterImg.style.clipPath = `inset(0 0 0 ${percentage}%)`;
            handle.style.left = `${percentage}%`;
        };

        const start = (e) => {
            isDragging = true;
            move(e);
        };
        const stop = () => isDragging = false;

        // Allow clicking anywhere on the container to start dragging
        container.addEventListener('mousedown', start);
        container.addEventListener('touchstart', start, { passive: false });
        window.addEventListener('mousemove', move);
        window.addEventListener('touchmove', move, { passive: false });
        window.addEventListener('mouseup', stop);
        window.addEventListener('touchend', stop);
        
        // Final init call to ensure globals are set
        setTimeout(() => initComparisonSlider(), 50);
    }

    async function handleRestoreOriginal(e) {
        const btn = e.target.closest('#packshotphoto-restore-btn');
        if (!btn || btn.classList.contains('packshotphoto-loading')) return;
        
        if (!confirm(packshotphotoConfig.i18n.restoreConfirm || 'Are you sure you want to restore the original file? The current version will be replaced.')) {
            return;
        }

        const id = btn.dataset.id;
        const nonce = btn.dataset.nonce;

        btn.classList.add('packshotphoto-loading');
        const originalText = btn.textContent;
        btn.textContent = '⏳ Restoring...';

        try {
            const response = await fetch(packshotphotoConfig.ajaxUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    action: 'packshotphoto_restore_original',
                    id: id,
                    nonce: nonce
                })
            });

            const data = await response.json();

            if (data.success) {
                showToast(data.data.message || (packshotphotoConfig.i18n.restoredFile || 'Original file restored!'), 'success');
                modalManager.overlay.classList.remove('active');
                // Refresh the page after a short delay to show restored image
                setTimeout(() => location.reload(), 1000);
            } else {
                showToast(data.data.message || 'Error restoring', 'error');
                btn.classList.remove('packshotphoto-loading');
                btn.textContent = originalText;
            }
        } catch (error) {
            showToast(packshotphotoConfig.i18n.networkError || 'Connection error', 'error');
            btn.classList.remove('packshotphoto-loading');
            btn.textContent = originalText;
        }
    }

    function initDeactivationSurvey() {
        const deactivateBtn = document.querySelector('a#deactivate-pro-media-manager-lite') || 
                              document.querySelector('a[href*="action=deactivate"][href*="plugin=pro-media-manager-lite"]');
        if (!deactivateBtn) return;

        deactivateBtn.addEventListener('click', function (e) {
            e.preventDefault();
            const deactivationUrl = deactivateBtn.href;

            const modalHtml = `
                <p style="font-size:14px; margin-bottom:15px; color:#444;">
                    ${packshotphotoConfig.i18n.deactivateSurveyTitle}
                </p>
                <div class="packshotphoto-deactivate-options" style="margin-bottom: 15px;">
                    <label style="display:block; margin-bottom:8px; font-size:13px; cursor:pointer;">
                        <input type="radio" name="deactivate_reason" value="better_plugin" checked style="margin-right:8px;">
                        ${packshotphotoConfig.i18n.deactivateReason1}
                    </label>
                    <label style="display:block; margin-bottom:8px; font-size:13px; cursor:pointer;">
                        <input type="radio" name="deactivate_reason" value="broken_bugs" style="margin-right:8px;">
                        ${packshotphotoConfig.i18n.deactivateReason2}
                    </label>
                    <label style="display:block; margin-bottom:8px; font-size:13px; cursor:pointer;">
                        <input type="radio" name="deactivate_reason" value="hard_to_use" style="margin-right:8px;">
                        ${packshotphotoConfig.i18n.deactivateReason3}
                    </label>
                    <label style="display:block; margin-bottom:8px; font-size:13px; cursor:pointer;">
                        <input type="radio" name="deactivate_reason" value="temporary" style="margin-right:8px;">
                        ${packshotphotoConfig.i18n.deactivateReason4}
                    </label>
                    <label style="display:block; margin-bottom:8px; font-size:13px; cursor:pointer;">
                        <input type="radio" name="deactivate_reason" value="other" style="margin-right:8px;">
                        ${packshotphotoConfig.i18n.deactivateReason5}
                    </label>
                </div>
                <div class="packshotphoto-deactivate-details-wrapper" style="margin-top:10px; display:none;">
                    <textarea class="packshotphoto-deactivate-details" rows="3" placeholder="${packshotphotoConfig.i18n.deactivateReasonPlaceholder}" style="width:100%; padding:8px; border:1px solid #ccc; border-radius:4px; font-size:13px; resize:vertical;"></textarea>
                </div>
            `;

            modalManager.confirm({
                title: packshotphotoConfig.i18n.deactivateSurveyTitle,
                icon: '💬',
                message: modalHtml,
                buttons: [
                    { label: packshotphotoConfig.i18n.skipAndDeactivate, value: 'skip', class: 'packshotphoto-btn-secondary' },
                    { label: packshotphotoConfig.i18n.submitAndDeactivate, value: 'submit', class: 'packshotphoto-btn-primary' }
                ]
            }).then(result => {
                if (result.value === 'submit') {
                    const modal = modalManager.overlay;
                    const selectedRadio = modal.querySelector('input[name="deactivate_reason"]:checked');
                    const reason = selectedRadio ? selectedRadio.value : 'other';
                    const detailsInput = modal.querySelector('.packshotphoto-deactivate-details');
                    const details = detailsInput ? detailsInput.value.trim() : '';

                    sendDeactivationFeedback(reason, details).then(() => {
                        window.location.href = deactivationUrl;
                    });
                } else if (result.value === 'skip') {
                    window.location.href = deactivationUrl;
                }
            });

            // Toggle textarea visibility when "Other" or "It doesn't work" is selected
            const modal = modalManager.overlay;
            const radios = modal.querySelectorAll('input[name="deactivate_reason"]');
            const detailsWrapper = modal.querySelector('.packshotphoto-deactivate-details-wrapper');
            
            const updateDetailsVisibility = () => {
                const selected = modal.querySelector('input[name="deactivate_reason"]:checked')?.value;
                if (selected === 'other' || selected === 'broken_bugs') {
                    detailsWrapper.style.display = 'block';
                } else {
                    detailsWrapper.style.display = 'none';
                }
            };

            radios.forEach(radio => radio.addEventListener('change', updateDetailsVisibility));
            updateDetailsVisibility(); // run once initially
        });
    }

    function sendDeactivationFeedback(reason, details) {
        return fetch(packshotphotoConfig.ajaxUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: new URLSearchParams({
                action: 'packshotphoto_log_deactivation_survey',
                nonce: packshotphotoConfig.nonce,
                reason: reason,
                details: details
            }),
        }).catch(err => {
            console.error('Error logging deactivation survey', err);
        });
    }

    // ===== SESSION LOG (CSV SPREADSHEET) =====

    function getSessionLog() {
        try {
            const data = sessionStorage.getItem('packshotphoto_session_log');
            return data ? JSON.parse(data) : [];
        } catch (e) {
            return [];
        }
    }

    function saveSessionLog(log) {
        try {
            sessionStorage.setItem('packshotphoto_session_log', JSON.stringify(log));
        } catch (e) {}
    }

    function addSessionLogEntry(entry) {
        const log = getSessionLog();
        const now = new Date().toISOString().replace('T', ' ').substring(0, 19);
        log.push({
            datetime: now,
            id: entry.id,
            original_filename: entry.original_filename || '-',
            new_filename: entry.new_filename || '-',
            action: entry.action || '-',
            status: entry.status || '-',
            original_size: entry.original_size || '-',
            new_size: entry.new_size || '-',
            savings: entry.savings || '-',
            width_change: entry.width_change || '-',
            height_change: entry.height_change || '-',
            alt: entry.alt || '-',
            caption: entry.caption || '-',
            message: entry.message || '-'
        });
        saveSessionLog(log);
        updateLogNotification();
    }

    // Export so upload panel can use it
    window.packshotphotoAddLogEntry = addSessionLogEntry;

    function downloadSessionLogCSV() {
        const log = getSessionLog();
        if (!log.length) return;

        // Escape CSV fields
        const escapeCSV = (val) => {
            if (val === null || val === undefined) return '';
            let str = String(val);
            if (str.includes(',') || str.includes('"') || str.includes('\n')) {
                str = str.replace(/"/g, '""');
                return '"' + str + '"';
            }
            return str;
        };

        const headers = [
            'Date/Time',
            'Attachment ID',
            'Original Filename',
            'New Filename',
            'Action',
            'Status',
            'Original Size',
            'New Size',
            'Savings',
            'Width Change',
            'Height Change',
            'AI Alt Text',
            'AI Caption',
            'Message/Error'
        ];
        const csvRows = [headers.join(',')];

        log.forEach(row => {
            const line = [
                escapeCSV(row.datetime),
                escapeCSV(row.id),
                escapeCSV(row.original_filename),
                escapeCSV(row.new_filename),
                escapeCSV(row.action),
                escapeCSV(row.status),
                escapeCSV(row.original_size),
                escapeCSV(row.new_size),
                escapeCSV(row.savings),
                escapeCSV(row.width_change),
                escapeCSV(row.height_change),
                escapeCSV(row.alt),
                escapeCSV(row.caption),
                escapeCSV(row.message)
            ];
            csvRows.push(line.join(','));
        });

        const csvContent = "\uFEFF" + csvRows.join('\n'); // UTF-8 BOM for Excel
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.setAttribute('href', url);
        link.setAttribute('download', 'packshotphoto-process-log-' + new Date().toISOString().slice(0,10) + '.csv');
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }

    function updateLogNotification() {
        const log = getSessionLog();
        if (!log.length) return;

        // 1. Remove old notice if exists
        const oldNotice = document.querySelector('.packshotphoto-csv-log-notice');
        if (oldNotice) oldNotice.remove();

        // 2. Build the notice markup
        const notice = document.createElement('div');
        notice.className = 'notice notice-info is-dismissible packshotphoto-csv-log-notice';
        notice.style.marginTop = '15px';
        notice.style.display = 'flex';
        notice.style.alignItems = 'center';
        notice.style.justifyContent = 'space-between';
        notice.style.padding = '10px 15px';
        notice.style.borderLeft = '4px solid #72aee6';
        notice.style.backgroundColor = '#fff';
        notice.style.boxShadow = '0 1px 1px 0 rgba(0,0,0,.1)';

        const textSpan = document.createElement('span');
        textSpan.innerHTML = '📊 <strong>PackshotPhoto AI:</strong> Processed <strong>' + log.length + '</strong> items in this session.';

        const actionDiv = document.createElement('div');
        actionDiv.style.display = 'flex';
        actionDiv.style.gap = '10px';

        const downloadBtn = document.createElement('button');
        downloadBtn.type = 'button';
        downloadBtn.className = 'button button-primary button-small';
        downloadBtn.textContent = 'Download Excel/CSV Log';
        downloadBtn.addEventListener('click', downloadSessionLogCSV);

        const clearBtn = document.createElement('button');
        clearBtn.type = 'button';
        clearBtn.className = 'button button-link button-small';
        clearBtn.style.color = '#d63638';
        clearBtn.style.textDecoration = 'none';
        clearBtn.textContent = 'Clear Log';
        clearBtn.addEventListener('click', () => {
            sessionStorage.removeItem('packshotphoto_session_log');
            notice.remove();
        });

        actionDiv.appendChild(downloadBtn);
        actionDiv.appendChild(clearBtn);
        notice.appendChild(textSpan);
        notice.appendChild(actionDiv);

        // 3. Insert notice depending on page
        const uploadWrap = document.querySelector('.wrap');
        if (uploadWrap) {
            const h1 = uploadWrap.querySelector('h1');
            if (h1) {
                h1.after(notice);
            } else {
                uploadWrap.prepend(notice);
            }
        }
    }

    function initEuAiAct() {
        // 1. Column Button Click Handler (Media Library & Single views)
        document.addEventListener('click', async function (e) {
            const btn = e.target.closest('.packshotphoto-eu-ai-btn');
            if (!btn) return;
            e.preventDefault();

            const id = btn.dataset.id;
            const nonce = btn.dataset.nonce || packshotphotoConfig.nonce;

            btn.disabled = true;
            btn.classList.add('packshotphoto-loading');

            console.log('[PMM EU AI] Sending stamp request for ID:', id, 'nonce:', nonce);

            try {
                const response = await fetch(packshotphotoConfig.ajaxUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: new URLSearchParams({
                        action: 'packshotphoto_apply_eu_ai_label',
                        id: id,
                        nonce: nonce
                    })
                });

                console.log('[PMM EU AI] Response status:', response.status);
                const data = await response.json();
                console.log('[PMM EU AI] Response data:', JSON.stringify(data));

                if (data.success) {
                    const msg = data.data && data.data.message ? data.data.message : 'Oznaczono znakiem EU AI Act!';
                    showToast(msg, 'success');

                    // If restore button was hidden in this row, show it
                    const row = btn.closest('tr') || btn.closest('.packshotphoto-upload-item-dashboard') || document.querySelector('#post-' + id);
                    if (row) {
                        const restoreBtn = row.querySelector('.packshotphoto-restore-btn');
                        if (restoreBtn) restoreBtn.style.display = 'inline-block';
                        
                        // Force refresh all thumbnail images in this row with cache busting & clear srcset
                        row.querySelectorAll('.column-primary img, .media-icon img, .thumbnail img').forEach(img => {
                            if (img) {
                                img.removeAttribute('srcset');
                                const newSrc = (data.data && data.data.thumb_url) ? data.data.thumb_url : ((data.data && data.data.file_url) ? data.data.file_url : (img.src ? img.src.split('?')[0] : ''));
                                if (newSrc) {
                                    img.src = newSrc + (newSrc.includes('?') ? '&' : '?') + 't=' + Date.now();
                                }
                            }
                        });
                    }

                    // Add to session log
                    let filename = 'ID ' + id;
                    if (row) {
                        const titleEl = row.querySelector('.title a, .row-title');
                        if (titleEl) filename = titleEl.textContent.trim();
                    }

                    if (typeof addSessionLogEntry === 'function') {
                        addSessionLogEntry({
                            id: id,
                            original_filename: filename,
                            new_filename: filename,
                            action: 'EU_AI_STAMP',
                            status: 'Success',
                            original_size: '-',
                            new_size: '-',
                            savings: '-',
                            width_change: '-',
                            height_change: '-',
                            alt: '-',
                            caption: '-',
                            message: msg
                        });
                    }
                } else {
                    console.error('[PMM EU AI] FAILED:', data);
                    showToast(getErrorMessage(data), 'error');
                }
            } catch (err) {
                console.error('[PMM EU AI] Exception:', err);
                showToast(packshotphotoConfig.i18n.error || 'Error', 'error');
            } finally {
                btn.disabled = false;
                btn.classList.remove('packshotphoto-loading');
            }
        });

        // 2. Settings Page Interactivity (Live Preview, Mode Selector, Media Picker)
        initEuAiSettingsInteractivity();
    }

    function initEuAiSettingsInteractivity() {
        const toggleBtn        = document.getElementById('packshotphoto-toggle-eu-ai-customization');
        const customPanel      = document.getElementById('packshotphoto-eu-ai-customization-panel');
        const toggleArrow      = document.getElementById('packshotphoto-toggle-eu-ai-arrow');
        const presetsContainer = document.getElementById('packshotphoto-eu-ai-presets-container');
        const customContainer  = document.getElementById('packshotphoto-eu-ai-custom-container');
        const previewStamp      = document.getElementById('packshotphoto-preview-stamp');
        const previewBox        = document.getElementById('packshotphoto-live-preview-box');
        const scaleSlider       = document.getElementById('packshotphoto_eu_ai_scale');
        const scaleValSpan      = document.getElementById('packshotphoto-scale-val');
        const opacitySlider     = document.getElementById('packshotphoto_eu_ai_opacity');
        const opacityValSpan    = document.getElementById('packshotphoto-opacity-val');
        const customInput       = document.getElementById('packshotphoto_eu_ai_custom_image');
        const uploadBtn         = document.getElementById('packshotphoto-upload-custom-badge');
        const clearBtn          = document.getElementById('packshotphoto-clear-custom-badge');
        const customPreviewBox  = document.getElementById('packshotphoto-custom-image-preview');

        const padTopInput       = document.getElementById('packshotphoto_eu_ai_padding_top');
        const padRightInput     = document.getElementById('packshotphoto_eu_ai_padding_right');
        const padBottomInput    = document.getElementById('packshotphoto_eu_ai_padding_bottom');
        const padLeftInput      = document.getElementById('packshotphoto_eu_ai_padding_left');

        // Collapsible Accordion Toggle
        if (toggleBtn && customPanel) {
            toggleBtn.addEventListener('click', function (e) {
                e.preventDefault();
                const isHidden = (customPanel.style.display === 'none' || customPanel.style.display === '');
                if (isHidden) {
                    customPanel.style.display = 'block';
                    if (toggleArrow) {
                        toggleArrow.classList.remove('dashicons-arrow-down-alt2');
                        toggleArrow.classList.add('dashicons-arrow-up-alt2');
                    }
                } else {
                    customPanel.style.display = 'none';
                    if (toggleArrow) {
                        toggleArrow.classList.remove('dashicons-arrow-up-alt2');
                        toggleArrow.classList.add('dashicons-arrow-down-alt2');
                    }
                }
            });
        }

        if (!previewStamp || !previewBox) return;

        // Update live preview placement & styling
        const updateLivePreview = () => {
            const mode = document.querySelector('input[name="packshotphoto_eu_ai_mode"]:checked')?.value || 'preset';
            const scale = scaleSlider ? parseInt(scaleSlider.value, 10) : 15;
            const opacity = opacitySlider ? parseInt(opacitySlider.value, 10) : 100;
            const pos = document.querySelector('input[name="packshotphoto_eu_ai_position"]:checked')?.value || 'bottom-right';

            const padTop    = padTopInput ? Math.max(0, parseInt(padTopInput.value, 10) || 15) : 15;
            const padRight  = padRightInput ? Math.max(0, parseInt(padRightInput.value, 10) || 15) : 15;
            const padBottom = padBottomInput ? Math.max(0, parseInt(padBottomInput.value, 10) || 15) : 15;
            const padLeft   = padLeftInput ? Math.max(0, parseInt(padLeftInput.value, 10) || 15) : 15;

            // Source image
            if (mode === 'custom' && customInput && customInput.value) {
                previewStamp.src = customInput.value;
            } else {
                const activeCard = document.querySelector('.packshotphoto-preset-card.selected') || document.querySelector('.packshotphoto-preset-card');
                if (activeCard && activeCard.dataset.url) {
                    previewStamp.src = activeCard.dataset.url;
                }
            }

            // Scale & Opacity
            previewStamp.style.width = Math.max(10, Math.min(80, scale * 1.5)) + '%';
            previewStamp.style.opacity = (opacity / 100).toString();

            // Position with scaled padding for small preview box (ratio ~0.2)
            previewStamp.style.top = 'auto';
            previewStamp.style.bottom = 'auto';
            previewStamp.style.left = 'auto';
            previewStamp.style.right = 'auto';
            previewStamp.style.transform = 'none';

            const pTop    = Math.max(2, Math.round(padTop * 0.25)) + 'px';
            const pRight  = Math.max(2, Math.round(padRight * 0.25)) + 'px';
            const pBottom = Math.max(2, Math.round(padBottom * 0.25)) + 'px';
            const pLeft   = Math.max(2, Math.round(padLeft * 0.25)) + 'px';

            switch (pos) {
                case 'top-left':
                    previewStamp.style.top = pTop;
                    previewStamp.style.left = pLeft;
                    break;
                case 'top-right':
                    previewStamp.style.top = pTop;
                    previewStamp.style.right = pRight;
                    break;
                case 'bottom-left':
                    previewStamp.style.bottom = pBottom;
                    previewStamp.style.left = pLeft;
                    break;
                case 'center':
                    previewStamp.style.top = '50%';
                    previewStamp.style.left = '50%';
                    previewStamp.style.transform = 'translate(-50%, -50%)';
                    break;
                case 'bottom-right':
                default:
                    previewStamp.style.bottom = pBottom;
                    previewStamp.style.right = pRight;
                    break;
            }
        };

        // Padding input listeners
        [padTopInput, padRightInput, padBottomInput, padLeftInput].forEach(input => {
            if (input) {
                input.addEventListener('input', updateLivePreview);
            }
        });

        // Mode switch
        document.querySelectorAll('.packshotphoto-eu-ai-mode-radio').forEach(radio => {
            radio.addEventListener('change', function () {
                if (this.value === 'preset') {
                    if (presetsContainer) presetsContainer.style.display = 'block';
                    if (customContainer) customContainer.style.display = 'none';
                } else {
                    if (presetsContainer) presetsContainer.style.display = 'none';
                    if (customContainer) customContainer.style.display = 'block';
                }
                updateLivePreview();
            });
        });

        // Preset card clicks
        document.querySelectorAll('.packshotphoto-preset-card').forEach(card => {
            card.addEventListener('click', function () {
                document.querySelectorAll('.packshotphoto-preset-card').forEach(c => {
                    c.classList.remove('selected');
                    c.style.borderColor = c.dataset.key.indexOf('white') !== -1 ? '#334155' : '#cbd5e1';
                });
                card.classList.add('selected');
                card.style.borderColor = '#2271b1';
                const radio = card.querySelector('input[type="radio"]');
                if (radio) radio.checked = true;
                updateLivePreview();
            });
        });

        // Position buttons
        document.querySelectorAll('.packshotphoto-pos-btn').forEach(btn => {
            btn.addEventListener('click', function () {
                document.querySelectorAll('.packshotphoto-pos-btn').forEach(b => {
                    b.classList.remove('active');
                    b.style.background = '#ffffff';
                    b.style.borderColor = '#cbd5e1';
                    b.style.color = '#334155';
                });
                btn.classList.add('active');
                btn.style.background = '#2271b1';
                btn.style.borderColor = '#2271b1';
                btn.style.color = '#ffffff';
                const radio = btn.querySelector('input[type="radio"]');
                if (radio) radio.checked = true;
                updateLivePreview();
            });
        });

        // Sliders
        if (scaleSlider) {
            scaleSlider.addEventListener('input', function () {
                if (scaleValSpan) scaleValSpan.textContent = this.value + '%';
                updateLivePreview();
            });
        }

        if (opacitySlider) {
            opacitySlider.addEventListener('input', function () {
                if (opacityValSpan) opacityValSpan.textContent = this.value + '%';
                updateLivePreview();
            });
        }

        // Custom Image Upload via WordPress Media Frame
        if (uploadBtn && customInput) {
            let customMediaFrame;
            uploadBtn.addEventListener('click', function (e) {
                e.preventDefault();
                if (customMediaFrame) {
                    customMediaFrame.open();
                    return;
                }

                customMediaFrame = wp.media({
                    title: 'Wybierz grafikę znaku wodnego / etykiety',
                    button: { text: 'Użyj jako znak wodny' },
                    library: { type: 'image' },
                    multiple: false
                });

                customMediaFrame.on('select', function () {
                    const attachment = customMediaFrame.state().get('selection').first().toJSON();
                    customInput.value = attachment.url;
                    if (customPreviewBox) {
                        customPreviewBox.innerHTML = '<img src="' + attachment.url + '" style="max-width:100%; max-height:100%; object-fit:contain;" alt="Custom watermark preview">';
                    }
                    if (clearBtn) clearBtn.style.display = 'inline-block';
                    updateLivePreview();
                });

                customMediaFrame.open();
            });
        }

        // Clear custom image
        if (clearBtn && customInput) {
            clearBtn.addEventListener('click', function (e) {
                e.preventDefault();
                customInput.value = '';
                if (customPreviewBox) {
                    customPreviewBox.innerHTML = '<span style="font-size:24px; color:#94a3b8;">🖼️</span>';
                }
                clearBtn.style.display = 'none';
                updateLivePreview();
            });
        }

        // Manual text input on custom image url
        if (customInput) {
            customInput.addEventListener('input', function () {
                if (this.value) {
                    if (customPreviewBox) {
                        customPreviewBox.innerHTML = '<img src="' + this.value + '" style="max-width:100%; max-height:100%; object-fit:contain;" alt="Custom watermark preview">';
                    }
                    if (clearBtn) clearBtn.style.display = 'inline-block';
                } else {
                    if (customPreviewBox) {
                        customPreviewBox.innerHTML = '<span style="font-size:24px; color:#94a3b8;">🖼️</span>';
                    }
                    if (clearBtn) clearBtn.style.display = 'none';
                }
                updateLivePreview();
            });
        }

        // Run initial live preview setup
        updateLivePreview();
    }

    // Wait for DOM (fully declared context to avoid temporal dead zone)
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();
