/**
 * Admin feature components: TinyMCE, user edit, verify modal, scroll sync, etc.
 */
import Alpine from '@alpinejs/csp';

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

// TinyMCE editor (loads from CDN, remains imperative)
Alpine.data('tinyMceEditor', () => ({
    init() {
        if (!document.getElementById('body') && !document.querySelector('.tinymce-editor')) return;
        this._loadAndInit();
    },

    _loadAndInit() {
        if (typeof tinymce !== 'undefined') { this._doInit(); return; }
        const body = document.getElementById('body');
        const editors = document.querySelectorAll('.tinymce-editor');
        let apiKey = 'no-api-key';
        const meta = document.querySelector('meta[name="tinymce-api-key"]');
        if (meta) { apiKey = meta.content; }
        else if (window.NNTmuxConfig?.tinymceApiKey) apiKey = window.NNTmuxConfig.tinymceApiKey;
        else if (body?.dataset.tinymceApiKey) apiKey = body.dataset.tinymceApiKey;
        else { for (let e of editors) { if (e.dataset.tinymceApiKey) { apiKey = e.dataset.tinymceApiKey; break; } } }

        const script = document.createElement('script');
        script.src = 'https://cdn.tiny.cloud/1/' + apiKey + '/tinymce/8/tinymce.min.js';
        script.referrerPolicy = 'origin';
        // Add CSP nonce for Content Security Policy compliance
        const nonceMeta = document.querySelector('meta[name="csp-nonce"]');
        if (nonceMeta) {
            script.nonce = nonceMeta.content;
        }
        script.onload = () => this._doInit();
        script.onerror = () => {
            document.querySelectorAll('#body, .tinymce-editor').forEach(ta => {
                if (ta.parentElement) {
                    const err = document.createElement('div');
                    err.className = 'mt-2 p-3 bg-red-50 dark:bg-red-900 border border-red-200 dark:border-red-700 text-red-800 dark:text-red-200 rounded';
                    err.innerHTML = '<i class="fas fa-exclamation-triangle mr-2"></i>TinyMCE editor failed to load.';
                    ta.parentElement.insertBefore(err, ta.nextSibling);
                }
            });
        };
        document.head.appendChild(script);
    },

    _doInit() {
        const dark = document.documentElement.classList.contains('dark');
        tinymce.init({
            selector: '#body, .tinymce-editor', height: 500, menubar: true,
            skin: dark ? 'oxide-dark' : 'oxide', content_css: dark ? 'dark' : 'default',
            plugins: ['advlist','autolink','lists','link','image','charmap','preview','anchor','searchreplace','visualblocks','code','fullscreen','insertdatetime','media','table','help','wordcount','emoticons'],
            toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table emoticons | removeformat code fullscreen | help',
            toolbar_mode: 'sliding', content_style: 'body { font-family: Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.6; }',
            branding: false, promotion: false, resize: true, statusbar: true, valid_elements: '*[*]', extended_valid_elements: '*[*]',
            setup: function(editor) { editor.on('change blur keyup submit', function() { editor.save(); }); }
        });

        // Watch dark mode changes to reinit TinyMCE
        new MutationObserver(() => {
            if (!tinymce.editors.length) return;
            const contents = {};
            tinymce.editors.forEach(e => { contents[e.id] = e.getContent(); });
            tinymce.remove();
            const d = document.documentElement.classList.contains('dark');
            tinymce.init({
                selector: '#body, .tinymce-editor', height: 500, menubar: true,
                skin: d ? 'oxide-dark' : 'oxide', content_css: d ? 'dark' : 'default',
                plugins: ['advlist','autolink','lists','link','image','charmap','preview','anchor','searchreplace','visualblocks','code','fullscreen','insertdatetime','media','table','help','wordcount','emoticons'],
                toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table emoticons | removeformat code fullscreen | help',
                toolbar_mode: 'sliding', branding: false, promotion: false, valid_elements: '*[*]', extended_valid_elements: '*[*]',
                setup: function(editor) { editor.on('change blur keyup submit', function() { editor.save(); }); }
            }).then(eds => { eds.forEach(e => { if (contents[e.id]) e.setContent(contents[e.id]); }); });
        }).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
    }
}));

