    jQuery(document).ready(function($) {
        var i18n = iv1wpt_vars.i18n || {};

        // ═══════════════════════════════════════════
        // Modal-System
        // ═══════════════════════════════════════════
        var modalCallback = null;

        function iv1wpt_modal(options) {
            var type   = options.type || 'confirm'; // confirm | error | success
            var title  = options.title || 'Hinweis';
            var body   = options.body || '';
            var ok     = options.ok || 'OK';
            var cancel = options.cancel || i18n.cancel || 'Cancel';

            var header = $('#iv1wpt-modal-header');
            var icons  = { confirm: 'warning', error: 'dismiss', success: 'yes-alt' };
            header.attr('class', 'iv1wpt-modal-header ' + type);
            header.find('.dashicons').attr('class', 'dashicons dashicons-' + (icons[type] || 'info'));
            $('#iv1wpt-modal-title').text(title);
            $('#iv1wpt-modal-body').html(body);

            var footer = $('#iv1wpt-modal-footer').empty();

            if (type === 'confirm') {
                $('<button class="button">' + (i18n.cancel || 'Cancel') + '</button>').on('click', function() {
                    var cb = modalCallback;
                    iv1wpt_modal_close();
                    if (cb) cb(false);
                }).appendTo(footer);
                $('<button class="button button-danger">' + ok + '</button>').on('click', function() {
                    var cb = modalCallback;
                    iv1wpt_modal_close();
                    if (cb) cb(true);
                }).appendTo(footer);
            } else {
                $('<button class="button button-primary">OK</button>').on('click', function() {
                    var cb = modalCallback;
                    iv1wpt_modal_close();
                    if (cb) cb(true);
                }).appendTo(footer);
            }

            $('#iv1wpt-modal').addClass('active');
        }

        function iv1wpt_modal_close() {
            $('#iv1wpt-modal').removeClass('active');
            modalCallback = null;
        }

        // Overlay-Klick schließt (nur bei Nicht-Confirm)
        $('#iv1wpt-modal').on('click', function(e) {
            if (e.target === this) iv1wpt_modal_close();
        });
        // ESC schließt
        $(document).on('keydown', function(e) {
            if (e.key === 'Escape' && $('#iv1wpt-modal').hasClass('active')) iv1wpt_modal_close();
        });

        // Shortcut: Bestätigung anfordern
        function iv1wpt_confirm(title, body, callback, okText) {
            modalCallback = callback;
            iv1wpt_modal({ type: 'confirm', title: title, body: body, ok: okText || i18n.ok || 'OK', cancel: i18n.cancel || 'Cancel' });
        }

        // Shortcut: Fehlermeldung anzeigen
        function iv1wpt_alert_error(title, body) {
            iv1wpt_modal({ type: 'error', title: title, body: body });
        }

        // ═══════════════════════════════════════════
        // Backup-Liste laden
        // ═══════════════════════════════════════════
        function iv1wpt_load_list() {
            $('#iv1wpt-backup-list').html('<p class="iv1wpt-loading">' + (i18n.loading_list || 'Loading...') + '</p>');
            $.post(ajaxurl, {
                action: 'iv1wpt_list_backups',
                _ajax_nonce: iv1wpt_vars.nonce
            }, function(response) {
                $('#iv1wpt-backup-list').html(response);
            }).fail(function() {
                $('#iv1wpt-backup-list').html('<p>' + (i18n.load_error || 'Error') + '</p>');
            });
        }

        // Initial laden (nur wenn Backup-Tab sichtbar)
        if ($('#iv1wpt-backup-list').length) {
            iv1wpt_load_list();
        }

        // Refresh-Button
        $('#iv1wpt-refresh-list').on('click', function() {
            iv1wpt_load_list();
        });

        // ═══════════════════════════════════════════
        // Manuelles Backup
        // ═══════════════════════════════════════════
        $('#backup-form .backup-btn').on('click', function(e) {
            e.preventDefault();
            var btn = $(this);
            var type = btn.data('type');
            var nonce = iv1wpt_vars.nonce;

            $('#backup-form button').prop('disabled', true);
            btn.text(i18n.running || 'Running...');
            $('#backup-result').html('<div class="notice notice-info"><p>' + (i18n.backup_running || 'Running...') + '</p></div>');

            $.post(ajaxurl, {
                action: 'iv1wpt_run_backup',
                backup_type: type,
                _ajax_nonce: nonce
            }, function(response) {
                $('#backup-result').html(response);
                iv1wpt_reset_buttons();
                iv1wpt_load_list();
            }).fail(function() {
                $('#backup-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Error') + '</p></div>');
                iv1wpt_reset_buttons();
            });
        });

        function iv1wpt_reset_buttons() {
            $('#backup-form button').prop('disabled', false).each(function() {
                var t = $(this).data('type');
                $(this).text(t === 'full' ? (i18n.all_files_db || 'All') : t === 'files' ? (i18n.files_only || 'Files') : (i18n.db_only || 'DB'));
            });
        }

        // ═══════════════════════════════════════════
        // Backup löschen (Modal statt confirm)
        // ═══════════════════════════════════════════
        $('#iv1wpt-backup-list').on('click', '.iv1wpt-delete-btn', function(e) {
            e.preventDefault();
            var btn = $(this);
            var filename = btn.data('file');

            iv1wpt_confirm(
                i18n.delete_backup || 'Delete backup',
                (i18n.delete_backup_confirm || '').replace('%s', $('<span>').text(filename).html()) + '<br><small class="description">' + (i18n.delete_backup_hint || '') + '</small>',
                function(yes) {
                    if (!yes) return;

                    btn.prop('disabled', true).text('…');

                    $.post(ajaxurl, {
                        action: 'iv1wpt_delete_backup',
                        filename: filename,
                        _ajax_nonce: iv1wpt_vars.nonce
                    }, function(response) {
                        if (response.success) {
                            btn.closest('tr').fadeOut(300, function() {
                                $(this).remove();
                                if ($('#iv1wpt-backup-list tbody tr').length === 0) {
                                    $('#iv1wpt-backup-list').html('<p>' + (i18n.no_backups || 'No backups') + '</p>');
                                }
                            });
                        } else {
                            iv1wpt_alert_error(i18n.delete_failed || 'Error', response.data || i18n.unknown_error || 'Error');
                            btn.prop('disabled', false).text(i18n.delete || 'Delete');
                        }
                    }).fail(function() {
                        iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed');
                        btn.prop('disabled', false).text(i18n.delete || 'Delete');
                    });
                },
                i18n.yes_delete || 'Yes, delete'
            );
        });

        // ═══════════════════════════════════════════
        // DB-Bereinigung
        // ═══════════════════════════════════════════
        // ── DB Restore ──
        $('#iv1wpt-backup-list').on('click', '.iv1wpt-restore-btn', function(e) {
            e.preventDefault();
            var btn = $(this);
            var filename = btn.data('file');

            iv1wpt_confirm(
                i18n.restore_db || 'Restore database',
                (i18n.restore_confirm || '').replace('%s', $('<span>').text(filename).html()) + '<br><small class="description" style="color:#d63638;">' + (i18n.restore_warning || 'Warning!') + '</small>',
                function(yes) {
                    if (!yes) return;
                    btn.prop('disabled', true).text(i18n.restoring || 'Restoring...');

                    $.post(ajaxurl, {
                        action: 'iv1wpt_restore_db',
                        filename: filename,
                        _ajax_nonce: iv1wpt_vars.nonce
                    }, function(response) {
                        if (response.success) {
                            var cls = response.data.status === 'warning' ? 'notice-warning' : 'notice-success';
                            $('#backup-result').html('<div class="notice ' + cls + ' is-dismissible"><p>' + response.data.message + '</p></div>');
                        } else {
                            iv1wpt_alert_error(i18n.restore_error || 'Error', response.data || i18n.unknown_error || 'Error');
                        }
                        btn.prop('disabled', false).text(i18n.yes_restore || 'Restore');
                    }).fail(function() {
                        iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed');
                        btn.prop('disabled', false).text(i18n.yes_restore || 'Restore');
                    });
                },
                i18n.yes_restore || 'Yes, restore'
            );
        });

        var cleanupNonce = iv1wpt_vars.nonce;

        // Einzelnen Typ scannen
        function iv1wpt_scan_item(key, callback) {
            var row = $('#iv1wpt-cleanup-table tr[data-key="' + key + '"]');
            row.find('.iv1wpt-clean-count').text('…').removeClass('has-items clean');
            row.find('.iv1wpt-clean-size').text('…').removeClass('has-items');
            row.find('.iv1wpt-scan-single').prop('disabled', true);

            $.post(ajaxurl, {
                action: 'iv1wpt_cleanup_scan',
                cleanup_key: key,
                _ajax_nonce: cleanupNonce
            }, function(response) {
                if (response.success) {
                    var d = response.data;
                    var countEl = row.find('.iv1wpt-clean-count');
                    var sizeEl = row.find('.iv1wpt-clean-size');
                    countEl.text(d.count);
                    sizeEl.text(d.size || '—');

                    if (d.count > 0) {
                        countEl.addClass('has-items');
                        sizeEl.addClass('has-items');
                        row.find('.iv1wpt-clean-single').prop('disabled', false);
                    } else {
                        countEl.addClass('clean');
                        row.find('.iv1wpt-clean-single').prop('disabled', true);
                    }

                    // Detail speichern (z.B. Tabellennamen bei verwaisten Tabellen)
                    if (d.detail) {
                        row.data('detail', d.detail);
                        countEl.css('cursor', 'help').attr('title', d.detail);
                    }
                }
                row.find('.iv1wpt-scan-single').prop('disabled', false);
                if (callback) callback();
            }).fail(function() {
                row.find('.iv1wpt-clean-count').text(i18n.error || 'Error');
                row.find('.iv1wpt-scan-single').prop('disabled', false);
                if (callback) callback();
            });
        }

        // Einzelnen Typ bereinigen
		function iv1wpt_clean_item(key, callback) {
			var row = $('#iv1wpt-cleanup-table tr[data-key="' + key + '"]');
			row.find('.iv1wpt-clean-single').prop('disabled', true).html('…');

			$.post(ajaxurl, {
				action: 'iv1wpt_cleanup_run',
				cleanup_key: key,
				_ajax_nonce: cleanupNonce
			}, function(response) {
				if (response.success) {
					row.find('.iv1wpt-clean-count').text('0').removeClass('has-items').addClass('clean');
					row.find('.iv1wpt-clean-size').text('0 B').removeClass('has-items');
					row.find('.iv1wpt-clean-single').html('<span class="dashicons dashicons-trash" aria-hidden="true"></span>').prop('disabled', true);
					$('#iv1wpt-cleanup-result').html('<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p></div>');
				} else {
					row.find('.iv1wpt-clean-single').html('<span class="dashicons dashicons-trash" aria-hidden="true"></span>').prop('disabled', false);
					$('#iv1wpt-cleanup-result').html('<div class="notice notice-error"><p>' + (response.data || i18n.error || 'Error') + '</p></div>');
				}
				if (callback) callback();
			}).fail(function() {
				row.find('.iv1wpt-clean-single').html('<span class="dashicons dashicons-trash" aria-hidden="true"></span>').prop('disabled', false);
				if (callback) callback();
			});
		}

        // Alle scannen
        $('#iv1wpt-scan-all').on('click', function() {
            var btn = $(this);
            btn.prop('disabled', true).text(i18n.scanning || 'Scanning...');
            var keys = [];
            $('#iv1wpt-cleanup-table tr[data-key]').each(function() {
                keys.push($(this).data('key'));
            });

            var i = 0;
            function next() {
                if (i < keys.length) {
                    iv1wpt_scan_item(keys[i], function() { i++; next(); });
                } else {
                    btn.prop('disabled', false).text(i18n.scan_all || 'Scan all');
                    var hasItems = $('#iv1wpt-cleanup-table .iv1wpt-clean-count.has-items').length > 0;
                    $('#iv1wpt-clean-all').prop('disabled', !hasItems);
                }
            }
            next();
        });

        // Alle bereinigen (mit Modal)
        $('#iv1wpt-clean-all').on('click', function() {
            var checkedCount = 0;
            $('#iv1wpt-cleanup-table tr[data-key]').each(function() {
                var row = $(this);
                if (row.find('.iv1wpt-clean-check').is(':checked') && row.find('.iv1wpt-clean-count').hasClass('has-items')) {
                    checkedCount++;
                }
            });

            iv1wpt_confirm(
                i18n.clean_all || 'Clean all',
                (i18n.clean_all_confirm || 'Really clean all?').replace('%s', checkedCount) + '<br><small class="description">' + (i18n.clean_all_hint || '') + '</small>',
                function(yes) {
                    if (!yes) return;
                    var btn = $('#iv1wpt-clean-all');
                    btn.prop('disabled', true).text(i18n.cleaning || 'Cleaning...');

                    var keys = [];
                    $('#iv1wpt-cleanup-table tr[data-key]').each(function() {
                        var row = $(this);
                        if (row.find('.iv1wpt-clean-check').is(':checked') && row.find('.iv1wpt-clean-count').hasClass('has-items')) {
                            keys.push(row.data('key'));
                        }
                    });

                    var i = 0;
                    function next() {
                        if (i < keys.length) {
                            iv1wpt_clean_item(keys[i], function() { i++; next(); });
                        } else {
                            btn.text(i18n.clean_all || 'Clean all');
                            var remaining = $('#iv1wpt-cleanup-table .iv1wpt-clean-count.has-items').length;
                            btn.prop('disabled', remaining === 0);
                            if (remaining === 0) {
                                $('#iv1wpt-cleanup-result').html('<div class="notice notice-success is-dismissible"><p>' + (i18n.all_cleaned || 'Done') + '</p></div>');
                            }
                        }
                    }
                    next();
                },
                i18n.yes_clean || 'Yes, clean'
            );
        });

        // Einzel-Scan
        $('#iv1wpt-cleanup-table').on('click', '.iv1wpt-scan-single', function() {
            iv1wpt_scan_item($(this).data('key'));
        });

        // Einzel-Bereinigung (mit Modal)
        $('#iv1wpt-cleanup-table').on('click', '.iv1wpt-clean-single', function() {
            var key = $(this).data('key');
            var row = $(this).closest('tr');
            var label = row.find('td:eq(1)').text();
            var count = row.find('.iv1wpt-clean-count').text();
            var detail = row.data('detail') || '';

            var bodyHtml = '<strong>' + $('<span>').text(label).html() + '</strong> – ' + count + ' ' + (i18n.entries_delete || 'entries delete?');

            // Bei verwaisten Tabellen die Namen anzeigen
            if (key === 'orphan_tables' && detail) {
                bodyHtml += '<br><br><small class="description"><strong>' + (i18n.affected_tables || 'Affected tables') + ':</strong><br><code>' + $('<span>').text(detail).html() + '</code></small>';
                bodyHtml += '<br><small style="color:#d63638;">' + (i18n.restore_warning || 'Warning!') + '</small>';
            }

            iv1wpt_confirm(
                (i18n.clean_confirm || 'Confirm'),
                bodyHtml,
                function(yes) {
                    if (!yes) return;
                    iv1wpt_clean_item(key);
                },
                i18n.yes_clean || 'Yes, clean'
            );
        });

        // Alle-Checkbox
        $('#iv1wpt-check-all').on('change', function() {
            $('.iv1wpt-clean-check').prop('checked', $(this).is(':checked'));
        });

        // ═══════════════════════════════════════════
        // Tab: Verwaiste Tabellen
        // ═══════════════════════════════════════════

        // Scannen
        $('#iv1wpt-tables-scan').on('click', function() {
            var btn = $(this);
            btn.prop('disabled', true).text(i18n.scanning || 'Scanning...');
            $('#iv1wpt-tables-list').html('<p style="color:#666;font-style:italic;">' + (i18n.scanning || 'Scanning...') + '</p>');
            $('#iv1wpt-tables-delete-selected').prop('disabled', true);

            $.post(ajaxurl, {
                action: 'iv1wpt_tables_scan',
                _ajax_nonce: cleanupNonce
            }, function(response) {
                btn.prop('disabled', false).text(i18n.scan_tables || 'Scan tables');
                if (response.success) {
                    $('#iv1wpt-tables-list').html(response.data.html);
                    if (response.data.orphan_count > 0) {
                        $('#iv1wpt-tables-delete-selected').prop('disabled', false);
                    }
                    // Alle-Checkbox im Tabellen-Tab
                    $('#iv1wpt-tables-check-all').on('change', function() {
                        $('#iv1wpt-tables-list .iv1wpt-table-check').prop('checked', $(this).is(':checked'));
                    });
                } else {
                    $('#iv1wpt-tables-list').html('<p>' + (i18n.error || 'Error') + '</p>');
                }
            }).fail(function() {
                btn.prop('disabled', false).text(i18n.scan_tables || 'Scan tables');
                $('#iv1wpt-tables-list').html('<p>' + (i18n.connection_error || 'Error') + '</p>');
            });
        });

        // Einzelne Tabelle löschen
        $('#iv1wpt-tables-list').on('click', '.iv1wpt-drop-table', function() {
            var btn = $(this);
            var table = btn.data('table');

            iv1wpt_confirm(
                (i18n.delete_table || 'Delete table'),
                (i18n.drop_confirm || '').replace('%s', $('<span>').text(table).html()),
                function(yes) {
                    if (!yes) return;
                    btn.prop('disabled', true).text('…');

                    $.post(ajaxurl, {
                        action: 'iv1wpt_tables_drop',
                        table_name: table,
                        _ajax_nonce: cleanupNonce
                    }, function(response) {
                        if (response.success) {
                            btn.closest('tr').fadeOut(300, function() {
                                $(this).remove();
                                if ($('#iv1wpt-tables-list tbody tr').length === 0) {
                                    $('#iv1wpt-tables-list').html('<p>' + (i18n.no_orphan_tables || 'No orphaned tables') + '</p>');
                                    $('#iv1wpt-tables-delete-selected').prop('disabled', true);
                                }
                            });
                            $('#iv1wpt-tables-result').html('<div class="notice notice-success is-dismissible"><p>' + response.data + '</p></div>');
                        } else {
                            iv1wpt_alert_error(i18n.delete_failed || 'Error', response.data || i18n.unknown_error || 'Error');
                            btn.prop('disabled', false).text(i18n.delete || 'Delete');
                        }
                    }).fail(function() {
                        iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Error');
                        btn.prop('disabled', false).text(i18n.delete || 'Delete');
                    });
                },
                i18n.yes_delete || 'Yes, delete'
            );
        });

        // Markierte löschen
        $('#iv1wpt-tables-delete-selected').on('click', function() {
            
			if (typeof iv1wpt_vars === 'undefined' || !iv1wpt_vars.has_pro) {
				var proUrl = (typeof iv1wpt_vars !== 'undefined' && iv1wpt_vars.pro_license_url)
					? iv1wpt_vars.pro_license_url
					: '#';

				if (proUrl !== '#') {
					window.open(proUrl, '_blank', 'noopener,noreferrer');
				}

				return;
			}
			
            var tables = [];
            $('#iv1wpt-tables-list .iv1wpt-table-check:checked').each(function() {
                tables.push($(this).val());
            });

            if (tables.length === 0) {
                iv1wpt_alert_error(i18n.no_selection || 'No selection', i18n.select_one || 'Select at least one.');
                return;
            }

            iv1wpt_confirm(
                (i18n.n_tables_delete || '%d tables').replace('%d', tables.length),
                '<strong>' + tables.length + '</strong> ' + (i18n.n_tables_delete || 'tables') + ':<br><br><code>' + $('<span>').text(tables.join(', ')).html() + '</code>',
                function(yes) {
                    if (!yes) return;
                    var btn = $('#iv1wpt-tables-delete-selected');
                    btn.prop('disabled', true).text(i18n.deleting || 'Deleting...');

                    var i = 0;
                    function nextDrop() {
                        if (i < tables.length) {
                            var tbl = tables[i];
                            $.post(ajaxurl, {
                                action: 'iv1wpt_tables_drop',
                                table_name: tbl,
                                _ajax_nonce: cleanupNonce
                            }, function(response) {
                                if (response.success) {
                                    $('#iv1wpt-tables-list tr[data-table="' + tbl + '"]').fadeOut(200, function() { $(this).remove(); });
                                }
                                i++; nextDrop();
                            }).fail(function() { i++; nextDrop(); });
                        } else {
                            btn.text(i18n.delete_selected || 'Delete selected');
                            var remaining = $('#iv1wpt-tables-list tbody tr').length;
                            btn.prop('disabled', remaining === 0);
                            if (remaining === 0) {
                                $('#iv1wpt-tables-list').html('<p>' + (i18n.no_orphan_tables || 'No orphaned tables') + '</p>');
                            }
                            $('#iv1wpt-tables-result').html('<div class="notice notice-success is-dismissible"><p>' + (i18n.n_tables_deleted || '').replace('%d', tables.length) + '</p></div>');
                        }
                    }
                    nextDrop();
                },
                i18n.yes_delete || 'Yes, delete'
            );
        });

        // ═══════════════════════════════════════════
        // Tab: Bilder
        // ═══════════════════════════════════════════
        var imageResults = [];

        $('#iv1wpt-images-scan').on('click', function() {
            var btn = $(this);
            btn.prop('disabled', true);
            if ($('#iv1wpt-images-delete-selected').length) $('#iv1wpt-images-delete-selected').prop('disabled', true);
            $('#iv1wpt-images-progress').show();
            $('#iv1wpt-images-progress-text').text(i18n.loading_ids || 'Loading...');
            $('#iv1wpt-images-list').empty();
            $('#iv1wpt-images-stats').hide();
            $('#iv1wpt-images-filter').hide();
            $('#iv1wpt-images-result').empty();
            imageResults = [];

            $.post(ajaxurl, {
                action: 'iv1wpt_images_get_ids',
                _ajax_nonce: cleanupNonce
            }, function(response) {
                if (!response.success) {
                    $('#iv1wpt-images-progress').hide();
                    btn.prop('disabled', false);
                    $('#iv1wpt-images-result').html('<div class="notice notice-error"><p>' + (response.data || i18n.error || 'Error') + '</p></div>');
                    return;
                }
                var ids = response.data.ids;
                var total = ids.length;
                if (total === 0) {
                    $('#iv1wpt-images-progress').hide();
                    btn.prop('disabled', false);
                    $('#iv1wpt-images-list').html('<p>' + (i18n.no_images || 'No images') + '</p>');
                    return;
                }
                var batchSize = 50;
                var offset = 0;
                function scanBatch() {
                    var batch = ids.slice(offset, offset + batchSize);
                    if (batch.length === 0) {
                        $('#iv1wpt-images-progress').hide();
                        btn.prop('disabled', false);
                        iv1wpt_render_images('unused');
                        return;
                    }
                    var pct = Math.round((offset / total) * 100);
                    $('#iv1wpt-images-progress-text').text((i18n.scanning || 'Scanning...') + ' ' + pct + '% (' + offset + '/' + total + ')');
                    $.post(ajaxurl, {
                        action: 'iv1wpt_images_scan_batch',
                        ids: batch.join(','),
                        _ajax_nonce: cleanupNonce
                    }, function(resp) {
                        if (resp.success) imageResults = imageResults.concat(resp.data.results);
                        offset += batchSize;
                        scanBatch();
                    }).fail(function() { offset += batchSize; scanBatch(); });
                }
                scanBatch();
            }).fail(function() {
                $('#iv1wpt-images-progress').hide();
                btn.prop('disabled', false);
            });
        });

		function iv1wpt_render_images(filter) {
			var used = 0, unused = 0, unusedSize = 0;
			for (var i = 0; i < imageResults.length; i++) {
				if (imageResults[i].used) {
					used++;
				} else {
					unused++;
					unusedSize += imageResults[i].filesize || 0;
				}
			}

			$('#iv1wpt-stat-total').text(imageResults.length);
			$('#iv1wpt-stat-used').text(used);
			$('#iv1wpt-stat-unused').text(unused);
			$('#iv1wpt-stat-size').text(iv1wpt_format_size(unusedSize));
			$('#iv1wpt-images-stats').show();
			$('#iv1wpt-images-filter').show();
			$('#iv1wpt-images-filter-select').val(filter);

			if (unused > 0) {
				$('#iv1wpt-images-delete-selected').prop('disabled', !iv1wpt_vars.has_pro);
			}

			var filtered = imageResults.filter(function(img) {
				if (filter === 'unused') return !img.used;
				if (filter === 'used') return img.used;
				return true;
			});

			if (filtered.length === 0) {
				$('#iv1wpt-images-list').html('<p style="padding:20px;color:#666;text-align:center;">' + (i18n.no_images_view || 'No images') + '</p>');
				return;
			}

			var html = '<div class="iv1wpt-images-container"><div class="iv1wpt-images-header">';
			var hasPro = (typeof iv1wpt_vars !== 'undefined' && !!iv1wpt_vars.has_pro);

			if (filter !== 'used') {
				html += hasPro
					? '<div style="width:30px;"><input type="checkbox" id="iv1wpt-img-check-all" checked></div>'
					: '<div style="width:30px;"></div>';
			}

			html += '<div style="width:60px;">' + (i18n.preview || 'Preview') + '</div>';
			html += '<div style="flex:1;">' + (i18n.file || 'File') + '</div>';
			html += '<div style="width:80px;text-align:right;">' + (i18n.size || 'Size') + '</div>';
			html += '<div style="width:120px;">' + (i18n.status || 'Status') + '</div>';
			html += '<div style="width:80px;text-align:right;">' + (i18n.action || 'Action') + '</div>';
			html += '</div>';

			for (var j = 0; j < filtered.length; j++) {
				var img = filtered[j];

				var st = img.used
					? '<span class="iv1wpt-img-used">' + (i18n.used || 'Used') + '</span>'
					: '<span class="iv1wpt-img-unused">' + (i18n.unused || 'Unused') + '</span>';

				html += '<div class="iv1wpt-img-row" data-id="' + img.id + '">';

				if (filter !== 'used') {
					html += '<div style="width:30px;">';
					if (!img.used && hasPro) {
						html += '<input type="checkbox" class="iv1wpt-img-check" value="' + img.id + '" checked>';
					}
					html += '</div>';
				}

				html += '<div style="width:60px;"><img class="iv1wpt-img-thumb" src="' + (img.thumb || '') + '" alt="" loading="lazy"></div>';

				html += '<div class="iv1wpt-img-info" style="flex:1;">';
				html += '<div class="iv1wpt-img-name">' + iv1wpt_esc(img.filename) + '</div>';
				html += '<div class="iv1wpt-img-meta"><span>' + (img.mime || '') + '</span>';
				if (img.dimensions) {
					html += '<span>' + img.dimensions + '</span>';
				}
				html += '<span>ID: ' + img.id + '</span>';
				if (img.used_in) {
					html += '<span>📌 ' + iv1wpt_esc(img.used_in) + '</span>';
				}
				html += '</div></div>';

				html += '<div style="width:80px;text-align:right;font-size:12px;color:#666;">' + iv1wpt_format_size(img.filesize || 0) + '</div>';
				html += '<div style="width:120px;">' + st + '</div>';
				html += '<div style="width:80px;text-align:right;">';

				if (!img.used) {
					if (hasPro) {
						html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-img-delete" data-id="' + img.id + '" title="' + iv1wpt_esc(i18n.delete || 'Delete') + '" aria-label="' + iv1wpt_esc(i18n.delete || 'Delete') + '">';
						html += '<span class="dashicons dashicons-trash" aria-hidden="true"></span>';
						html += '</button>';
					} else {
						html += '<a href="' + iv1wpt_esc(iv1wpt_vars.pro_license_url) + '" class="button button-small iv1wpt-icon-btn iv1wpt-pro-restore-btn" title="' + iv1wpt_esc(i18n.pro_required || 'Pro required') + '" target="_blank" rel="noopener noreferrer" aria-label="' + iv1wpt_esc(i18n.delete || 'Delete') + '">';
						html += '<span class="dashicons dashicons-lock" aria-hidden="true"></span>';
						html += '</a>';
					}
				}

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

			html += '</div>';
			$('#iv1wpt-images-list').html(html);

			if (hasPro) {
				$('#iv1wpt-img-check-all').on('change', function() {
					$('.iv1wpt-img-check').prop('checked', $(this).is(':checked'));
				});
			}
		}


        $(document).on('change', '#iv1wpt-images-filter-select', function() { iv1wpt_render_images($(this).val()); });

        $('#iv1wpt-images-list').on('click', '.iv1wpt-img-delete', function() {
			
			if (!iv1wpt_vars.has_pro) {
				iv1wpt_alert_error(i18n.pro_required || 'Pro required', i18n.pro_required_msg || 'This feature requires the Pro version.');
				return;
			}			
			
            var btn = $(this), id = btn.data('id'), row = btn.closest('.iv1wpt-img-row'), name = row.find('.iv1wpt-img-name').text();
            iv1wpt_confirm(i18n.delete_image || 'Delete image',
                (i18n.delete_image_confirm || '').replace('%s', iv1wpt_esc(name)) + '<br><small class="description">' + (i18n.delete_image_hint || '') + '</small>',
                function(yes) {
                    if (!yes) return;
                    btn.prop('disabled', true).text('…');
                    $.post(ajaxurl, { action: 'iv1wpt_images_delete', image_id: id, _ajax_nonce: cleanupNonce }, function(resp) {
                        if (resp.success) {
                            row.fadeOut(300, function() { $(this).remove(); });
                            imageResults = imageResults.filter(function(img) { return img.id !== id; });
                            iv1wpt_update_image_stats();
                        } else { iv1wpt_alert_error(i18n.error || 'Error', resp.data || i18n.delete_failed || 'Error'); btn.prop('disabled', false).text(i18n.delete || 'Delete'); }
                    });
                }, i18n.yes_delete || 'Yes, delete');
        });

        $('#iv1wpt-images-delete-selected').on('click', function() {
            var ids = []; $('.iv1wpt-img-check:checked').each(function() { ids.push(parseInt($(this).val())); });
            if (ids.length === 0) { iv1wpt_alert_error(i18n.no_selection || 'No selection', i18n.select_one || 'Select at least one.'); return; }
            iv1wpt_confirm((i18n.n_images_delete || '%d images').replace('%d', ids.length),
                '<strong>' + ids.length + '</strong> ' + (i18n.n_images_delete || 'images') + '<br><small class="description">' + (i18n.delete_image_hint || '') + '</small>',
                function(yes) {
                    if (!yes) return;
                    var btn = $('#iv1wpt-images-delete-selected'); btn.prop('disabled', true).text(i18n.deleting || 'Deleting...');
                    var i = 0;
                    function nextImg() {
                        if (i < ids.length) {
                            var imgId = ids[i];
                            $.post(ajaxurl, { action: 'iv1wpt_images_delete', image_id: imgId, _ajax_nonce: cleanupNonce }, function(resp) {
                                if (resp.success) { $('.iv1wpt-img-row[data-id="' + imgId + '"]').fadeOut(150, function(){ $(this).remove(); }); imageResults = imageResults.filter(function(img){ return img.id !== imgId; }); }
                                i++; nextImg();
                            }).fail(function(){ i++; nextImg(); });
                        } else {
                            btn.text(i18n.delete_selected || 'Delete selected'); iv1wpt_update_image_stats();
                            btn.prop('disabled', $('.iv1wpt-img-check').length === 0);
                            $('#iv1wpt-images-result').html('<div class="notice notice-success is-dismissible"><p>' + (i18n.n_images_deleted || '').replace('%d', ids.length) + '</p></div>');
                        }
                    }
                    nextImg();
                }, i18n.yes_delete || 'Yes, delete');
        });

        function iv1wpt_update_image_stats() {
            var used=0, unused=0, unusedSize=0;
            for (var i=0; i<imageResults.length; i++) { if(imageResults[i].used) used++; else { unused++; unusedSize+=imageResults[i].filesize||0; } }
            $('#iv1wpt-stat-total').text(imageResults.length); $('#iv1wpt-stat-used').text(used); $('#iv1wpt-stat-unused').text(unused); $('#iv1wpt-stat-size').text(iv1wpt_format_size(unusedSize));
        }
        function iv1wpt_format_size(bytes) {
            if(bytes===0) return '0 B'; var k=1024,s=['B','KB','MB','GB']; var i=Math.floor(Math.log(bytes)/Math.log(k));
            return parseFloat((bytes/Math.pow(k,i)).toFixed(1))+' '+s[i];
        }
        function iv1wpt_esc(str) { return $('<span>').text(str||'').html(); }

		function ssbAutoHideNotice(selector) {
			setTimeout(function() {
				$(selector + ' .notice-success').fadeOut(400, function() {
					$(this).remove();
				});
			}, 5000);
		}

		// Globaler MutationObserver: Auto-Hide für alle .notice-success in Result-DIVs
		var iv1wpt_result_selectors = [
			'#backup-result', '#iv1wpt-cleanup-result', '#iv1wpt-tables-result',
			'#iv1wpt-images-result', '#iv1wpt-settings-result', '#iv1wpt-settings-schedule-result',
			'#iv1wpt-settings-ftp-result', '#iv1wpt-settings-email-result',
			'#iv1wpt-2fa-result', '#iv1wpt-tools-result', '#iv1wpt-debug-status', '#iv1wpt-codeeditor-result'
		];
		iv1wpt_result_selectors.forEach(function(sel) {
			var el = document.querySelector(sel);
			if (!el) return;
			var observer = new MutationObserver(function(mutations) {
				mutations.forEach(function(m) {
					if (m.addedNodes.length) ssbAutoHideNotice(sel);
				});
			});
			observer.observe(el, { childList: true });
		});


		// ═══════════════════════════════════════════
		// Tab: Schedule Settings
		// ═══════════════════════════════════════════
		$('#iv1wpt_schedule_save').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();
			
			btn.prop('disabled', true).text(i18n.saving || 'Saving...');

			var data = {
				action: 'iv1wpt_save_schedule',
				_ajax_nonce: iv1wpt_vars.nonce,
				files_schedule: $('#files_schedule').val(),
				files_hour: $('#files_hour').val(),
				db_schedule: $('#db_schedule').val(),
				db_hour: $('#db_hour').val(),
				retention_files: $('#retention_files').val(),
				retention_db: $('#retention_db').val(),
				exclude_patterns: $('#exclude_patterns').val()
			};

			$.post(ajaxurl, data, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (response.success) {
					$('#iv1wpt-settings-schedule-result').html(
						'<div class="notice notice-success is-dismissible"><p>✅ ' + (i18n.schedule_saved || 'Saved') + '</p></div>'
					);
					// nach 5 Sekunden ausblenden
					ssbAutoHideNotice('#iv1wpt-settings-schedule-result');

					// Status-Widget live aktualisieren
					var d = response.data;
					if (d && d.next_files_str !== undefined) {
						var deactivated = i18n.deactivated || 'deactivated';
						$('#iv1wpt-status-next-files').text(
							d.files_schedule === 'off' ? deactivated : d.next_files_str
						);
						$('#iv1wpt-status-interval-files').text(
							d.files_schedule === 'off' ? '' : '(' + d.files_label + ')'
						);
						$('#iv1wpt-status-next-db').text(
							d.db_schedule === 'off' ? deactivated : d.next_db_str
						);
						$('#iv1wpt-status-interval-db').text(
							d.db_schedule === 'off' ? '' : '(' + d.db_label + ')'
						);
					}
				} else {
					$('#iv1wpt-settings-schedule-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || 'Fehler') +
						'</p></div>'
					);
				}
			}).fail(function(xhr) {
				console.log(xhr.responseText);

				btn.prop('disabled', false).text(originalText);
				$('#iv1wpt-settings-schedule-result').html(
					'<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>'
				);
			});
		});

		// ═══════════════════════════════════════════
		// Tab: FTP Settings
		// ═══════════════════════════════════════════
		$('#iv1wpt_ftp_save').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();
			
			btn.prop('disabled', true).text(i18n.saving || 'Saving...');

			var data = {
				action: 'iv1wpt_save_ftp',
				_ajax_nonce: iv1wpt_vars.nonce,
				ftp_enabled: $('#ftp_enabled').is(':checked') ? 1 : 0,
				ftp_host: $('#ftp_host').val(),
				ftp_port: $('#ftp_port').val(),
				ftp_username: $('#ftp_username').val(),
				ftp_password: $('#ftp_password').val(),
				use_ftps: $('#use_ftps').is(':checked') ? 1 : 0,
				ftp_passive: $('#ftp_passive').is(':checked') ? 1 : 0,
				ftp_remote_dir: $('#ftp_remote_dir').val()
			};

			$.post(ajaxurl, data, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (response.success) {
					$('#iv1wpt-settings-ftp-result').html(
						'<div class="notice notice-success is-dismissible"><p>✅ ' + (i18n.ftp_saved || 'Saved') + '</p></div>'
					);
					// nach 5 Sekunden ausblenden
					ssbAutoHideNotice('#iv1wpt-settings-ftp-result');					
				} else {
					$('#iv1wpt-settings-ftp-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || 'Fehler') +
						'</p></div>'
					);
				}
			}).fail(function(xhr) {
				console.log(xhr.responseText);

				btn.prop('disabled', false).text(originalText);
				$('#iv1wpt-settings-ftp-result').html(
					'<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>'
				);
			});
		});

		// ═══════════════════════════════════════════
		// Tab: Email Settings
		// ═══════════════════════════════════════════
		$('#iv1wpt_email_save').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();

			btn.prop('disabled', true).text(i18n.saving || 'Saving...');

			var data = {
				action: 'iv1wpt_save_email',
				_ajax_nonce: iv1wpt_vars.nonce,
				email_enabled: $('#email_enabled').is(':checked') ? 1 : 0,
				email_recipient: $('#email_recipient').val(),
				email_on_success: $('input[name="email_on_success"]').is(':checked') ? 1 : 0,
				email_on_error: $('input[name="email_on_error"]').is(':checked') ? 1 : 0
			};

			$.post(ajaxurl, data, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (response.success) {
					$('#iv1wpt-settings-email-result').html(
						'<div class="notice notice-success is-dismissible"><p>✅ ' + (i18n.email_saved || 'Saved') + '</p></div>'
					);
					// nach 5 Sekunden ausblenden
					ssbAutoHideNotice('#iv1wpt-settings-email-result');						
				} else {
					$('#iv1wpt-settings-email-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || 'Fehler') +
						'</p></div>'
					);
				}
			}).fail(function(xhr) {
				console.log(xhr.responseText);

				btn.prop('disabled', false).text(originalText);
				$('#iv1wpt-settings-email-result').html(
					'<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>'
				);
			});
		});

        // ═══════════════════════════════════════════
        // Tab: WP-Settings
        // ═══════════════════════════════════════════
        $('#iv1wpt-settings-save').on('click', function() {
			var btn = $(this);
			var originalText = btn.text();
	
            btn.prop('disabled', true).text(i18n.saving || 'Saving...');

            var data = { action: 'iv1wpt_save_wp_settings', _ajax_nonce: iv1wpt_vars.nonce };
            $('.iv1wpt-setting-toggle').each(function() {
                data[$(this).attr('name')] = $(this).is(':checked') ? 1 : 0;
            });

            $.post(ajaxurl, data, function(response) {
				btn.prop('disabled', false).text(originalText);
                
                if (response.success) {
                    $('#iv1wpt-settings-result').html('<div class="notice notice-success is-dismissible"><p>✅ ' + (i18n.wp_settings_saved || 'Saved') + '</p></div>');
                } else {
                    $('#iv1wpt-settings-result').html('<div class="notice notice-error"><p>' + (response.data || i18n.error || 'Error') + '</p></div>');
                }
            }).fail(function() {
				btn.prop('disabled', false).text(originalText);
                $('#iv1wpt-settings-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>');
            });
        });

        // Toggle All in Group
        $('.iv1wpt-settings-group-toggle').on('change', function() {
            var group = $(this).closest('tr').nextUntil('tr:has(.iv1wpt-settings-group-toggle), tr.iv1wpt-settings-group');
            group.find('.iv1wpt-setting-toggle').prop('checked', $(this).is(':checked'));
        });

		// ═══════════════════════════════════════════
		// Tab: Security – 2FA
		// ═══════════════════════════════════════════
		$('#iv1wpt-2fa-save').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();

			btn.prop('disabled', true).text(i18n.saving || 'Saving...');

			var postData = {
				action: 'iv1wpt_2fa_save',
				enabled: $('#iv1wpt-2fa-enabled').is(':checked') ? '1' : '0',
				timeout: $('#iv1wpt-2fa-timeout').val(),
				exempt_users: $('#iv1wpt-2fa-exempt').val(),
				_ajax_nonce: iv1wpt_vars.nonce
			};

			$.post(ajaxurl, postData, function(resp) {
				btn.prop('disabled', false).text(originalText);

				if (resp.success) {
					var message = resp.data && resp.data.message
						? resp.data.message
						: (i18n.tfa_saved || '2FA settings saved.');

					var statusText = $('#iv1wpt-2fa-enabled').is(':checked')
						? '2FA ist jetzt <strong style="color:#00a32a;">aktiviert</strong>.'
						: '2FA ist jetzt <strong style="color:#999;">deaktiviert</strong>.';

					$('#iv1wpt-2fa-result').html(
						'<div class="notice notice-success is-dismissible"><p>' +
						message + ' ' + statusText +
						'</p></div>'
					);

					if (resp.data && resp.data.redirect) {
						setTimeout(function() {
							window.location.href = resp.data.redirect;
						}, 1500);
					}

				} else {
					var errorMessage = resp.data && resp.data.message
						? resp.data.message
						: (resp.data || 'Fehler beim Speichern.');

					$('#iv1wpt-2fa-result').html(
						'<div class="notice notice-error"><p>' +
						errorMessage +
						'</p></div>'
					);
				}
			}).fail(function(xhr, status, error) {
				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-2fa-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Error') + ': ' + error +
					'</p></div>'
				);
			});
		});

        // QR-Code ein-/ausblenden
        $('#iv1wpt-2fa-show-qr').on('click', function() {
            $('#iv1wpt-2fa-qr').slideToggle(200);
            $(this).text($('#iv1wpt-2fa-qr').is(':visible') ? (i18n.hide_qr || 'Hide QR') : (i18n.show_qr || 'Show QR'));
        });

        // Eigenen Secret zurücksetzen
        $('#iv1wpt-2fa-reset').on('click', function() {
            iv1wpt_confirm(i18n.reset_secret || 'Reset 2FA', i18n.reset_confirm || 'Your secret will be reset.', function(yes) {
                if (!yes) return;
                var userId = iv1wpt_vars.current_user_id;
                $.post(ajaxurl, { action: 'iv1wpt_2fa_reset', user_id: userId, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    if (resp.success) location.reload();
                    else iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                });
            }, i18n.yes_reset || 'Yes, reset');
        });

        // Admin-Secret zurücksetzen
        $('.iv1wpt-2fa-reset-user').on('click', function() {
            var btn = $(this), userId = btn.data('user-id');
            iv1wpt_confirm(i18n.reset_secret || 'Reset 2FA', i18n.reset_user_confirm || 'Secret will be deleted.', function(yes) {
                if (!yes) return;
                btn.prop('disabled', true).text('…');
                $.post(ajaxurl, { action: 'iv1wpt_2fa_reset', user_id: userId, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    if (resp.success) { btn.closest('tr').find('td:eq(2)').html('<span style="color:#999;">—</span>'); btn.remove(); $('#iv1wpt-2fa-result').html('<div class="notice notice-success is-dismissible"><p>'+resp.data+'</p></div>'); }
                    else { iv1wpt_alert_error(i18n.error || 'Error', resp.data); btn.prop('disabled', false).text(i18n.reset_secret || 'Reset'); }
                });
            }, i18n.yes_reset || 'Yes, reset');
        });

        // ═══════════════════════════════════════════
        // Tab: Tools – Error Log
        // ═══════════════════════════════════════════

        function iv1wpt_load_log() {
            var btn  = $('#iv1wpt-log-load');
            var lines  = $('#iv1wpt-log-lines').val();
            var filter = $('#iv1wpt-log-filter').val();
            btn.prop('disabled', true).text(i18n.loading_list || 'Loading...');
            $('#iv1wpt-log-output').hide().text('');
            $('#iv1wpt-log-meta').text('');

            $.post(ajaxurl, {
                action: 'iv1wpt_errorlog_load',
                lines:  lines,
                filter: filter,
                _ajax_nonce: iv1wpt_vars.nonce
            }, function(resp) {
                btn.prop('disabled', false).text(i18n.log_load || 'Load log');
                if (!resp.success) { iv1wpt_alert_error(i18n.error || 'Error', resp.data); return; }
                var d = resp.data;
                if (!d.exists) {
                    $('#iv1wpt-log-meta').text(i18n.log_not_found || 'Log file does not exist.');
                    return;
                }
                $('#iv1wpt-log-meta').text(
                    (i18n.log_meta || 'Total: %1$s lines | Shown: %2$s | Size: %3$s | Path: %4$s')
                        .replace('%1$s', d.total)
                        .replace('%2$s', d.filtered)
                        .replace('%3$s', iv1wpt_format_size(d.size))
                        .replace('%4$s', d.path)
                );
                var colors = { fatal: '#f87171', error: '#fb923c', warning: '#fbbf24', notice: '#a3e635', info: '#d4d4d4' };
                var html = '';
                for (var j = 0; j < d.lines.length; j++) {
                    var col = colors[d.lines[j].type] || '#d4d4d4';
                    html += '<span style="color:' + col + ';">' + $('<div>').text(d.lines[j].line).html() + '</span>\n';
                }
                $('#iv1wpt-log-output').html(html || ('<span style="color:#999;">' + (i18n.log_empty || 'Log is empty.') + '</span>')).show();
            }).fail(function() {
                btn.prop('disabled', false).text(i18n.log_load || 'Load log');
                iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
            });
        }

        $('#iv1wpt-log-load').on('click', iv1wpt_load_log);

        $('#iv1wpt-log-filter').on('keydown', function(e) {
            if (e.key === 'Enter') iv1wpt_load_log();
        });

        $('#iv1wpt-log-clear').on('click', function() {
            iv1wpt_confirm(i18n.log_clear || 'Clear log', i18n.log_clear_confirm || 'Really clear the log file?', function(yes) {
                if (!yes) return;
                $.post(ajaxurl, { action: 'iv1wpt_errorlog_clear', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    if (resp.success) {
                        $('#iv1wpt-log-output').text('').hide();
                        $('#iv1wpt-log-meta').text('');
                        $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                    }
                });
            }, i18n.yes_clear || 'Yes, clear');
        });

        // ═══════════════════════════════════════════
        // Tab: Tools – Cron Jobs
        // ═══════════════════════════════════════════
        $('#iv1wpt-cron-load').on('click', function() {
            var btn = $(this);
            btn.prop('disabled', true).text(i18n.scanning || 'Scanning...');
            $('#iv1wpt-cron-list').html('');
            $('#iv1wpt-cron-meta').text('');

            $.post(ajaxurl, { action: 'iv1wpt_cron_list', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                btn.prop('disabled', false).text(i18n.cron_load || 'Load Cron events');
                if (!resp.success) { iv1wpt_alert_error(i18n.error || 'Error', resp.data); return; }
                var d = resp.data;
                $('#iv1wpt-cron-meta').text(
                    (i18n.cron_total || '%d events found').replace('%d', d.total)
                );
                if (d.total === 0) {
                    $('#iv1wpt-cron-list').html('<p>' + (i18n.cron_none || 'No events found.') + '</p>');
                    return;
                }
                var typeColors = { core: '#2271b1', plugin: '#00a32a', unknown: '#996800' };
                var html = '<table class="widefat striped"><thead><tr>';
                html += '<th>' + (i18n.cron_hook || 'Hook') + '</th>';
                html += '<th style="width:160px;">' + (i18n.cron_next || 'Next run') + '</th>';
                html += '<th style="width:120px;">' + (i18n.cron_schedule || 'Schedule') + '</th>';
                html += '<th style="width:160px;">' + (i18n.belongs_to || 'Belongs to') + '</th>';
                html += '<th style="width:120px;text-align:right;">' + (i18n.action || 'Action') + '</th>';
                html += '</tr></thead><tbody>';
                for (var j = 0; j < d.events.length; j++) {
                    var ev = d.events[j];
                    var col = typeColors[ev.owner_type] || '#666';
                    var overdueHtml = ev.overdue ? ' <span style="color:#d63638;font-size:11px;">⚠ overdue</span>' : '';
                    html += '<tr>';
                    html += '<td><code>' + $('<span>').text(ev.hook).html() + '</code>' + overdueHtml + '</td>';
                    html += '<td style="font-size:12px;">' + esc_html(ev.next_run) + '</td>';
                    html += '<td style="font-size:12px;">' + esc_html(ev.schedule) + '</td>';
                    html += '<td><span style="color:' + col + ';">' + esc_html(ev.owner) + '</span></td>';
                    html += '<td style="text-align:right;white-space:nowrap;">';
					if (iv1wpt_vars.has_pro) {
						html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-cron-run" data-hook="' + esc_attr(ev.hook) + '" title="' + (i18n.cron_run || 'Run now') + '">';
						html += '<span class="dashicons dashicons-controls-play" aria-hidden="true"></span></button> ';
						if (ev.owner_type !== 'core') {
							html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-cron-delete" data-hook="' + esc_attr(ev.hook) + '" data-ts="' + ev.timestamp + '" title="' + (i18n.delete || 'Delete') + '">';
							html += '<span class="dashicons dashicons-trash" aria-hidden="true"></span></button>';
						}
					}else {
						html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-cron-run" data-hook="' + esc_attr(ev.hook) + '" title="' + (i18n.cron_run || 'Run now') + '" disabled>';
						html += '<span class="dashicons dashicons-controls-play" aria-hidden="true"></span></button> ';
						if (ev.owner_type !== 'core') {
							html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-cron-delete" data-hook="' + esc_attr(ev.hook) + '" data-ts="' + ev.timestamp + '" title="' + (i18n.delete || 'Delete') + '" disabled>';
							html += '<span class="dashicons dashicons-trash" aria-hidden="true"></span></button>';
						}						
					}
                    html += '</td></tr>';
                }
                html += '</tbody></table>';
                $('#iv1wpt-cron-list').html(html);
            }).fail(function() {
                btn.prop('disabled', false).text(i18n.cron_load || 'Load Cron events');
                iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
            });
        });

        function esc_html(str) { return $('<span>').text(str || '').html(); }
        function esc_attr(str) { return $('<span>').text(str || '').html(); }

        $('#iv1wpt-cron-list').on('click', '.iv1wpt-cron-run', function() {
            if (!iv1wpt_vars.has_pro) { window.open(iv1wpt_vars.pro_license_url, '_blank', 'noopener,noreferrer'); return; }
            var btn = $(this), hook = btn.data('hook');
            iv1wpt_confirm(i18n.cron_run || 'Run now', (i18n.cron_run_confirm || 'Run "%s" now?').replace('%s', hook), function(yes) {
                if (!yes) return;
                btn.prop('disabled', true);
                $.post(ajaxurl, { action: 'iv1wpt_cron_run', hook: hook, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    btn.prop('disabled', false);
                    if (resp.success) {
                        $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                    }
                });
            }, i18n.cron_run || 'Run now');
        });

        $('#iv1wpt-cron-list').on('click', '.iv1wpt-cron-delete', function() {
            if (!iv1wpt_vars.has_pro) { window.open(iv1wpt_vars.pro_license_url, '_blank', 'noopener,noreferrer'); return; }
            var btn = $(this), hook = btn.data('hook'), ts = btn.data('ts');
            iv1wpt_confirm(i18n.delete || 'Delete', (i18n.cron_delete_confirm || 'Delete event "%s"?').replace('%s', hook), function(yes) {
                if (!yes) return;
                btn.prop('disabled', true);
                $.post(ajaxurl, { action: 'iv1wpt_cron_delete', hook: hook, timestamp: ts, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    if (resp.success) {
                        btn.closest('tr').fadeOut(300, function() { $(this).remove(); });
                        $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                        btn.prop('disabled', false);
                    }
                });
            }, i18n.yes_delete || 'Yes, delete');
        });

        // ═══════════════════════════════════════════
        // Tab: Tools – Options Cleanup
        // ═══════════════════════════════════════════
        $('#iv1wpt-options-scan').on('click', function() {
            var btn = $(this);
            btn.prop('disabled', true).text(i18n.scanning || 'Scanning...');
            $('#iv1wpt-options-list').html('');
            $('#iv1wpt-options-meta').text('');

            $.post(ajaxurl, { action: 'iv1wpt_options_scan', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                btn.prop('disabled', false).text(i18n.options_scan || 'Scan options');
                if (!resp.success) { iv1wpt_alert_error(i18n.error || 'Error', resp.data); return; }
                var d = resp.data;
                $('#iv1wpt-options-meta').html(
                    '<strong>' + (i18n.options_total || 'Total options: %d').replace('%d', d.total_options) + '</strong> &nbsp;|&nbsp; ' +
                    (i18n.options_autoload || 'Autoloaded: %1$d (%2$s)').replace('%1$d', d.autoload_count).replace('%2$s', iv1wpt_format_size(d.autoload_total_size)) + ' &nbsp;|&nbsp; ' +
                    (i18n.options_db_size || 'Table size: %s').replace('%s', iv1wpt_format_size(d.total_size))
                );
                if (d.options.length === 0) {
                    $('#iv1wpt-options-list').html('<p style="color:#00a32a;">✅ ' + (i18n.options_clean || 'No large or unknown options found.') + '</p>');
                    return;
                }
                var typeColors = { core: '#2271b1', plugin: '#00a32a', transient: '#666', unknown: '#996800' };
                var html = '<table class="widefat striped"><thead><tr>';
                html += '<th>' + (i18n.options_name || 'Option name') + '</th>';
                html += '<th style="width:80px;text-align:right;">' + (i18n.size || 'Size') + '</th>';
                html += '<th style="width:80px;text-align:center;">Autoload</th>';
                html += '<th style="width:100px;">' + (i18n.belongs_to || 'Type') + '</th>';
                html += '<th style="width:130px;text-align:right;">' + (i18n.action || 'Action') + '</th>';
                html += '</tr></thead><tbody>';
                for (var j = 0; j < d.options.length; j++) {
                    var opt = d.options[j];
                    var col = typeColors[opt.type] || '#666';
                    var alIcon = opt.autoload ? '✅' : '❌';
                    html += '<tr data-name="' + esc_attr(opt.name) + '">';
                    html += '<td><code style="font-size:12px;">' + esc_html(opt.name) + '</code></td>';
                    html += '<td style="text-align:right;font-size:12px;">' + iv1wpt_format_size(opt.size) + '</td>';
                    html += '<td style="text-align:center;" class="iv1wpt-opt-autoload">' + alIcon + '</td>';
                    var ownerLabel = opt.owner ? opt.owner : opt.type;
                html += '<td><span style="color:' + col + ';font-size:12px;">' + esc_html(ownerLabel) + '</span></td>';
                    html += '<td style="text-align:right;white-space:nowrap;">';
                    if (opt.type !== 'core') {
                        var newAl = opt.autoload ? 'no' : 'yes';
                        var alTitle = opt.autoload ? (i18n.options_disable_autoload || 'Disable autoload') : (i18n.options_enable_autoload || 'Enable autoload');
						if (iv1wpt_vars.has_pro) {
							html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-opt-toggle" data-name="' + esc_attr(opt.name) + '" data-autoload="' + newAl + '" title="' + alTitle + '">';
							html += '<span class="dashicons dashicons-' + (opt.autoload ? 'minus' : 'plus') + '" aria-hidden="true"></span></button> ';
							if (opt.type !== 'plugin') {
								html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-opt-delete" data-name="' + esc_attr(opt.name) + '" title="' + (i18n.delete || 'Delete') + '">';
								html += '<span class="dashicons dashicons-trash" aria-hidden="true"></span></button>';
							}
						} else {
							html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-opt-toggle" data-name="' + esc_attr(opt.name) + '" data-autoload="' + newAl + '" title="' + alTitle + '" disabled>';
							html += '<span class="dashicons dashicons-' + (opt.autoload ? 'minus' : 'plus') + '" aria-hidden="true"></span></button> ';
							if (opt.type !== 'plugin') {
								html += '<button type="button" class="button button-small iv1wpt-icon-btn iv1wpt-opt-delete" data-name="' + esc_attr(opt.name) + '" title="' + (i18n.delete || 'Delete') + '" disabled>';
								html += '<span class="dashicons dashicons-trash" aria-hidden="true"></span></button>';
							}
						}	
                    }
                    html += '</td></tr>';
                }
                html += '</tbody></table>';
                $('#iv1wpt-options-list').html(html);
            }).fail(function() {
                btn.prop('disabled', false).text(i18n.options_scan || 'Scan options');
                iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
            });
        });

        $('#iv1wpt-options-list').on('click', '.iv1wpt-opt-toggle', function() {
            if (!iv1wpt_vars.has_pro) { window.open(iv1wpt_vars.pro_license_url, '_blank', 'noopener,noreferrer'); return; }
            var btn = $(this), name = btn.data('name'), autoload = btn.data('autoload');
            btn.prop('disabled', true);
            $.post(ajaxurl, { action: 'iv1wpt_options_toggle_autoload', option_name: name, autoload: autoload, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                btn.prop('disabled', false);
                if (resp.success) {
                    var row = btn.closest('tr');
                    var newAl = resp.data.autoload === 'yes';
                    row.find('.iv1wpt-opt-autoload').text(newAl ? '✅' : '❌');
                    btn.data('autoload', newAl ? 'no' : 'yes');
                    btn.find('.dashicons').attr('class', 'dashicons dashicons-' + (newAl ? 'minus' : 'plus'));
                    btn.attr('title', newAl ? (i18n.options_disable_autoload || 'Disable autoload') : (i18n.options_enable_autoload || 'Enable autoload'));
                    $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                } else {
                    iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                }
            });
        });

        $('#iv1wpt-options-list').on('click', '.iv1wpt-opt-delete', function() {
            if (!iv1wpt_vars.has_pro) { window.open(iv1wpt_vars.pro_license_url, '_blank', 'noopener,noreferrer'); return; }
            var btn = $(this), name = btn.data('name');
            iv1wpt_confirm(i18n.delete || 'Delete', (i18n.options_delete_confirm || 'Delete option "%s"?').replace('%s', name), function(yes) {
                if (!yes) return;
                btn.prop('disabled', true);
                $.post(ajaxurl, { action: 'iv1wpt_options_delete', option_name: name, _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                    if (resp.success) {
                        btn.closest('tr').fadeOut(300, function() { $(this).remove(); });
                        $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                        btn.prop('disabled', false);
                    }
                });
            }, i18n.yes_delete || 'Yes, delete');
        });

        // ═══════════════════════════════════════════
        // Tab: Tools – Debug Settings
        // ═══════════════════════════════════════════
        function iv1wpt_debug_load_status() {
            $('#iv1wpt-debug-current').html('<span style="color:#666;">' + (i18n.loading_list || 'Loading...') + '</span>');
            $.post(ajaxurl, { action: 'iv1wpt_debug_status', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                if (!resp.success) { $('#iv1wpt-debug-current').text(resp.data); return; }
                var d = resp.data;
                var icon = function(v) { return v ? '✅' : '❌'; };
                var html = '<table style="border-collapse:collapse;font-size:13px;">';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">WP_DEBUG</td><td>' + icon(d.wp_debug) + ' ' + (d.wp_debug ? '<strong style="color:#00a32a;">active</strong>' : '<span style="color:#999;">inactive</span>') + '</td></tr>';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">WP_DEBUG_LOG</td><td>' + icon(d.wp_debug_log) + ' ' + (d.wp_debug_log ? '<strong style="color:#00a32a;">active</strong>' : '<span style="color:#999;">inactive</span>') + '</td></tr>';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">WP_DEBUG_DISPLAY</td><td>' + icon(d.wp_debug_display) + ' ' + (d.wp_debug_display ? '<strong style="color:#d63638;">active (security risk!)</strong>' : '<span style="color:#00a32a;">inactive (ok)</span>') + '</td></tr>';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">' + (i18n.log_path || 'Log path') + '</td><td><code style="font-size:11px;">' + esc_html(d.log_path) + '</code></td></tr>';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">wp-config.php</td><td>' + (d.config_writable ? '✅ ' + (i18n.debug_writable || 'writable') : '❌ ' + (i18n.debug_not_writable || 'not writable')) + '</td></tr>';
                html += '<tr><td style="padding:3px 12px 3px 0;color:#555;">MU-Plugin</td><td>' + (d.mu_plugin_active ? '✅ ' + (i18n.debug_mu_active || 'active') : '❌ ' + (i18n.debug_mu_inactive || 'inactive')) + '</td></tr>';
                html += '</table>';
                $('#iv1wpt-debug-current').html(html);
                if (!d.config_writable) {
                    $('#iv1wpt-debug-snippet').show();
                }
            }).fail(function() {
                $('#iv1wpt-debug-current').text(i18n.connection_error || 'Connection error');
            });
        }

        if ($('#iv1wpt-debug-current').length) {
            iv1wpt_debug_load_status();
        }

        $('#iv1wpt-debug-refresh').on('click', iv1wpt_debug_load_status);

        function iv1wpt_debug_toggle(enable) {
            var method = $('input[name="iv1wpt_debug_method"]:checked').val() || 'config';
            $.post(ajaxurl, {
                action: 'iv1wpt_debug_toggle',
                enable: enable ? 1 : 0,
                method: method,
                _ajax_nonce: iv1wpt_vars.nonce
            }, function(resp) {
                if (resp.success) {
                    $('#iv1wpt-tools-result').html('<div class="notice notice-success is-dismissible"><p>' + resp.data.message + '</p></div>');
                    iv1wpt_debug_load_status();
                } else {
                    iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                    if (resp.data && resp.data.indexOf('not writable') !== -1) {
                        $('#iv1wpt-debug-snippet').show();
                    }
                }
            }).fail(function() {
                iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
            });
        }

        $('#iv1wpt-debug-enable').on('click', function() {
			if (typeof iv1wpt_vars === 'undefined' || !iv1wpt_vars.has_pro) {
				return;
			}			
            iv1wpt_confirm(
                i18n.debug_enable || 'Enable debug logging',
                i18n.debug_enable_confirm || 'Enable WP_DEBUG and WP_DEBUG_LOG? WP_DEBUG_DISPLAY will be set to false for security.',
                function(yes) { if (yes) iv1wpt_debug_toggle(true); },
                i18n.debug_enable_btn || 'Yes, enable'
            );
        });

        $('#iv1wpt-debug-disable').on('click', function() {
			if (typeof iv1wpt_vars === 'undefined' || !iv1wpt_vars.has_pro) {
				return;
			}		
            iv1wpt_debug_toggle(false);
        });


        // ═══════════════════════════════════════════
        // Tab: CSS / JS Code Editor
        // ═══════════════════════════════════════════
        var iv1wpt_css_cm = null;
        var iv1wpt_js_cm  = null;


        function iv1wpt_ce_init_cm(id, wrap_id, mode) {
            var ta = document.getElementById(id);
            if (!ta || !window.wp || !wp.codeEditor) return null;
            var settings = wp.codeEditor.defaultSettings ? _.clone(wp.codeEditor.defaultSettings) : {};
            settings.codemirror = _.extend({}, settings.codemirror, {
                mode: mode,
                lineNumbers: true,
                lineWrapping: true,
                indentUnit: 4,
                tabSize: 4,
                autoCloseBrackets: true,
                matchBrackets: true,
                theme: 'default',
            });
            var editor = wp.codeEditor.initialize(ta, settings);
            if (editor && editor.codemirror) {
                var wrap = document.getElementById(wrap_id);
                if (wrap) {
                    editor.codemirror.setSize('100%', '500px');
                    wrap.appendChild(editor.codemirror.getWrapperElement());
                }
            }
            return editor ? editor.codemirror : null;
        }

        // CSS Editor initialisieren
        if ($('#iv1wpt-css-cm').length) {
            // Einstellungen laden
            $.post(ajaxurl, { action: 'iv1wpt_codeeditor_load', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                if (!resp.success) return;
                var d = resp.data;
                $('#iv1wpt-css-enabled').prop('checked', d.css_enabled);
                $('#iv1wpt-css-position').val(d.css_position || 'header');
                if (d.css_position === 'footer') $('#iv1wpt-css-fouc-warning').show();
                $('#iv1wpt-css-file-path').text(d.css_file || 'wp-content/iv1-custom.css');
                if (d.css_size) $('#iv1wpt-css-size').text(iv1wpt_format_size(d.css_size));

                // CodeMirror initialisieren
                iv1wpt_css_cm = iv1wpt_ce_init_cm('iv1wpt-css-editor', 'iv1wpt-css-cm', 'text/css');
                if (iv1wpt_css_cm) {
                    iv1wpt_css_cm.setValue(d.css_content || '/* Custom CSS */\n');
                    setTimeout(function() { iv1wpt_css_cm.refresh(); }, 100);
                } else {
                    // Fallback: plain textarea
                    $('#iv1wpt-css-editor').val(d.css_content || '/* Custom CSS */\n').show();
                    $('#iv1wpt-css-cm').hide();
                }
            });

            // CSS speichern
            $('#iv1wpt-css-save').on('click', function() {
                var btn     = $(this);
                var content = iv1wpt_css_cm ? iv1wpt_css_cm.getValue() : $('#iv1wpt-css-editor').val();
                var enabled = $('#iv1wpt-css-enabled').is(':checked') ? 1 : 0;
                btn.prop('disabled', true).text(i18n.code_saving || 'Saving...');
                var css_position = $('#iv1wpt-css-position').val();
                $.post(ajaxurl, {
                    action:   'iv1wpt_codeeditor_save_css',
                    content:  content,
                    enabled:  enabled,
                    position: css_position,
                    _ajax_nonce: iv1wpt_vars.nonce
                }, function(resp) {
                    btn.prop('disabled', false).text(i18n.css_save || 'Save CSS');
                    if (resp.success) {
                        $('#iv1wpt-codeeditor-result').html('<div class="notice notice-success is-dismissible"><p>✅ ' + resp.data.message + '</p></div>');
                        if (resp.data.size !== undefined) $('#iv1wpt-css-size').text(iv1wpt_format_size(resp.data.size));
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                    }
                }).fail(function() {
                    btn.prop('disabled', false).text(i18n.css_save || 'Save CSS');
                    iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
                });
            });

            // FOUC-Warnung bei Footer-Position
            $('#iv1wpt-css-position').on('change', function() {
                if ($(this).val() === 'footer') {
                    $('#iv1wpt-css-fouc-warning').slideDown(200);
                } else {
                    $('#iv1wpt-css-fouc-warning').slideUp(200);
                }
            });

            // Ctrl+S / Cmd+S zum Speichern
            $(document).on('keydown', function(e) {
                if ((e.ctrlKey || e.metaKey) && e.key === 's' && $('#iv1wpt-css-cm').is(':visible')) {
                    e.preventDefault();
                    $('#iv1wpt-css-save').trigger('click');
                }
            });
        }

        // JS Editor initialisieren
        if ($('#iv1wpt-js-cm').length) {
            $.post(ajaxurl, { action: 'iv1wpt_codeeditor_load', _ajax_nonce: iv1wpt_vars.nonce }, function(resp) {
                if (!resp.success) return;
                var d = resp.data;
                $('#iv1wpt-js-enabled').prop('checked', d.js_enabled);
                $('#iv1wpt-js-position').val(d.js_position || 'footer');
                $('#iv1wpt-js-file-path').text(d.js_file || 'wp-content/iv1-custom.js');
                if (d.js_size) $('#iv1wpt-js-size').text(iv1wpt_format_size(d.js_size));

                iv1wpt_js_cm = iv1wpt_ce_init_cm('iv1wpt-js-editor', 'iv1wpt-js-cm', 'text/javascript');
                if (iv1wpt_js_cm) {
                    iv1wpt_js_cm.setValue(d.js_content || '/* Custom JavaScript */\n');
                    setTimeout(function() { iv1wpt_js_cm.refresh(); }, 100);
                } else {
                    $('#iv1wpt-js-editor').val(d.js_content || '/* Custom JavaScript */\n').show();
                    $('#iv1wpt-js-cm').hide();
                }
            });

            // JS speichern
            $('#iv1wpt-js-save').on('click', function() {
                var btn      = $(this);
                var content  = iv1wpt_js_cm ? iv1wpt_js_cm.getValue() : $('#iv1wpt-js-editor').val();
                var enabled  = $('#iv1wpt-js-enabled').is(':checked') ? 1 : 0;
                var position = $('#iv1wpt-js-position').val();
                btn.prop('disabled', true).text(i18n.code_saving || 'Saving...');
                $.post(ajaxurl, {
                    action:   'iv1wpt_codeeditor_save_js',
                    content:  content,
                    enabled:  enabled,
                    position: position,
                    _ajax_nonce: iv1wpt_vars.nonce
                }, function(resp) {
                    btn.prop('disabled', false).text(i18n.js_save || 'Save JS');
                    if (resp.success) {
                        $('#iv1wpt-codeeditor-result').html('<div class="notice notice-success is-dismissible"><p>✅ ' + resp.data.message + '</p></div>');
                        if (resp.data.size !== undefined) $('#iv1wpt-js-size').text(iv1wpt_format_size(resp.data.size));
                    } else {
                        iv1wpt_alert_error(i18n.error || 'Error', resp.data);
                    }
                }).fail(function() {
                    btn.prop('disabled', false).text(i18n.js_save || 'Save JS');
                    iv1wpt_alert_error(i18n.error || 'Error', i18n.connection_failed || 'Connection failed.');
                });
            });

            // Ctrl+S / Cmd+S
            $(document).on('keydown', function(e) {
                if ((e.ctrlKey || e.metaKey) && e.key === 's' && $('#iv1wpt-js-cm').is(':visible')) {
                    e.preventDefault();
                    $('#iv1wpt-js-save').trigger('click');
                }
            });
        }

		// ═══════════════════════════════════════════
		// Tab: File Monitor
		// ═══════════════════════════════════════════
		$('#iv1wpt-filemonitor-baseline').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();

			btn.prop('disabled', true).text(i18n.filemonitor_creating_baseline || 'Creating baseline...');

			$('#iv1wpt-filemonitor-result').html(
				'<div class="notice notice-info inline"><p>' +
				(i18n.filemonitor_creating_baseline || 'Creating baseline...') +
				'</p></div>'
			);

			$.post(ajaxurl, {
				action: 'iv1wpt_filemonitor_create_baseline',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {

				if (response.success) {
					var d = response.data || {};

					btn.prop('disabled', false).text(
						i18n.filemonitor_update_baseline || 'Update baseline'
					);					

					$('#iv1wpt-filemonitor-baseline-status').text(
						i18n.filemonitor_available || 'Available'
					);

					$('#iv1wpt-filemonitor-baseline-date').text(d.created_at || '—');
					$('#iv1wpt-filemonitor-baseline-count').text(d.count || 0);

					$('#iv1wpt-filemonitor-result').html(
						'<div class="notice notice-success is-dismissible"><p>✅ ' +
						(d.message || i18n.filemonitor_baseline_created || 'Baseline created successfully.') +
						'</p></div>'
					);
					
					setTimeout(function() {
						$('#iv1wpt-filemonitor-result .notice').fadeOut(300, function() {
							$(this).remove();
						});
					}, 5000);					
					
				} else {
					btn.prop('disabled', false).text(originalText);

					$('#iv1wpt-filemonitor-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
				}
			}).fail(function() {
				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-filemonitor-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		});

		$('#iv1wpt-filemonitor-scan').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();

			btn.prop('disabled', true).text(i18n.filemonitor_scanning_changes || 'Scanning changes...');

			$('#iv1wpt-filemonitor-result').html(
				'<div class="notice notice-info inline"><p>' +
				(i18n.filemonitor_scanning_changes || 'Scanning changes...') +
				'</p></div>'
			);

			$.post(ajaxurl, {
				action: 'iv1wpt_filemonitor_scan_changes',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (!response.success) {
					$('#iv1wpt-filemonitor-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
					return;
				}

				var d = response.data || {};
				var summary = d.summary || {};
				var result = d.result || {};

				var added = parseInt(summary.added || 0, 10);
				var changed = parseInt(summary.changed || 0, 10);
				var deleted = parseInt(summary.deleted || 0, 10);

				var html = '';

				html += '<div class="notice notice-success is-dismissible"><p>✅ ' +
					(d.message || i18n.filemonitor_scan_completed || 'Scan completed.') +
					'</p></div>';

				if (added === 0 && changed === 0 && deleted === 0) {
					html += '<div class="notice notice-success inline"><p>✅ ' +
						(i18n.filemonitor_no_changes || 'No file changes detected.') +
						'</p></div>';
				}

				html += '<table class="widefat striped" style="margin-top:12px;">';
				html += '<thead><tr>';
				html += '<th>' + (i18n.filemonitor_status || 'Status') + '</th>';
				html += '<th>' + (i18n.filemonitor_entries || 'Entries') + '</th>';
				html += '</tr></thead>';
				html += '<tbody>';
				html += '<tr><td>' + (i18n.filemonitor_new_files || 'New files') + '</td><td><strong>' + added + '</strong></td></tr>';
				html += '<tr><td>' + (i18n.filemonitor_changed_files || 'Changed files') + '</td><td><strong>' + changed + '</strong></td></tr>';
				html += '<tr><td>' + (i18n.filemonitor_deleted_files || 'Deleted files') + '</td><td><strong>' + deleted + '</strong></td></tr>';
				html += '</tbody></table>';

				html += ssbRenderFileMonitorList(i18n.filemonitor_new_files || 'New files', result.added);
				html += ssbRenderFileMonitorList(i18n.filemonitor_changed_files || 'Changed files', result.changed);
				html += ssbRenderFileMonitorList(i18n.filemonitor_deleted_files || 'Deleted files', result.deleted);

				$('#iv1wpt-filemonitor-result').html(html);

				setTimeout(function() {
					$('#iv1wpt-filemonitor-result .notice').fadeOut(300, function() {
						$(this).remove();
					});
				}, 5000);


			}).fail(function() {
				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-filemonitor-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		});

		function ssbRenderFileMonitorList(title, items) {
			if (!items || Object.keys(items).length === 0) {
				return '';
			}

			var html = '';

			html += '<h3 style="margin-top:18px;">' + ssbEscapeHtml(title) + '</h3>';
			html += '<table class="widefat striped">';
			html += '<thead><tr>';
			html += '<th>' + (i18n.filemonitor_file || 'File') + '</th>';
			html += '<th>' + (i18n.filemonitor_size || 'Size') + '</th>';
			html += '<th>' + (i18n.filemonitor_modified || 'Modified at') + '</th>';
			html += '</tr></thead>';
			html += '<tbody>';

			$.each(items, function(path, data) {
				var fileData = data.new || data;

				html += '<tr>';
				html += '<td><code>' + ssbEscapeHtml(path) + '</code></td>';
				html += '<td>' + ssbFormatBytes(fileData.size || 0) + '</td>';
				html += '<td>' + ssbFormatTimestamp(fileData.mtime || 0) + '</td>';
				html += '</tr>';
			});

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

			return html;
		}

		$('#iv1wpt-filemonitor-core-check').on('click', function(e) {
			e.preventDefault();

			var btn = $(this);
			var originalText = btn.text();

			btn.prop('disabled', true).text(i18n.filemonitor_checking_core || 'Checking core...');

			$('#iv1wpt-filemonitor-result').html(
				'<div class="notice notice-info inline"><p>' +
				(i18n.filemonitor_checking_core || 'Checking core...') +
				'</p></div>'
			);

			$.post(ajaxurl, {
				action: 'iv1wpt_filemonitor_check_core',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (!response.success) {
					$('#iv1wpt-filemonitor-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
					return;
				}

				var d = response.data || {};
				var items = d.items || {};
				var html = '';

				html += '<div class="notice ' + (d.status === 'clean' ? 'notice-success' : 'notice-warning') + ' is-dismissible"><p>' +
					(d.status === 'clean' ? '✅ ' : '⚠️ ') +
					(d.message || '') +
					'</p></div>';

				if (items && Object.keys(items).length > 0) {
					html += '<h3 style="margin-top:18px;">' + (i18n.filemonitor_core_changes || 'Core file changes') + '</h3>';
					html += '<table class="widefat striped">';
					html += '<thead><tr>';
					html += '<th>' + (i18n.filemonitor_file || 'File') + '</th>';
					html += '<th>' + (i18n.filemonitor_status || 'Status') + '</th>';
					html += '</tr></thead>';
					html += '<tbody>';

					$.each(items, function(file, status) {
						html += '<tr>';
						html += '<td><code>' + ssbEscapeHtml(file) + '</code></td>';
						html += '<td>' + ssbEscapeHtml(status) + '</td>';
						html += '</tr>';
					});

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

				$('#iv1wpt-filemonitor-result').html(html);

				setTimeout(function() {
					$('#iv1wpt-filemonitor-result .notice').fadeOut(300, function() {
						$(this).remove();
					});
				}, 5000);

			}).fail(function() {
				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-filemonitor-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		});


		function ssbEscapeHtml(str) {
			return String(str)
				.replace(/&/g, '&amp;')
				.replace(/</g, '&lt;')
				.replace(/>/g, '&gt;')
				.replace(/"/g, '&quot;')
				.replace(/'/g, '&#039;');
		}

		function ssbFormatBytes(bytes) {
			bytes = parseInt(bytes, 10) || 0;

			if (bytes < 1024) return bytes + ' B';

			var kb = bytes / 1024;
			if (kb < 1024) return kb.toFixed(2) + ' KB';

			var mb = kb / 1024;
			if (mb < 1024) return mb.toFixed(2) + ' MB';

			var gb = mb / 1024;
			return gb.toFixed(2) + ' GB';
		}

		function ssbFormatTimestamp(timestamp) {
			timestamp = parseInt(timestamp, 10) || 0;

			if (!timestamp) {
				return '—';
			}

			var date = new Date(timestamp * 1000);

			return date.toLocaleString();
		}


		// ═══════════════════════════════════════════
		// Tab: Activity Log
		// ═══════════════════════════════════════════
		$('#iv1wpt-activity-load').on('click', function(e) {
			e.preventDefault();

			if (typeof iv1wpt_vars === 'undefined' || !iv1wpt_vars.has_pro) {
				return;
			}			

			var btn = $(this);
			var originalText = btn.text();
			var limit = $('#iv1wpt-activity-limit').val();

			btn.prop('disabled', true).text(i18n.loading || 'Loading...');

			$('#iv1wpt-activity-result').html(
				'<div class="notice notice-info inline"><p>' +
				(i18n.loading || 'Loading...') +
				'</p></div>'
			);

			$.post(ajaxurl, {
				action: 'iv1wpt_activity_load',
				_ajax_nonce: iv1wpt_vars.nonce,
				limit: limit
			}, function(response) {

				btn.prop('disabled', false).text(originalText);

				if (!response.success) {
					$('#iv1wpt-activity-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
					return;
				}

				$('#iv1wpt-activity-result').html(response.data.html || '');

			}).fail(function() {

				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-activity-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		});
		
		if (typeof iv1wpt_vars !== 'undefined' && iv1wpt_vars.has_pro && $('#iv1wpt-activity-load').length) {
			$('#iv1wpt-activity-load').trigger('click');
		}

		$('#iv1wpt-activity-clear').on('click', function(e) {
			e.preventDefault();

			if (typeof iv1wpt_vars === 'undefined' || !iv1wpt_vars.has_pro) {
				return;
			}

			var btn = $(this);
			var originalText = btn.text();

			iv1wpt_confirm(
				i18n.activity_clear_title || 'Clear activity log',
				'<p>' + (i18n.activity_clear_confirm || 'Really clear the activity log?') + '</p>',
				function(confirmed) {
					if (!confirmed) {
						return;
					}

					btn.prop('disabled', true).text(i18n.clearing || 'Clearing...');

					$.post(ajaxurl, {
						action: 'iv1wpt_activity_clear',
						_ajax_nonce: iv1wpt_vars.nonce
					}, function(response) {
						btn.prop('disabled', false).text(originalText);

						if (!response.success) {
							$('#iv1wpt-activity-result').html(
								'<div class="notice notice-error"><p>' +
								(response.data || i18n.error || 'Error') +
								'</p></div>'
							);
							return;
						}

						$('#iv1wpt-activity-result').html(
							'<div class="notice notice-success is-dismissible"><p>✅ ' +
							(response.data.message || i18n.activity_cleared || 'Activity log cleared.') +
							'</p></div>'
						);

						setTimeout(function() {
							$('#iv1wpt-activity-result .notice').fadeOut(300, function() {
								$(this).remove();
							});
						}, 5000);

						$('#iv1wpt-activity-load').trigger('click');

					}).fail(function() {
						btn.prop('disabled', false).text(originalText);

						$('#iv1wpt-activity-result').html(
							'<div class="notice notice-error"><p>' +
							(i18n.connection_error || 'Connection error') +
							'</p></div>'
						);
					});
				},
				i18n.yes_clear || 'Yes, clear'
			);
		});

		// ═══════════════════════════════════════════
		// Tab: Logs
		// ═══════════════════════════════════════════
		function ssbLoadLogFiles() {
			var select = $('#iv1wpt-log-file');

			if (!select.length) {
				return;
			}

			select.prop('disabled', true).html(
				'<option value="">' + (i18n.loading || 'Loading...') + '</option>'
			);

			$('#iv1wpt-logs-result').html('');

			$.post(ajaxurl, {
				action: 'iv1wpt_logs_load_list',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {
				select.prop('disabled', false);

				if (!response.success) {
					select.html('<option value="">' + (i18n.error || 'Error') + '</option>');
					$('#iv1wpt-logs-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
					return;
				}

				select.html(response.data.options || '');

				if (response.data.has_logs) {
					$('#iv1wpt-log-view').trigger('click');
				} else {
					$('#iv1wpt-logs-result').html(
						'<div class="notice notice-info inline"><p>' +
						(i18n.logs_not_found || 'No log files found.') +
						'</p></div>'
					);
				}
			}).fail(function() {
				select.prop('disabled', false).html(
					'<option value="">' + (i18n.error || 'Error') + '</option>'
				);

				$('#iv1wpt-logs-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		}

		function ssbViewSelectedLog() {
			var file = $('#iv1wpt-log-file').val();
			var lines = $('#iv1wpt-log-lines').val();
			var btn = $('#iv1wpt-log-view');
			var originalText = btn.text();

			if (!file) {
				$('#iv1wpt-logs-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.logs_no_file || 'No log file selected.') +
					'</p></div>'
				);
				return;
			}

			btn.prop('disabled', true).text(i18n.loading || 'Loading...');

			$('#iv1wpt-logs-result').html(
				'<div class="notice notice-info inline"><p>' +
				(i18n.loading || 'Loading...') +
				'</p></div>'
			);

			$.post(ajaxurl, {
				action: 'iv1wpt_logs_view',
				_ajax_nonce: iv1wpt_vars.nonce,
				file: file,
				lines: lines
			}, function(response) {
				btn.prop('disabled', false).text(originalText);

				if (!response.success) {
					$('#iv1wpt-logs-result').html(
						'<div class="notice notice-error"><p>' +
						(response.data || i18n.error || 'Error') +
						'</p></div>'
					);
					return;
				}

				$('#iv1wpt-logs-result').html(response.data.html || '');
			}).fail(function() {
				btn.prop('disabled', false).text(originalText);

				$('#iv1wpt-logs-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.connection_error || 'Connection error') +
					'</p></div>'
				);
			});
		}

		$('#iv1wpt-logs-load').on('click', function(e) {
			e.preventDefault();
			ssbLoadLogFiles();
		});

		$(document).on('click', '#iv1wpt-log-view', function(e) {
			e.preventDefault();
			ssbViewSelectedLog();
		});

		$(document).on('change', '#iv1wpt-log-file, #iv1wpt-log-lines', function() {
			ssbViewSelectedLog();
		});

		$('#iv1wpt-logs-clear').on('click', function(e) {
			e.preventDefault();

			var file = $('#iv1wpt-log-file').val();

			if (!file) {
				$('#iv1wpt-logs-result').html(
					'<div class="notice notice-error"><p>' +
					(i18n.logs_no_file || 'No log file selected.') +
					'</p></div>'
				);
				return;
			}

			iv1wpt_confirm(
				i18n.logs_clear_title || 'Clear log file',
				'<p>' + (i18n.logs_clear_confirm || 'Really clear the selected log file?') + '</p><p><code>' + ssbEscapeHtml(file) + '</code></p>',
				function(confirmed) {
					if (!confirmed) {
						return;
					}

					$.post(ajaxurl, {
						action: 'iv1wpt_logs_clear',
						_ajax_nonce: iv1wpt_vars.nonce,
						file: file
					}, function(response) {
						if (!response.success) {
							$('#iv1wpt-logs-result').html(
								'<div class="notice notice-error"><p>' +
								(response.data || i18n.error || 'Error') +
								'</p></div>'
							);
							return;
						}

						$('#iv1wpt-logs-result').html(
							'<div class="notice notice-success is-dismissible"><p>✅ ' +
							(response.data.message || i18n.logs_cleared || 'Log file cleared.') +
							'</p></div>'
						);

						setTimeout(function() {
							ssbViewSelectedLog();
						}, 600);
					}).fail(function() {
						$('#iv1wpt-logs-result').html(
							'<div class="notice notice-error"><p>' +
							(i18n.connection_error || 'Connection error') +
							'</p></div>'
						);
					});
				},
				i18n.yes_clear || 'Yes, clear'
			);
		});

		if ($('#iv1wpt-log-file').length) {
			ssbLoadLogFiles();
		}

		// ── ESC-Taste: alle Modals schließen ────────────────────────────────────
		$(document).on('keydown', function(e) {
			if (e.key !== 'Escape') return;
			if ($('#iv1wpt-modal').hasClass('active'))       iv1wpt_modal_close();
			if ($('#iv1wpt-vs-modal').hasClass('active'))    $('#iv1wpt-vs-modal').removeClass('active');
			if ($('#iv1wpt-vs-db-modal').hasClass('active')) $('#iv1wpt-vs-db-modal').removeClass('active');
		});

		// ── Virus Scanner  ────────────────────────────────────

		var ssbVsSeverityLabel = function(sev) {
			var labels = { critical: '🔴 KRITISCH', high: '🟠 HOCH', medium: '🟡 MITTEL', low: '🔵 NIEDRIG' };
			return labels[sev] || sev;
		};

		var ssbVsSeverityClass = function(sev) {
			var map = { critical: '#c0392b', high: '#e67e22', medium: '#f1c40f', low: '#3498db' };
			return map[sev] || '#999';
		};

		// Datei-Signatur-Scan
		$('#iv1wpt-vs-scan-files').on('click', function() {
			var btn   = $(this);
			var scope = $('#iv1wpt-vs-scope').val();
			btn.prop('disabled', true).text('⏳ ' + (i18n.vs_scanning || 'Scanning...'));
			$('#iv1wpt-vs-files-result').html('<div class="notice notice-info"><p>⏳ ' + (i18n.vs_scanning || 'Scanning files – this may take a moment...') + '</p></div>');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_scan_files',
				_ajax_nonce: iv1wpt_vars.nonce,
				scope: scope
			}, function(response) {
				btn.prop('disabled', false).text('' + (i18n.vs_start_file_scan || 'Start file scan'));
				if (!response.success) {
					$('#iv1wpt-vs-files-result').html('<div class="notice notice-error"><p>' + ssbEscapeHtml(response.data || 'Error') + '</p></div>');
					return;
				}
				var d = response.data;
				var findings = d.findings || [];
				var statusClass = findings.length === 0 ? 'notice-success' : 'notice-warning';
				var icon = findings.length === 0 ? '✅' : '⚠️';
				var html = '<div class="notice ' + statusClass + '"><p>' + icon + ' ' + ssbEscapeHtml(d.message) + '</p>';
				html += '<p style="margin:4px 0 0;font-size:12px;color:#555;">' +
					(i18n.vs_scanned || 'Scanned') + ': <strong>' + d.scanned + '</strong> &nbsp;|&nbsp; ' +
					(i18n.vs_skipped || 'Skipped') + ': <strong>' + d.skipped + '</strong>' +
					(d.errors > 0 ? ' &nbsp;|&nbsp; Errors: <strong>' + d.errors + '</strong>' : '') +
					'</p></div>';

					if (findings.length > 0) {
						html += '<table class="widefat striped" style="margin-top:12px;table-layout:fixed;width:100%;">';
						html += '<colgroup>';
						html += '<col style="width:110px;">';   /* Schweregrad */
						html += '<col>';                         /* Datei – flexibel */
						html += '<col style="width:140px;">';   /* Muster */
						html += '<col style="width:60px;">';    /* Zeile */
						html += '<col style="width:260px;">';   /* Code-Ausschnitt */
						html += '<col style="width:90px;">';    /* Aktionen */
						html += '</colgroup>';
						html += '<thead><tr>';
						html += '<th>' + (i18n.vs_severity || 'Severity') + '</th>';
						html += '<th>' + (i18n.vs_file || 'File') + '</th>';
						html += '<th>' + (i18n.vs_signature || 'Pattern') + '</th>';
						html += '<th>' + (i18n.vs_line || 'Line') + '</th>';
						html += '<th>' + (i18n.vs_context || 'Code excerpt') + '</th>';
						html += '<th style="text-align:center;">' + (i18n.vs_actions || 'Actions') + '</th>';
						html += '</tr></thead><tbody>';

						$.each(findings, function(i, f) {
							var color = ssbVsSeverityClass(f.severity);
							html += '<tr data-file="' + ssbEscapeHtml(f.file) + '">';
							html += '<td><span style="font-weight:bold;color:' + color + ';">' + ssbVsSeverityLabel(f.severity) + '</span></td>';
							html += '<td style="font-family:monospace;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.file) + '">' + ssbEscapeHtml(f.file) + '</td>';
							html += '<td><code style="font-size:11px;">' + ssbEscapeHtml(f.signature) + '</code></td>';
							html += '<td style="text-align:center;">' + (f.line > 0 ? f.line : '—') + '</td>';
							html += '<td style="font-family:monospace;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.context) + '">' + ssbEscapeHtml(f.context.substring(0, 120)) + (f.context.length > 120 ? '…' : '') + '</td>';
							html += '<td style="text-align:center;"><button class="button button-small iv1wpt-icon-btn iv1wpt-vs-view-file" data-file="' + ssbEscapeHtml(f.file) + '" title="' + ssbEscapeHtml(i18n.vs_view_file || 'View') + '" aria-label="' + ssbEscapeHtml(i18n.vs_view_file || 'View') + '">' +
								'<span class="dashicons dashicons-visibility" aria-hidden="true"></span>' +
							'</button></td>';							
							
							html += '</tr>';
						});

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


				$('#iv1wpt-vs-files-result').html(html);
			}).fail(function() {
				btn.prop('disabled', false).text('' + (i18n.vs_start_file_scan || 'Start file scan'));
				$('#iv1wpt-vs-files-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>');
			});
		});

		// Upload-Verzeichnis-Scan
		$('#iv1wpt-vs-scan-uploads').on('click', function() {
			var btn = $(this);
			btn.prop('disabled', true).text('⏳ ' + (i18n.vs_scanning || 'Scanning...'));
			$('#iv1wpt-vs-uploads-result').html('<div class="notice notice-info"><p>⏳ ' + (i18n.vs_scanning || 'Scanning...') + '</p></div>');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_scan_uploads',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {
				btn.prop('disabled', false).text('' + (i18n.vs_scan_uploads || 'Scan upload directory'));
				if (!response.success) {
					$('#iv1wpt-vs-uploads-result').html('<div class="notice notice-error"><p>' + ssbEscapeHtml(response.data || 'Error') + '</p></div>');
					return;
				}
				var d = response.data;
				var findings = d.findings || [];
				var statusClass = findings.length === 0 ? 'notice-success' : 'notice-error';
				var icon = findings.length === 0 ? '✅' : '🚨';
				var html = '<div class="notice ' + statusClass + '"><p>' + icon + ' ' + ssbEscapeHtml(d.message) + '</p></div>';

				if (findings.length > 0) {
					html += '<table class="widefat striped" style="margin-top:12px;table-layout:fixed;width:100%;">';
					html += '<colgroup>';
					html += '<col style="width:110px;">';  /* Schweregrad */
					html += '<col>';                        /* Datei – flexibel */
					html += '<col style="width:60px;">';   /* Typ */
					html += '<col style="width:100px;">';   /* Größe */
					html += '<col style="width:120px;">';  /* Geändert */
					html += '<col style="width:180px;">';  /* Grund */
					html += '<col style="width:100px;">';   /* Aktionen */
					html += '</colgroup>';
					html += '<thead><tr>';
					html += '<th>' + (i18n.vs_severity || 'Severity') + '</th>';
					html += '<th>' + (i18n.vs_file || 'File') + '</th>';
					html += '<th>' + (i18n.vs_file_type || 'Type') + '</th>';
					html += '<th>' + (i18n.size || 'Size') + '</th>';
					html += '<th>' + (i18n.filemonitor_modified || 'Modified') + '</th>';
					html += '<th>' + (i18n.vs_reason || 'Reason') + '</th>';
					html += '<th style="text-align:center;">' + (i18n.vs_actions || 'Actions') + '</th>';
					html += '</tr></thead><tbody>';

					$.each(findings, function(i, f) {
						html += '<tr data-file="' + ssbEscapeHtml(f.file) + '">';
						html += '<td><span style="font-weight:bold;color:' + ssbVsSeverityClass(f.severity) + ';">' + ssbVsSeverityLabel(f.severity) + '</span></td>';
						html += '<td style="font-family:monospace;font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.file) + '">' + ssbEscapeHtml(f.file) + '</td>';
						html += '<td><code style="font-size:11px;">' + ssbEscapeHtml(f.type) + '</code></td>';
						html += '<td>' + (f.size > 1024 ? Math.round(f.size / 1024) + ' KB' : f.size + ' B') + '</td>';
						html += '<td style="font-size:11px;">' + ssbEscapeHtml(f.mtime) + '</td>';
						html += '<td style="font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.reason) + '">' + ssbEscapeHtml(f.reason) + '</td>';
						html += '<td style="text-align:center;">' +
							'<button class="button button-small iv1wpt-icon-btn iv1wpt-vs-view-file" data-file="' + ssbEscapeHtml(f.file) + '" title="' + ssbEscapeHtml(i18n.vs_view_file || 'View') + '" aria-label="' + ssbEscapeHtml(i18n.vs_view_file || 'View') + '">' +
								'<span class="dashicons dashicons-visibility" aria-hidden="true"></span>' +
							'</button>' +
						'</td>';
						html += '</tr>';
					});

					html += '</tbody></table>';
				}
				
				$('#iv1wpt-vs-uploads-result').html(html);
			}).fail(function() {
				btn.prop('disabled', false).text('' + (i18n.vs_scan_uploads || 'Scan upload directory'));
				$('#iv1wpt-vs-uploads-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>');
			});
		});

		// Datenbank-Scan
		$('#iv1wpt-vs-scan-db').on('click', function() {
			var btn = $(this);
			btn.prop('disabled', true).text('⏳ ' + (i18n.vs_scanning || 'Scanning...'));
			$('#iv1wpt-vs-db-result').html('<div class="notice notice-info"><p>⏳ ' + (i18n.vs_scanning_db || 'Scanning database – this may take a moment...') + '</p></div>');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_scan_database',
				_ajax_nonce: iv1wpt_vars.nonce
			}, function(response) {
				btn.prop('disabled', false).text('' + (i18n.vs_start_db_scan || 'Start database scan'));
				if (!response.success) {
					$('#iv1wpt-vs-db-result').html('<div class="notice notice-error"><p>' + ssbEscapeHtml(response.data || 'Error') + '</p></div>');
					return;
				}
				var d = response.data;
				var findings = d.findings || [];
				var statusClass = findings.length === 0 ? 'notice-success' : 'notice-warning';
				var icon = findings.length === 0 ? '✅' : '⚠️';
				var html = '<div class="notice ' + statusClass + '"><p>' + icon + ' ' + ssbEscapeHtml(d.message) + '</p></div>';
				
				if (findings.length > 0) {
					html += '<table class="widefat striped" style="margin-top:12px;table-layout:fixed;width:100%;">';
					html += '<colgroup>';
					html += '<col style="width:110px;">';  /* Schweregrad */
					html += '<col style="width:180px;">';  /* Tabelle */
					html += '<col style="width:120px;">';  /* Spalte */
					html += '<col style="width:140px;">';  /* Muster */
					html += '<col style="width:70px;">';   /* Treffer */
					html += '<col style="width:50px;">';   /* Aktionen */
					html += '</colgroup>';
					html += '<thead><tr>';
					html += '<th>' + (i18n.vs_severity || 'Severity') + '</th>';
					html += '<th>' + (i18n.vs_table || 'Table') + '</th>';
					html += '<th>' + (i18n.vs_column || 'Column') + '</th>';
					html += '<th>' + (i18n.vs_pattern || 'Pattern') + '</th>';
					html += '<th style="text-align:center;">' + (i18n.vs_db_hits || 'Hits') + '</th>';
					html += '<th style="text-align:center;">' + (i18n.vs_actions || 'Actions') + '</th>';
					html += '</tr></thead><tbody>';

					$.each(findings, function(i, f) {
						html += '<tr>';
						html += '<td><span style="font-weight:bold;color:' + ssbVsSeverityClass(f.severity) + ';">' + ssbVsSeverityLabel(f.severity) + '</span></td>';
						html += '<td style="font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.table) + '"><code style="font-size:11px;">' + ssbEscapeHtml(f.table) + '</code></td>';
						html += '<td style="font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.column) + '"><code style="font-size:11px;">' + ssbEscapeHtml(f.column) + '</code></td>';
						html += '<td style="font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + ssbEscapeHtml(f.pattern) + '"><code style="font-size:11px;">' + ssbEscapeHtml(f.pattern) + '</code></td>';
						html += '<td style="text-align:center;"><strong>' + f.count + '</strong></td>';
						html += '<td style="text-align:center;">' +
							'<button class="button button-small iv1wpt-icon-btn iv1wpt-vs-view-db" ' +
								'data-table="' + ssbEscapeHtml(f.table) + '" ' +
								'data-column="' + ssbEscapeHtml(f.column) + '" ' +
								'data-pattern-id="' + ssbEscapeHtml(f.pattern) + '" ' +
								'title="' + ssbEscapeHtml(i18n.vs_db_records_btn || 'Records') + '" ' +
								'aria-label="' + ssbEscapeHtml(i18n.vs_db_records_btn || 'Records') + '">' +
								'<span class="dashicons dashicons-search" aria-hidden="true"></span>' +
							'</button>' +
						'</td>';
						html += '</tr>';
					});

					html += '</tbody></table>';
					html += '<p style="margin-top:8px;font-size:12px;color:#555;">💡 ' + (i18n.vs_db_hint || 'Tip: Create a database backup before making any changes.') + '</p>';
				}				
				
				$('#iv1wpt-vs-db-result').html(html);
			}).fail(function() {
				btn.prop('disabled', false).text('' + (i18n.vs_start_db_scan || 'Start database scan'));
				$('#iv1wpt-vs-db-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>');
			});
		});

		// ── Modal: Dateiinhalt anzeigen / löschen ──────────────────────────────
		// Modal schließen
		$(document).on('click', '#iv1wpt-vs-modal-close, #iv1wpt-vs-modal', function(e) {
			if (e.target === this) $('#iv1wpt-vs-modal').removeClass('active');
		});

		// Dateiinhalt laden und Modal öffnen
		$(document).on('click', '.iv1wpt-vs-view-file', function() {
			var file = $(this).data('file');
			$('#iv1wpt-vs-modal-title').text(file);
			$('#iv1wpt-vs-modal-meta').text((i18n.loading || 'Loading...'));
			$('#iv1wpt-vs-modal-code').text('');
			$('#iv1wpt-vs-modal-delete').data('file', file).prop('disabled', false).show();
			$('#iv1wpt-vs-modal-delete-status').text('');
			$('#iv1wpt-vs-modal').addClass('active');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_read_file',
				_ajax_nonce: iv1wpt_vars.nonce,
				file: file
			}, function(response) {
				if (!response.success) {
					$('#iv1wpt-vs-modal-code').text('❌ ' + (response.data || (i18n.error || 'Error')));
					$('#iv1wpt-vs-modal-meta').text('');
					return;
				}
				var d = response.data;
				$('#iv1wpt-vs-modal-meta').html(
					'📁 <strong>' + ssbEscapeHtml(d.file) + '</strong> &nbsp;|&nbsp; ' +
					(i18n.size || 'Size') + ': <strong>' + (d.size > 1024 ? Math.round(d.size / 1024) + ' KB' : d.size + ' B') + '</strong> &nbsp;|&nbsp; ' +
					(i18n.filemonitor_modified || 'Modified') + ': <strong>' + ssbEscapeHtml(d.mtime) + '</strong>'
				);
				$('#iv1wpt-vs-modal-code').text(d.content);
			}).fail(function() {
				$('#iv1wpt-vs-modal-code').text((i18n.connection_error || 'Connection error'));
			});
		});

		// Datei löschen
		$(document).on('click', '#iv1wpt-vs-modal-delete', function() {
			var file = $(this).data('file');
			if (!confirm('⚠️ ' + (i18n.vs_file_delete_confirm || 'Really delete this file? This cannot be undone!') + '\n\n' + file)) return;
			var btn = $(this).prop('disabled', true).text('⏳ ' + (i18n.deleting || 'Deleting...'));
			$('#iv1wpt-vs-modal-delete-status').text('');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_delete_file',
				_ajax_nonce: iv1wpt_vars.nonce,
				file: file
			}, function(response) {
				if (!response.success) {
					btn.prop('disabled', false).text('🗑️ ' + (i18n.vs_file_delete || 'Delete file'));
					$('#iv1wpt-vs-modal-delete-status').css('color', '#c0392b').text('❌ ' + (response.data || (i18n.error || 'Error')));
					return;
				}
				$('#iv1wpt-vs-modal-delete-status').css('color', '#27ae60').text('✅ ' + ssbEscapeHtml(response.data.message || 'Gelöscht'));
				btn.hide();
				$('#iv1wpt-vs-modal-code').text('— ' + (i18n.vs_file_deleted || 'File was deleted') + ' —');
				// Tabellenzeile aus Ergebnisliste entfernen
				$('tr[data-file="' + CSS.escape(file) + '"]').fadeOut(400, function() { $(this).remove(); });
				setTimeout(function() { $('#iv1wpt-vs-modal').removeClass('active'); }, 1800);
			}).fail(function() {
				btn.prop('disabled', false).text('🗑️ ' + (i18n.vs_file_delete || 'Delete file'));
				$('#iv1wpt-vs-modal-delete-status').css('color', '#c0392b').text((i18n.connection_error || 'Connection error'));
			});
		});

		// ── Modal: DB-Datensätze anzeigen ──────────────────────────────────────
		$(document).on('click', '#iv1wpt-vs-db-modal-close, #iv1wpt-vs-db-modal', function(e) {
			if (e.target === this) $('#iv1wpt-vs-db-modal').removeClass('active');
		});

		$(document).on('click', '.iv1wpt-vs-view-db', function() {
			var table     = $(this).data('table');
			var column    = $(this).data('column');
			var patternId = $(this).data('pattern-id');

			$('#iv1wpt-vs-db-modal-title').text('🗄️ ' + (i18n.vs_db_records_title || 'Database records') + ' – ' + table + ' / ' + column);
			$('#iv1wpt-vs-db-modal-meta').text(i18n.loading || 'Loading...');
			$('#iv1wpt-vs-db-modal-body').html('<p>⏳ ' + (i18n.loading || 'Loading...') + '</p>');
			$('#iv1wpt-vs-db-modal').addClass('active');

			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_db_records',
				_ajax_nonce: iv1wpt_vars.nonce,
				table:      table,
				column:     column,
				pattern_id: patternId
			}, function(response) {
				if (!response.success) {
					$('#iv1wpt-vs-db-modal-body').html('<p style="color:#c0392b;">❌ ' + ssbEscapeHtml(response.data || (i18n.error || 'Error')) + '</p>');
					$('#iv1wpt-vs-db-modal-meta').text('');
					return;
				}
				var d = response.data;
				$('#iv1wpt-vs-db-modal-meta').html(
					(i18n.vs_table || 'Table') + ': <strong>' + ssbEscapeHtml(d.table) + '</strong> &nbsp;|&nbsp; ' +
					(i18n.vs_column || 'Column') + ': <strong>' + ssbEscapeHtml(d.column) + '</strong> &nbsp;|&nbsp; ' +
					(i18n.vs_pattern || 'Pattern') + ': <code>' + ssbEscapeHtml(d.pattern_id) + '</code> &nbsp;|&nbsp; ' +
					'<strong>' + d.total + '</strong> ' + (i18n.vs_db_hits || 'hits') + ' (max. 50)'
				);
				if (d.rows.length === 0) {
					$('#iv1wpt-vs-db-modal-body').html('<p>' + (i18n.vs_no_records || 'No records found.') + '</p>');
					return;
				}
				var html = '<table class="widefat striped" style="font-size:12px;">';
				html += '<thead><tr><th style="width:60px;">' + d.pk + '</th><th>' + ssbEscapeHtml(d.column) + '</th></tr></thead><tbody>';
				$.each(d.rows, function(i, row) {
					var preview = row.content ? row.content.substring(0, 1000) : '';
					html += '<tr>';
					html += '<td style="font-family:monospace;color:#555;">' + ssbEscapeHtml(String(row.id)) + '</td>';
					html += '<td style="font-family:monospace;font-size:11px;white-space:pre-wrap;word-break:break-all;max-width:800px;">' + ssbEscapeHtml(preview) + (row.content && row.content.length > 1000 ? '<em style="color:#888;">…(' + row.content.length + ' ' + (i18n.vs_chars || 'chars') + ')</em>' : '') + '</td>';
					html += '</tr>';
				});
				html += '</tbody></table>';
				$('#iv1wpt-vs-db-modal-body').html(html);
			}).fail(function() {
				$('#iv1wpt-vs-db-modal-body').html('<p style="color:#c0392b;">❌ ' + (i18n.connection_error || 'Connection error') + '</p>');
			});
		});

		// Einstellungen speichern
		$('#iv1wpt-vs-save-settings').on('click', function() {
			var btn = $(this);
			btn.prop('disabled', true);
			$.post(ajaxurl, {
				action: 'iv1wpt_virusscanner_save_ignorelist',
				_ajax_nonce: iv1wpt_vars.nonce,
				ignorelist: $('#iv1wpt-vs-ignorelist').val(),
			}, function(response) {
				btn.prop('disabled', false);
				var ok = response.success;
				$('#iv1wpt-vs-settings-result').html(
					'<div class="notice ' + (ok ? 'notice-success' : 'notice-error') + ' is-dismissible"><p>' +
					(ok ? '✅ ' : '❌ ') + ssbEscapeHtml((response.data && response.data.message) || (ok ? 'Saved.' : 'Error.')) +
					'</p></div>'
				);
				setTimeout(function() { $('#iv1wpt-vs-settings-result .notice').fadeOut(400); }, 3000);
			}).fail(function() {
				btn.prop('disabled', false);
				$('#iv1wpt-vs-settings-result').html('<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>');
			});
		});

		// ── Datei-Monitor: Cron-Einstellungen speichern ───────────────────────
		$('#iv1wpt-filemonitor-cron-save').on('click', function () {
			var btn = $(this).prop('disabled', true);

			$.post(ajaxurl, {
				action:                 'iv1wpt_save_filemonitor_schedule',
				_ajax_nonce:            iv1wpt_vars.nonce,
				filemonitor_enabled:    $('#filemonitor_enabled').is(':checked') ? 1 : 0,
				filemonitor_interval:   $('#filemonitor_interval').val(),
				filemonitor_hour:       $('#filemonitor_hour').val(),
			}, function (response) {
				btn.prop('disabled', false);
				var ok  = response.success;
				var msg = (response.data && response.data.message) || (ok ? 'Saved.' : 'Error.');
				if (ok && response.data && response.data.next_run) {
					$('#iv1wpt-filemonitor-next-run').text(response.data.next_run);
				}
				$('#iv1wpt-filemonitor-cron-result').html(
					'<div class="notice ' + (ok ? 'notice-success' : 'notice-error') + ' is-dismissible"><p>' +
					(ok ? '✅ ' : '❌ ') + ssbEscapeHtml(msg) + '</p></div>'
				);
				setTimeout(function () { $('#iv1wpt-filemonitor-cron-result .notice').fadeOut(400); }, 3000);
			}).fail(function () {
				btn.prop('disabled', false);
				$('#iv1wpt-filemonitor-cron-result').html(
					'<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>'
				);
			});
		});

		// Stunden-Zeile ein-/ausblenden je nach Intervall
		$('#filemonitor_interval').on('change', function () {
			var v = $(this).val();
			$('#iv1wpt-filemonitor-hour-row').toggle(v === 'daily' || v === 'weekly');
		}).trigger('change');

		// ── Datei-Monitor: E-Mail-Einstellungen speichern ────────────────────
		$('#iv1wpt-filemonitor-email-save').on('click', function () {
			var btn = $(this).prop('disabled', true);

			$.post(ajaxurl, {
				action:                        'iv1wpt_save_filemonitor_email',
				_ajax_nonce:                   iv1wpt_vars.nonce,
				filemonitor_email_recipient:   $('#filemonitor_email_recipient').val(),
			}, function (response) {
				btn.prop('disabled', false);
				var ok  = response.success;
				var msg = (response.data && response.data.message) || (ok ? 'Saved.' : 'Error.');
				$('#iv1wpt-filemonitor-email-result').html(
					'<div class="notice ' + (ok ? 'notice-success' : 'notice-error') + ' is-dismissible"><p>' +
					(ok ? '✅ ' : '❌ ') + ssbEscapeHtml(msg) + '</p></div>'
				);
				setTimeout(function () { $('#iv1wpt-filemonitor-email-result .notice').fadeOut(400); }, 3000);
			}).fail(function () {
				btn.prop('disabled', false);
				$('#iv1wpt-filemonitor-email-result').html(
					'<div class="notice notice-error"><p>' + (i18n.connection_error || 'Connection error') + '</p></div>'
				);
			});
		});

	});