// User Edit datetime picker
Alpine.data('adminUserEdit', () => ({
    init() {
        if (!document.getElementById('rolechangedate')) return;
        this._initDateTime();
        this._setupExpiry();
    },

    _initDateTime() {
        const hidden = document.getElementById('rolechangedate');
        if (!hidden?.value) return;
        const d = new Date(hidden.value);
        if (isNaN(d.getTime())) return;
        this._setSelects(d);
        this._updatePreview();
    },

    _setSelects(d) {
        const ids = ['expiry_year','expiry_month','expiry_day','expiry_hour','expiry_minute'];
        const vals = [d.getFullYear().toString(), String(d.getMonth()+1).padStart(2,'0'), String(d.getDate()).padStart(2,'0'), String(d.getHours()).padStart(2,'0'), String(d.getMinutes()).padStart(2,'0')];
        ids.forEach((id, i) => { const el = document.getElementById(id); if (el) el.value = vals[i]; });
    },

    updateDateTime() {
        const y = document.getElementById('expiry_year')?.value;
        const mo = document.getElementById('expiry_month')?.value;
        const d = document.getElementById('expiry_day')?.value;
        const h = document.getElementById('expiry_hour')?.value;
        const mi = document.getElementById('expiry_minute')?.value;
        if (y && mo && d && h && mi) {
            document.getElementById('rolechangedate').value = y + '-' + mo + '-' + d + 'T' + h + ':' + mi + ':00';
            this._updatePreview();
        }
    },

    updateValidDays() {
        const y = parseInt(document.getElementById('expiry_year')?.value);
        const m = parseInt(document.getElementById('expiry_month')?.value);
        const daySelect = document.getElementById('expiry_day');
        if (!y || !m || !daySelect) return;
        const days = new Date(y, m, 0).getDate();
        const cur = parseInt(daySelect.value);
        daySelect.innerHTML = '<option value="">--</option>';
        for (let i = 1; i <= days; i++) { const o = document.createElement('option'); o.value = String(i).padStart(2,'0'); o.textContent = i; daySelect.appendChild(o); }
        if (cur && cur <= days) daySelect.value = String(cur).padStart(2,'0');
    },

    setExpiry(days, hours) {
        let base;
        const y = document.getElementById('expiry_year')?.value;
        const mo = document.getElementById('expiry_month')?.value;
        const d = document.getElementById('expiry_day')?.value;
        const h = document.getElementById('expiry_hour')?.value;
        const mi = document.getElementById('expiry_minute')?.value;
        const orig = document.getElementById('original_user_expiry')?.value;
        if (y && mo && d && h && mi) base = new Date(y, parseInt(mo)-1, d, h, mi);
        else if (orig) base = new Date(orig);
        else base = new Date();
        base.setDate(base.getDate() + days);
        base.setHours(base.getHours() + hours);
        this._setSelects(base);
        this.updateValidDays();
        this.updateDateTime();
    },

    setEndOfDay() {
        const d = new Date(); d.setHours(23,59,0,0);
        this._setSelects(d);
        this.updateValidDays();
        this.updateDateTime();
    },

    clearExpiry() {
        ['expiry_year','expiry_month','expiry_day','expiry_hour','expiry_minute'].forEach(id => { const el = document.getElementById(id); if (el) el.value = ''; });
        document.getElementById('rolechangedate').value = '';
        const p = document.getElementById('datetime_preview'); if (p) p.classList.add('hidden');
    },

    _setupExpiry() {
        ['expiry_year','expiry_month','expiry_day','expiry_hour','expiry_minute'].forEach(id => {
            const el = document.getElementById(id);
            if (el) el.addEventListener('change', () => this.updateDateTime());
        });
        const y = document.getElementById('expiry_year'), m = document.getElementById('expiry_month');
        if (y) y.addEventListener('change', () => this.updateValidDays());
        if (m) m.addEventListener('change', () => this.updateValidDays());

        // Setup quick action buttons
        document.querySelectorAll('[data-expiry-action]').forEach(btn => {
            btn.addEventListener('click', () => {
                const action = btn.dataset.expiryAction;
                if (action === 'set') {
                    const days = parseInt(btn.dataset.days) || 0;
                    const hours = parseInt(btn.dataset.hours) || 0;
                    this.setExpiry(days, hours);
                } else if (action === 'end-of-day') {
                    this.setEndOfDay();
                } else if (action === 'clear') {
                    this.clearExpiry();
                }
            });
        });
    },

    _updatePreview() {
        const hidden = document.getElementById('rolechangedate');
        const preview = document.getElementById('datetime_preview');
        const display = document.getElementById('datetime_display');
        if (!hidden?.value || !preview || !display) { if (preview) preview.classList.add('hidden'); return; }
        const d = new Date(hidden.value);
        display.textContent = d.toLocaleDateString('en-US', { weekday:'short', year:'numeric', month:'long', day:'numeric', hour:'2-digit', minute:'2-digit' });
        preview.classList.remove('hidden');
        const diff = d - new Date();
        display.classList.remove('text-red-600','dark:text-red-400','text-yellow-600','dark:text-yellow-400','text-blue-600','dark:text-blue-400');
        if (diff < 0) display.classList.add('text-red-600','dark:text-red-400');
        else if (diff < 7*24*60*60*1000) display.classList.add('text-yellow-600','dark:text-yellow-400');
        else display.classList.add('text-blue-600','dark:text-blue-400');
    }
}));

// Admin deleted users
Alpine.data('adminDeletedUsers', () => ({
    allChecked: false,

    toggleAll() {
        this.$el.querySelectorAll('.user-checkbox').forEach(cb => { cb.checked = this.allChecked; });
    },

    onCheckboxChange() {
        const all = this.$el.querySelectorAll('.user-checkbox');
        const checked = this.$el.querySelectorAll('.user-checkbox:checked');
        this.allChecked = all.length > 0 && checked.length === all.length;
    },

    submitBulkAction(e) {
        e.preventDefault();
        const action = this.$el.querySelector('#bulkAction')?.value;
        const checked = this.$el.querySelectorAll('.user-checkbox:checked');
        const errEl = document.getElementById('validationError');
        const errMsg = document.getElementById('validationErrorMessage');
        if (errEl) errEl.classList.add('hidden');

        if (!action) { if (errEl && errMsg) { errMsg.textContent = 'Please select an action.'; errEl.classList.remove('hidden'); } return; }
        if (checked.length === 0) { if (errEl && errMsg) { errMsg.textContent = 'Please select at least one user.'; errEl.classList.remove('hidden'); } return; }

        const text = action === 'restore' ? 'restore' : 'permanently delete';
        const type = action === 'restore' ? 'success' : 'danger';
        const form = this.$el.querySelector('#bulkActionForm');

        showConfirm({
            title: action === 'restore' ? 'Restore Users' : 'Delete Users',
            message: 'Are you sure you want to ' + text + ' ' + checked.length + ' user(s)?',
            type: type,
            confirmText: action === 'restore' ? 'Restore' : 'Delete',
            onConfirm: function() { if (form) form.submit(); }
        });
    },

    restoreUser(userId, username) {
        showConfirm({ title: 'Restore User', message: "Are you sure you want to restore user '" + username + "'?", type: 'success', confirmText: 'Restore', onConfirm: function() {
            const form = document.getElementById('individualActionForm');
            if (form) { form.action = window.location.origin + '/admin/deleted-users/restore/' + userId; form.submit(); }
        }});
    },

    deleteUser(userId, username) {
        showConfirm({ title: 'Permanently Delete User', message: "Are you sure you want to PERMANENTLY delete user '" + username + "'?", details: 'This action cannot be undone!', type: 'danger', confirmText: 'Delete Permanently', onConfirm: function() {
            const form = document.getElementById('individualActionForm');
            if (form) { form.action = window.location.origin + '/admin/deleted-users/permanent-delete/' + userId; form.submit(); }
        }});
    }
}));

// Invitations select all
Alpine.data('adminInvitations', () => ({
    allChecked: false,
    toggleAll() { this.$el.querySelectorAll('.invitation-checkbox').forEach(cb => { cb.checked = this.allChecked; }); },
    onCheckboxChange() {
        const all = this.$el.querySelectorAll('.invitation-checkbox');
        const checked = this.$el.querySelectorAll('.invitation-checkbox:checked');
        this.allChecked = all.length > 0 && checked.length === all.length;
    }
}));

// Regex form validation
Alpine.data('adminRegexForm', () => ({
    validate(e) {
        const inputs = this.$el.querySelectorAll('input[name*="regex"], textarea[name*="regex"]');
        let valid = true;
        inputs.forEach(input => {
            const val = input.value.trim();
            if (val && input.hasAttribute('required')) {
                const delims = ['/','/','#','~','%','@','!'];
                if (delims.includes(val[0])) {
                    let found = false;
                    for (let i = 1; i < val.length; i++) { if (val[i] === val[0]) { found = true; break; } }
                    if (!found) { valid = false; input.classList.add('border-red-500'); }
                    else input.classList.remove('border-red-500');
                }
            }
        });
        if (!valid) { e.preventDefault(); showToast('Please fix regex validation errors', 'error'); }
    }
}));

// Tmux crap types toggle
Alpine.data('tmuxEdit', () => ({
    customCrap: false,
    init() {
        const checked = document.querySelector('input[name="fix_crap_opt"]:checked');
        if (checked) this.customCrap = checked.value === 'Custom';
    },
    setCrapOpt(value) { this.customCrap = value === 'Custom'; }
}));

// Image fallbacks (global)
Alpine.data('imageFallback', () => ({
    onError(e) {
        const fallback = e.target.getAttribute('data-fallback-src');
        if (fallback && e.target.src !== fallback) e.target.src = fallback;
    }
}));

// Select redirect
Alpine.data('selectRedirect', () => ({
    onChange(e) {
        const url = e.target.value;
        if (url && url !== '#') window.location.href = url;
    }
}));

// Confirm delete (link or form)
Alpine.data('confirmAction', () => ({
    confirmDelete(e, message) {
        e.preventDefault();
        e.stopPropagation();
        const el = e.currentTarget;
        const form = el.closest('form');
        showConfirm({
            message: message || 'Are you sure you want to delete this item?',
            type: 'danger',
            confirmText: 'Delete',
            onConfirm: function() { if (form) form.submit(); else if (el.href) window.location.href = el.href; }
        });
    }
}));

// Download NZB toast
Alpine.data('downloadNzb', () => ({
    onClick() { showToast('Downloading NZB...', 'success'); }
}));

// Logout
Alpine.data('logout', () => ({
    submit(e) {
        e.preventDefault();
        const form = document.getElementById('logout-form') || document.getElementById('sidebar-logout-form');
        if (form) form.submit();
    }
}));

// Promotion toggle/delete
Alpine.data('promotionAction', () => ({
    togglePromotion(e, name, isActive, href) {
        e.preventDefault();
        const action = isActive ? 'deactivate' : 'activate';
        showConfirm({
            title: action.charAt(0).toUpperCase() + action.slice(1) + ' Promotion',
            message: 'Are you sure you want to ' + action + ' the promotion "' + name + '"?',
            type: isActive ? 'warning' : 'success',
            confirmText: action.charAt(0).toUpperCase() + action.slice(1),
            onConfirm: function() { window.location.href = href; }
        });
    },
    deletePromotion(e, name) {
        e.preventDefault();
        const form = e.currentTarget.closest('form');
        showConfirm({
            title: 'Delete Promotion',
            message: 'Are you sure you want to delete the promotion "' + name + '"?',
            details: 'This action cannot be undone.',
            type: 'danger',
            confirmText: 'Delete',
            onConfirm: function() { if (form) form.submit(); }
        });
    }
}));

// Binary blacklist
Alpine.data('binaryBlacklist', () => ({
    deleteBlacklist(e, id) {
        e.preventDefault();
        if (confirm('Are you sure? This will delete the blacklist from this list.')) {
            if (typeof ajax_binaryblacklist_delete === 'function') ajax_binaryblacklist_delete(id);
        }
    }
}));

// Regex delete
Alpine.data('regexDelete', () => ({
    deleteRegex(e, id, deleteUrl) {
        e.preventDefault();
        if (confirm('Are you sure you want to delete this regex? This action cannot be undone.')) {
            const csrf = document.querySelector('meta[name="csrf-token"]')?.content;
            fetch(deleteUrl + '?id=' + id, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrf } })
            .then(r => r.json())
            .then(d => {
                if (d.success) { const row = document.getElementById('row-' + id); if (row) { row.style.transition = 'opacity 0.3s'; row.style.opacity = '0'; setTimeout(() => row.remove(), 300); } showToast('Regex deleted successfully', 'success'); }
                else showToast('Error deleting regex', 'error');
            }).catch(() => showToast('Error deleting regex', 'error'));
        }
    }
}));

// My Movies confirm
Alpine.data('myMovies', () => ({
    confirmRemove(e) {
        if (!confirm('Are you sure you want to remove this movie from your watchlist?')) e.preventDefault();
    }
}));

/**
 * Document-level delegation for admin and global UI handlers.
 * Replaces event-bridge.js; keeps delegation for elements that may not have x-data.
 */
(function() {
    // --- Click delegation ---
    document.addEventListener('click', function(e) {
        // Admin menu submenu toggle
        var menuToggle = e.target.closest('[data-toggle-submenu]');
        if (menuToggle) {
            var menuId = menuToggle.getAttribute('data-toggle-submenu');
            if (menuId) {
                var submenu = document.getElementById(menuId);
                var icon = document.getElementById(menuId + '-icon');
                if (submenu) submenu.classList.toggle('hidden');
                if (icon) icon.classList.toggle('rotate-180');
            }
            return;
        }

        // Admin groups data-action delegation
        var actionTarget = e.target.closest('[data-action]');
        if (actionTarget) {
            var action = actionTarget.dataset.action;
            var groupId = actionTarget.dataset.groupId;
            var status = actionTarget.dataset.status;
            switch (action) {
                case 'show-reset-modal': if (typeof showResetAllModal === 'function') showResetAllModal(); break;
                case 'hide-reset-modal': if (typeof hideResetAllModal === 'function') hideResetAllModal(); break;
                case 'show-purge-modal': if (typeof showPurgeAllModal === 'function') showPurgeAllModal(); break;
                case 'hide-purge-modal': if (typeof hidePurgeAllModal === 'function') hidePurgeAllModal(); break;
                case 'show-reset-selected-modal': if (typeof showResetSelectedModal === 'function') showResetSelectedModal(); break;
                case 'hide-reset-selected-modal': if (typeof hideResetSelectedModal === 'function') hideResetSelectedModal(); break;
                case 'select-all-groups': if (typeof toggleSelectAllGroups === 'function') toggleSelectAllGroups(actionTarget); break;
                case 'toggle-group-status': if (typeof ajax_group_status === 'function') ajax_group_status(groupId, status); break;
                case 'toggle-backfill': if (typeof ajax_backfill_status === 'function') ajax_backfill_status(groupId, status); break;
                case 'reset-group': if (typeof ajax_group_reset === 'function') ajax_group_reset(groupId); break;
                case 'delete-group': if (typeof confirmGroupDelete === 'function') confirmGroupDelete(groupId); break;
                case 'purge-group': if (typeof confirmGroupPurge === 'function') confirmGroupPurge(groupId); break;
                case 'reset-all': if (typeof ajax_group_reset_all === 'function') ajax_group_reset_all(); break;
                case 'purge-all': if (typeof ajax_group_purge_all === 'function') ajax_group_purge_all(); break;
                case 'reset-selected': if (typeof ajax_group_reset_selected === 'function') ajax_group_reset_selected(); break;
            }
            return;
        }

        // Verify user modal
        var verifyBtn = e.target.closest('[data-show-verify-modal]');
        if (verifyBtn) { var form = verifyBtn.closest('form'); if (form && typeof showVerifyModal === 'function') showVerifyModal(e, form); return; }
        if (e.target.closest('[data-close-verify-modal]')) { e.preventDefault(); if (typeof hideVerifyModal === 'function') hideVerifyModal(); return; }
        if (e.target.closest('[data-submit-verify-form]')) { e.preventDefault(); if (typeof submitVerifyForm === 'function') submitVerifyForm(); return; }

        // Restore/delete user buttons
        var restoreBtn = e.target.closest('.restore-user-btn');
        if (restoreBtn) {
            e.preventDefault();
            var userId = restoreBtn.getAttribute('data-user-id');
            var username = restoreBtn.getAttribute('data-username') || 'this user';
            showConfirm({ title: 'Restore User', message: 'Are you sure you want to restore user "' + username + '"?', type: 'success', confirmText: 'Restore', onConfirm: function() {
                var form = document.getElementById('individualActionForm');
                if (form) { form.action = '/admin/deleted-users/restore/' + userId; form.method = 'POST'; form.submit(); }
            }});
            return;
        }

        var deleteUserBtn = e.target.closest('.delete-user-btn');
        if (deleteUserBtn) {
            e.preventDefault();
            var userId = deleteUserBtn.getAttribute('data-user-id');
            var username = deleteUserBtn.getAttribute('data-username') || 'this user';
            showConfirm({ title: 'Permanently Delete User', message: 'Are you sure you want to permanently delete user "' + username + '"? This action cannot be undone.', type: 'danger', confirmText: 'Delete Permanently', onConfirm: function() {
                var form = document.getElementById('individualActionForm');
                if (form) { form.action = '/admin/deleted-users/permanent-delete/' + userId; form.method = 'POST'; form.submit(); }
            }});
            return;
        }

        // Promotion toggle/delete
        var promoToggle = e.target.closest('.promotion-toggle-btn');
        if (promoToggle) {
            e.preventDefault();
            var name = promoToggle.getAttribute('data-promotion-name');
            var active = promoToggle.getAttribute('data-promotion-active') === '1';
            var action = active ? 'deactivate' : 'activate';
            showConfirm({
                title: action.charAt(0).toUpperCase() + action.slice(1) + ' Promotion',
                message: 'Are you sure you want to ' + action + ' the promotion "' + name + '"?',
                type: active ? 'warning' : 'success',
                confirmText: action.charAt(0).toUpperCase() + action.slice(1),
                onConfirm: function() { window.location.href = promoToggle.href; }
            });
            return;
        }

        var promoDelete = e.target.closest('.promotion-delete-btn');
        if (promoDelete) {
            e.preventDefault();
            var name = promoDelete.getAttribute('data-promotion-name');
            var form = promoDelete.closest('form');
            showConfirm({ title: 'Delete Promotion', message: 'Are you sure you want to delete the promotion "' + name + '"?', details: 'This action cannot be undone.', type: 'danger', confirmText: 'Delete', onConfirm: function() { if (form) form.submit(); } });
            return;
        }

        // Content toggle/delete
        var contentToggle = e.target.closest('.content-toggle-status');
        if (contentToggle) {
            e.preventDefault();
            var id = contentToggle.getAttribute('data-content-id');
            var csrf = document.querySelector('meta[name="csrf-token"]')?.content;
            if (!id || !csrf) return;
            contentToggle.disabled = true; contentToggle.style.opacity = '0.6';
            fetch('/admin/content-toggle-status', {
                method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, 'X-Requested-With': 'XMLHttpRequest' },
                body: JSON.stringify({ id: id })
            }).then(function(r) { return r.json(); }).then(function(data) {
                if (data.success) {
                    var row = contentToggle.closest('tr'), sc = row.cells[5], ns = data.status;
                    if (ns === 1) { sc.innerHTML = '<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-100"><i class="fa fa-check mr-1"></i>Enabled</span>'; contentToggle.className = 'content-toggle-status text-green-600 dark:text-green-400 hover:text-green-900 dark:hover:text-green-300'; contentToggle.innerHTML = '<i class="fa fa-toggle-on"></i>'; }
                    else { sc.innerHTML = '<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-100"><i class="fa fa-times mr-1"></i>Disabled</span>'; contentToggle.className = 'content-toggle-status text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-300'; contentToggle.innerHTML = '<i class="fa fa-toggle-off"></i>'; }
                    contentToggle.setAttribute('data-current-status', ns); contentToggle.title = ns === 1 ? 'Disable' : 'Enable';
                    showToast(data.message, 'success');
                } else showToast(data.message || 'Failed', 'error');
                contentToggle.disabled = false; contentToggle.style.opacity = '1';
            }).catch(function() { showToast('Error', 'error'); contentToggle.disabled = false; contentToggle.style.opacity = '1'; });
            return;
        }

        var contentDelete = e.target.closest('.content-delete');
        if (contentDelete) {
            e.preventDefault();
            var id = contentDelete.getAttribute('data-content-id');
            var title = contentDelete.getAttribute('data-content-title');
            var csrf = document.querySelector('meta[name="csrf-token"]')?.content;
            if (!id || !csrf) return;
            showConfirm({ title: 'Delete Content', message: 'Are you sure you want to delete "' + title + '"?', details: 'This action cannot be undone.', type: 'danger', confirmText: 'Delete',
                onConfirm: function() {
                    contentDelete.disabled = true; contentDelete.style.opacity = '0.6';
                    fetch('/admin/content-delete', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrf, 'X-Requested-With': 'XMLHttpRequest' }, body: JSON.stringify({ id: id }) })
                    .then(function(r) { return r.json(); }).then(function(data) {
                        if (data.success) { var row = contentDelete.closest('tr'); if (row) { row.style.transition = 'opacity 0.3s'; row.style.opacity = '0'; setTimeout(function() { row.remove(); if (document.querySelector('tbody')?.children.length === 0) location.reload(); }, 300); } showToast(data.message, 'success'); }
                        else { showToast(data.message || 'Failed', 'error'); contentDelete.disabled = false; contentDelete.style.opacity = '1'; }
                    }).catch(function() { showToast('Error', 'error'); contentDelete.disabled = false; contentDelete.style.opacity = '1'; });
                }
            });
            return;
        }

        // Regex delete
        var regexDel = e.target.closest('[data-delete-regex]');
        if (regexDel) {
            e.preventDefault();
            var id = regexDel.getAttribute('data-delete-regex');
            var url = regexDel.getAttribute('data-delete-url');
            if (confirm('Are you sure you want to delete this regex?')) {
                var csrf = document.querySelector('meta[name="csrf-token"]')?.content;
                fetch(url + '?id=' + id, { method: 'GET', headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrf } })
                .then(function(r) { return r.json(); }).then(function(d) {
                    if (d.success) { var row = document.getElementById('row-' + id); if (row) { row.style.transition = 'opacity 0.3s'; row.style.opacity = '0'; setTimeout(function() { row.remove(); }, 300); } showToast('Regex deleted', 'success'); }
                    else showToast('Error', 'error');
                }).catch(function() { showToast('Error', 'error'); });
            }
            return;
        }

        // Binary blacklist delete
        var blDel = e.target.closest('[data-delete-blacklist]');
        if (blDel) {
            e.preventDefault();
            var id = blDel.getAttribute('data-delete-blacklist');
            if (confirm('Are you sure? This will delete the blacklist.')) {
                if (typeof ajax_binaryblacklist_delete === 'function') ajax_binaryblacklist_delete(id);
            }
            return;
        }

        // Season tab
        var seasonTab = e.target.closest('.season-tab');
        if (seasonTab) {
            e.preventDefault();
            var num = seasonTab.getAttribute('data-season');
            if (num && typeof switchSeason === 'function') switchSeason(num);
            return;
        }

        // My Movies confirm
        var confirmAction = e.target.closest('.confirm_action');
        if (confirmAction) {
            if (!confirm('Are you sure you want to remove this movie from your watchlist?')) e.preventDefault();
            return;
        }
    });

    // --- Change event delegation ---
    document.addEventListener('change', function(e) {
        if (e.target.hasAttribute('data-redirect-on-change')) {
            var url = e.target.value;
            if (url && url !== '#') window.location.href = url;
        }
        if (e.target.classList.contains('group-checkbox')) {
            if (typeof updateSelectionUI === 'function') updateSelectionUI();
        }
    });

    // --- Image fallbacks ---
    document.querySelectorAll('img[data-fallback-src], img[data-hide-on-error]').forEach(function(img) {
        img.addEventListener('error', function() {
            var fb = this.getAttribute('data-fallback-src');
            if (fb && this.src !== fb) { this.src = fb; return; }
            if (this.hasAttribute('data-hide-on-error')) this.style.display = 'none';
        });
    });

    // --- Admin select-alls and bulk forms ---
    // Invitations select-all
    var selectAllInv = document.getElementById('select_all');
    if (selectAllInv) {
        var invBoxes = document.querySelectorAll('.invitation-checkbox');
        selectAllInv.addEventListener('change', function() { invBoxes.forEach(function(cb) { cb.checked = selectAllInv.checked; }); });
        invBoxes.forEach(function(cb) { cb.addEventListener('change', function() {
            var all = Array.from(invBoxes).every(function(c) { return c.checked; });
            var some = Array.from(invBoxes).some(function(c) { return c.checked; });
            selectAllInv.checked = all; selectAllInv.indeterminate = some && !all;
        }); });
    }

    // Deleted users select-all
    var selectAllUsers = document.getElementById('selectAll');
    if (selectAllUsers) {
        var userBoxes = document.querySelectorAll('.user-checkbox');
        selectAllUsers.addEventListener('change', function() { userBoxes.forEach(function(cb) { cb.checked = selectAllUsers.checked; }); });
        userBoxes.forEach(function(cb) { cb.addEventListener('change', function() {
            var all = Array.from(userBoxes).every(function(c) { return c.checked; });
            var some = Array.from(userBoxes).some(function(c) { return c.checked; });
            selectAllUsers.checked = all; selectAllUsers.indeterminate = some && !all;
        }); });
    }

    // Bulk action form
    var bulkForm = document.getElementById('bulkActionForm');
    if (bulkForm) {
        bulkForm.addEventListener('submit', function(ev) {
            ev.preventDefault();
            var action = document.getElementById('bulkAction')?.value;
            var checked = document.querySelectorAll('.user-checkbox:checked');
            var errEl = document.getElementById('validationError'), errMsg = document.getElementById('validationErrorMessage');
            if (errEl) errEl.classList.add('hidden');
            if (!action) { if (errEl && errMsg) { errMsg.textContent = 'Please select an action.'; errEl.classList.remove('hidden'); } return; }
            if (!checked.length) { if (errEl && errMsg) { errMsg.textContent = 'Please select at least one user.'; errEl.classList.remove('hidden'); } return; }
            var text = action === 'restore' ? 'restore' : 'permanently delete';
            showConfirm({ title: action === 'restore' ? 'Restore Users' : 'Delete Users', message: 'Are you sure you want to ' + text + ' ' + checked.length + ' user(s)?', type: action === 'restore' ? 'success' : 'danger', confirmText: action === 'restore' ? 'Restore' : 'Delete', onConfirm: function() { bulkForm.submit(); } });
        });
    }

    // Tmux crap types toggle
    var checkedRadio = document.querySelector('input[name="fix_crap_opt"]:checked');
    var crapContainer = document.getElementById('crap_types_container');
    if (crapContainer) {
        if (checkedRadio) crapContainer.style.display = checkedRadio.value === 'Custom' ? 'block' : 'none';
        document.querySelectorAll('input[name="fix_crap_opt"]').forEach(function(r) { r.addEventListener('change', function() { crapContainer.style.display = this.value === 'Custom' ? 'block' : 'none'; }); });
    }
})();
