/**
 * Database Cleaner Admin JavaScript
 */
(function($) {
    'use strict';

    // State
    const state = {
        counts: {},
        currentTab: 'cleanup',
        optionsPage: 1,
        metadataPage: 1,
        tablesLoaded: false,
        optionsLoaded: false,
        metadataLoaded: false,
        logsLoaded: false
    };

    // Initialize on document ready
    $(document).ready(function() {
        initTabs();
        initCategoryToggles();
        initCleanupActions();
        initSettings();

        // Load initial counts
        loadCounts();

        // Check URL for tab parameter and activate that tab
        const urlParams = new URLSearchParams(window.location.search);
        const tabParam = urlParams.get('tab');
        if (tabParam && $('.dbcleaner-tab[data-tab="' + tabParam + '"]').length) {
            $('.dbcleaner-tab[data-tab="' + tabParam + '"]').trigger('click');
        }
    });

    /**
     * Initialize tab navigation
     */
    function initTabs() {
        $('.dbcleaner-tab').on('click', function() {
            const tab = $(this).data('tab');

            // Update active state
            $('.dbcleaner-tab').removeClass('active');
            $(this).addClass('active');

            // Show correct content
            $('.dbcleaner-tab-content').removeClass('active');
            $('#tab-' + tab).addClass('active');

            state.currentTab = tab;

            // Update URL with tab parameter (without page reload)
            const url = new URL(window.location.href);
            url.searchParams.set('tab', tab);
            window.history.replaceState({}, '', url);

            // Load tab-specific data
            switch (tab) {
                case 'tables':
                    if (!state.tablesLoaded) loadTables();
                    break;
                case 'options':
                    if (!state.optionsLoaded) loadOptions();
                    break;
                case 'metadata':
                    if (!state.metadataLoaded) loadMetadata();
                    break;
                case 'logs':
                    if (!state.logsLoaded) loadLogs();
                    break;
            }
        });
    }

    /**
     * Initialize category card toggles
     */
    function initCategoryToggles() {
        $('.category-header').on('click', function() {
            const $card = $(this).closest('.dbcleaner-category-card');
            $card.toggleClass('collapsed');
        });
    }

    /**
     * Initialize cleanup action buttons
     */
    function initCleanupActions() {
        // Analyze button
        $('#dbcleaner-analyze-btn').on('click', function() {
            loadCounts();
        });

        // Individual clean buttons
        $(document).on('click', '.item-clean-btn', function() {
            const item = $(this).data('item');
            const count = state.counts[item]?.count || 0;

            if (count === 0) {
                showToast(switchboardDbCleaner.i18n.noItems, 'info');
                return;
            }

            if (!confirm(switchboardDbCleaner.i18n.confirmClean)) {
                return;
            }

            cleanItems([item]);
        });

        // Clean selected button
        $('#clean-selected-btn').on('click', function() {
            const selectedItems = getSelectedItems();

            if (selectedItems.length === 0) {
                showToast('Please select at least one item', 'warning');
                return;
            }

            // Filter to only items with count > 0
            const itemsToClean = selectedItems.filter(item => (state.counts[item]?.count || 0) > 0);

            if (itemsToClean.length === 0) {
                showToast(switchboardDbCleaner.i18n.noItems, 'info');
                return;
            }

            if (!confirm(switchboardDbCleaner.i18n.confirmClean)) {
                return;
            }

            cleanItems(itemsToClean);
        });

        // Clean all safe items button
        $('#clean-all-safe-btn').on('click', function() {
            const safeItems = [];

            $('.cleanup-item[data-risk="safe"]').each(function() {
                const item = $(this).data('item');
                if ((state.counts[item]?.count || 0) > 0) {
                    safeItems.push(item);
                }
            });

            if (safeItems.length === 0) {
                showToast(switchboardDbCleaner.i18n.noItems, 'info');
                return;
            }

            if (!confirm(switchboardDbCleaner.i18n.confirmCleanAll)) {
                return;
            }

            cleanItems(safeItems);
        });
    }

    /**
     * Initialize settings handlers
     */
    function initSettings() {
        $('#save-settings-btn').on('click', function() {
            saveSettings();
        });

        // Toggle active class on checkbox items in settings
        $('.sb-module-checkbox-item input[type="checkbox"]').on('change', function() {
            $(this).closest('.sb-module-checkbox-item').toggleClass('active', $(this).is(':checked'));
        });

        // Toggle active class on radio items (schedule options) - only one can be active
        $('.sb-module-checkbox-item input[type="radio"]').on('change', function() {
            const name = $(this).attr('name');
            $('input[name="' + name + '"]').closest('.sb-module-checkbox-item').removeClass('active');
            $(this).closest('.sb-module-checkbox-item').addClass('active');
        });

        // Options tab handlers
        $('#options-search-btn').on('click', function() {
            state.optionsPage = 1;
            loadOptions();
        });

        $('#options-search').on('keypress', function(e) {
            if (e.which === 13) {
                state.optionsPage = 1;
                loadOptions();
            }
        });

        $('#options-autoload').on('change', function() {
            state.optionsPage = 1;
            loadOptions();
        });

        // Metadata tab handlers
        $('#metadata-search-btn').on('click', function() {
            state.metadataPage = 1;
            loadMetadata();
        });

        $('#metadata-search').on('keypress', function(e) {
            if (e.which === 13) {
                state.metadataPage = 1;
                loadMetadata();
            }
        });

        $('#metadata-sort').on('change', function() {
            state.metadataPage = 1;
            loadMetadata();
        });
    }

    /**
     * Get list of selected item keys
     */
    function getSelectedItems() {
        const items = [];
        $('.cleanup-item').each(function() {
            if ($(this).find('input[type="checkbox"]').is(':checked')) {
                items.push($(this).data('item'));
            }
        });
        return items;
    }

    /**
     * Load counts for all cleanup items
     */
    function loadCounts() {
        const $btn = $('#dbcleaner-analyze-btn');
        $btn.prop('disabled', true).html('<span class="spinner is-active" style="margin: 0 4px 0 0;"></span>' + switchboardDbCleaner.i18n.refreshing);

        // Show loading state on all items
        $('[data-count]').text('--');
        $('[data-size]').text('--');

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_counts',
                nonce: switchboardDbCleaner.nonce
            },
            success: function(response) {
                if (response.success) {
                    state.counts = response.data.counts;
                    updateCountsDisplay(response.data.counts);
                    updateStatsDisplay(response.data.db_size, response.data.counts);
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
            },
            complete: function() {
                $btn.prop('disabled', false).html('<span class="dashicons dashicons-update"></span>' + switchboardDbCleaner.i18n.refresh);
            }
        });
    }

    /**
     * Update counts display in the UI
     */
    function updateCountsDisplay(counts) {
        // Update individual item counts
        for (const [key, data] of Object.entries(counts)) {
            $(`[data-count="${key}"]`).text(formatNumber(data.count) + ' items');
            $(`[data-size="${key}"]`).text(formatBytes(data.size));

            // Disable clean button if count is 0
            const $btn = $(`.item-clean-btn[data-item="${key}"]`);
            $btn.prop('disabled', data.count === 0);
        }

        // Update category counts
        const categories = {
            posts: ['revisions', 'auto_drafts', 'trashed_posts'],
            comments: ['spam_comments', 'trashed_comments', 'unapproved_comments', 'pingbacks'],
            metadata: ['orphaned_postmeta', 'duplicated_postmeta', 'orphaned_commentmeta', 'orphaned_usermeta', 'orphaned_termmeta', 'oembed_cache'],
            transients: ['expired_transients', 'all_transients'],
            terms: ['unused_terms', 'orphaned_term_relationships']
        };

        for (const [category, items] of Object.entries(categories)) {
            let total = 0;
            for (const item of items) {
                total += counts[item]?.count || 0;
            }
            $(`[data-category-count="${category}"]`).text(formatNumber(total) + ' ' + switchboardDbCleaner.i18n.items);
        }
    }

    /**
     * Update stats summary display
     */
    function updateStatsDisplay(dbSize, counts) {
        // Database size
        $('#stat-db-size').text(formatBytes(dbSize.total));

        // Total cleanable items
        let totalCleanable = 0;
        let totalSavings = 0;

        for (const [key, data] of Object.entries(counts)) {
            totalCleanable += data.count;
            totalSavings += data.size;
        }

        $('#stat-cleanable').text(formatNumber(totalCleanable));
        $('#stat-savings').text('~' + formatBytes(totalSavings));

        // Last cleaned - get from logs
        const settings = switchboardDbCleaner.settings;
        if (settings.cleanup_log && settings.cleanup_log.length > 0) {
            const lastLog = settings.cleanup_log[settings.cleanup_log.length - 1];
            $('#stat-last-clean').text(formatRelativeTime(lastLog.timestamp));
        } else {
            $('#stat-last-clean').text('Never');
        }
    }

    /**
     * Clean selected items
     */
    function cleanItems(items) {
        const $cleanSelectedBtn = $('#clean-selected-btn');
        const $cleanAllBtn = $('#clean-all-safe-btn');

        $cleanSelectedBtn.prop('disabled', true).html('<span class="spinner is-active" style="margin: 0 4px 0 0;"></span>' + switchboardDbCleaner.i18n.cleaning);
        $cleanAllBtn.prop('disabled', true);

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_clean',
                nonce: switchboardDbCleaner.nonce,
                items: items
            },
            success: function(response) {
                if (response.success) {
                    const message = switchboardDbCleaner.i18n.cleaned.replace('%d', response.data.total);
                    showToast(message, 'success');

                    // Refresh counts
                    loadCounts();
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
            },
            complete: function() {
                $cleanSelectedBtn.prop('disabled', false).html('<span class="dashicons dashicons-trash"></span>Clean Selected');
                $cleanAllBtn.prop('disabled', false);
            }
        });
    }

    /**
     * Load database tables
     */
    function loadTables() {
        const $tbody = $('#tables-list tbody');
        $tbody.html('<tr class="loading-row"><td colspan="6" class="loading-cell"><span class="spinner is-active"></span> ' + switchboardDbCleaner.i18n.loading + '</td></tr>');

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_tables',
                nonce: switchboardDbCleaner.nonce
            },
            success: function(response) {
                console.log('Tables response:', response);
                if (response.success) {
                    state.tablesLoaded = true;
                    renderTablesTable(response.data.tables);
                } else {
                    $tbody.html('<tr><td colspan="6">' + (response.data?.message || switchboardDbCleaner.i18n.error) + '</td></tr>');
                }
            },
            error: function(xhr, status, error) {
                console.error('Tables AJAX error:', status, error);
                $tbody.html('<tr><td colspan="6">' + switchboardDbCleaner.i18n.error + '</td></tr>');
            }
        });
    }

    /**
     * Render tables table
     */
    function renderTablesTable(tables) {
        const $tbody = $('#tables-list tbody');
        let html = '';

        if (!tables || tables.length === 0) {
            html = '<tr><td colspan="6">No tables found</td></tr>';
        } else {
            for (const table of tables) {
                html += `
                    <tr>
                        <td class="column-name"><code>${escapeHtml(table.name || '')}</code></td>
                        <td class="column-rows">${formatNumber(table.rows || 0)}</td>
                        <td class="column-size">${formatBytes(table.total_size || 0)}</td>
                        <td class="column-percent">
                            <div class="percent-bar">
                                <div class="percent-fill" style="width: ${table.percentage || 0}%"></div>
                                <span class="percent-text">${table.percentage || 0}%</span>
                            </div>
                        </td>
                        <td class="column-engine">${escapeHtml(table.engine || 'N/A')}</td>
                        <td class="column-actions">
                            <button type="button" class="button button-small optimize-table-btn" data-table="${escapeHtml(table.name || '')}">
                                Optimize
                            </button>
                        </td>
                    </tr>
                `;
            }
        }

        $tbody.html(html);

        // Bind optimize button handlers
        $('.optimize-table-btn').on('click', function() {
            const table = $(this).data('table');
            optimizeTable(table, $(this));
        });
    }

    /**
     * Optimize a table
     */
    function optimizeTable(tableName, $btn) {
        $btn.prop('disabled', true).text(switchboardDbCleaner.i18n.optimizing);

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_optimize_table',
                nonce: switchboardDbCleaner.nonce,
                table: tableName
            },
            success: function(response) {
                if (response.success) {
                    showToast(switchboardDbCleaner.i18n.optimized, 'success');
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
            },
            complete: function() {
                $btn.prop('disabled', false).text('Optimize');
            }
        });
    }

    /**
     * Load options
     */
    function loadOptions() {
        const $tbody = $('#options-list tbody');
        $tbody.html('<tr class="loading-row"><td colspan="4" class="loading-cell"><span class="spinner is-active"></span> ' + switchboardDbCleaner.i18n.loading + '</td></tr>');

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_options',
                nonce: switchboardDbCleaner.nonce,
                page: state.optionsPage,
                search: $('#options-search').val(),
                autoload: $('#options-autoload').val()
            },
            success: function(response) {
                if (response.success) {
                    state.optionsLoaded = true;
                    renderOptionsTable(response.data.options);
                    renderPagination('#options-pagination', response.data.pages, state.optionsPage, function(page) {
                        state.optionsPage = page;
                        loadOptions();
                    });
                } else {
                    $tbody.html('<tr><td colspan="4">' + (response.data?.message || switchboardDbCleaner.i18n.error) + '</td></tr>');
                }
            },
            error: function() {
                $tbody.html('<tr><td colspan="4">' + switchboardDbCleaner.i18n.error + '</td></tr>');
            }
        });
    }

    /**
     * Render options table
     */
    function renderOptionsTable(options) {
        const $tbody = $('#options-list tbody');
        let html = '';

        if (options.length === 0) {
            html = '<tr><td colspan="4">No options found</td></tr>';
        } else {
            for (const option of options) {
                html += `
                    <tr>
                        <td class="column-name"><code>${escapeHtml(option.option_name)}</code></td>
                        <td class="column-size">${formatBytes(option.size)}</td>
                        <td class="column-autoload">${option.autoload === 'yes' ? '<span class="badge badge-yes">Yes</span>' : '<span class="badge badge-no">No</span>'}</td>
                        <td class="column-actions">
                            <button type="button" class="sb-module-button sb-module-button-danger sb-module-button-sm delete-option-btn" data-option="${escapeHtml(option.option_name)}">
                                Delete
                            </button>
                        </td>
                    </tr>
                `;
            }
        }

        $tbody.html(html);

        // Bind delete handlers
        $('.delete-option-btn').on('click', function() {
            const option = $(this).data('option');
            if (confirm(switchboardDbCleaner.i18n.confirmDelete)) {
                deleteOption(option, $(this));
            }
        });
    }

    /**
     * Delete an option
     */
    function deleteOption(optionName, $btn) {
        $btn.prop('disabled', true);

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_delete_option',
                nonce: switchboardDbCleaner.nonce,
                option_name: optionName
            },
            success: function(response) {
                if (response.success) {
                    showToast('Option deleted', 'success');
                    loadOptions();
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                    $btn.prop('disabled', false);
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
                $btn.prop('disabled', false);
            }
        });
    }

    /**
     * Load metadata
     */
    function loadMetadata() {
        const $tbody = $('#metadata-list tbody');
        $tbody.html('<tr class="loading-row"><td colspan="4" class="loading-cell"><span class="spinner is-active"></span> ' + switchboardDbCleaner.i18n.loading + '</td></tr>');

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_metadata',
                nonce: switchboardDbCleaner.nonce,
                page: state.metadataPage,
                search: $('#metadata-search').val(),
                sort: $('#metadata-sort').val()
            },
            success: function(response) {
                if (response.success) {
                    state.metadataLoaded = true;
                    renderMetadataTable(response.data.metadata);
                    renderPagination('#metadata-pagination', response.data.pages, state.metadataPage, function(page) {
                        state.metadataPage = page;
                        loadMetadata();
                    });
                } else {
                    $tbody.html('<tr><td colspan="4">' + (response.data?.message || switchboardDbCleaner.i18n.error) + '</td></tr>');
                }
            },
            error: function() {
                $tbody.html('<tr><td colspan="4">' + switchboardDbCleaner.i18n.error + '</td></tr>');
            }
        });
    }

    /**
     * Render metadata table
     */
    function renderMetadataTable(metadata) {
        const $tbody = $('#metadata-list tbody');
        let html = '';

        if (metadata.length === 0) {
            html = '<tr><td colspan="4">No metadata found</td></tr>';
        } else {
            for (const meta of metadata) {
                // Check if it's a protected meta key
                const isProtected = meta.meta_key.startsWith('_wp_') ||
                                   meta.meta_key.startsWith('_edit_') ||
                                   meta.meta_key.startsWith('_menu_') ||
                                   meta.meta_key.startsWith('_thumbnail');
                html += `
                    <tr>
                        <td class="column-key"><code>${escapeHtml(meta.meta_key)}</code></td>
                        <td class="column-count">${formatNumber(meta.count)}</td>
                        <td class="column-size">${formatBytes(meta.size)}</td>
                        <td class="column-actions">
                            <button type="button" class="sb-module-button sb-module-button-danger sb-module-button-sm delete-meta-btn" data-meta-key="${escapeHtml(meta.meta_key)}" ${isProtected ? 'disabled title="Protected meta key"' : ''}>
                                Delete
                            </button>
                        </td>
                    </tr>
                `;
            }
        }

        $tbody.html(html);

        // Bind delete handlers
        $('.delete-meta-btn').on('click', function() {
            const metaKey = $(this).data('meta-key');
            if (confirm(switchboardDbCleaner.i18n.confirmDeleteMeta)) {
                deleteMetadata(metaKey, $(this));
            }
        });
    }

    /**
     * Delete metadata by key
     */
    function deleteMetadata(metaKey, $btn) {
        $btn.prop('disabled', true);

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_delete_metadata',
                nonce: switchboardDbCleaner.nonce,
                meta_key: metaKey
            },
            success: function(response) {
                if (response.success) {
                    showToast(response.data.message, 'success');
                    loadMetadata();
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                    $btn.prop('disabled', false);
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
                $btn.prop('disabled', false);
            }
        });
    }

    /**
     * Load logs
     */
    function loadLogs() {
        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_logs',
                nonce: switchboardDbCleaner.nonce
            },
            success: function(response) {
                if (response.success) {
                    state.logsLoaded = true;
                    renderLogs(response.data.logs);
                    renderSizeHistory(response.data.size_history);
                }
            }
        });
    }

    /**
     * Render cleanup logs
     */
    function renderLogs(logs) {
        const $container = $('#cleanup-log-list');

        if (!logs || logs.length === 0) {
            $container.html('<p class="no-logs">No cleanup history yet</p>');
            return;
        }

        let html = '<ul class="log-entries">';
        for (const log of logs.slice(0, 20)) {
            const itemLabel = getItemLabel(log.item);
            html += `
                <li class="log-entry">
                    <span class="log-time">${formatRelativeTime(log.timestamp)}</span>
                    <span class="log-action">Cleaned <strong>${log.count}</strong> ${itemLabel}</span>
                </li>
            `;
        }
        html += '</ul>';

        $container.html(html);
    }

    /**
     * Render size history chart (simple bar chart)
     */
    function renderSizeHistory(history) {
        const $container = $('#size-history-chart');

        if (!history || history.length === 0) {
            $container.html('<p class="no-data">No size history available yet. History is recorded when you run database analysis or cleanup.</p>');
            return;
        }

        // Get last 14 days
        const recentHistory = history.slice(-14);
        const maxSize = Math.max(...recentHistory.map(h => h.size));
        const minSize = Math.min(...recentHistory.map(h => h.size));

        // If only one data point or all same values, show flat line at middle height
        const hasVariation = maxSize > minSize;

        let html = '<div class="size-chart-bars">';
        for (const entry of recentHistory) {
            // If no variation, show bars at 60% height; otherwise calculate proportionally
            let height;
            if (!hasVariation || recentHistory.length === 1) {
                height = 60;
            } else {
                // Scale between 20% and 100% for visual clarity
                const normalizedValue = (entry.size - minSize) / (maxSize - minSize);
                height = 20 + (normalizedValue * 80);
            }

            const date = new Date(entry.date);
            const dayLabel = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });

            html += `
                <div class="chart-bar-wrapper" title="${dayLabel}: ${formatBytes(entry.size)}">
                    <div class="chart-bar" style="height: ${height}%"></div>
                    <div class="chart-label">${dayLabel}</div>
                </div>
            `;
        }
        html += '</div>';

        // Add size info below chart
        if (recentHistory.length > 0) {
            const latestSize = recentHistory[recentHistory.length - 1].size;
            html += `<p class="chart-info" style="text-align: center; margin-top: 12px; font-size: 12px; color: var(--gray-500);">Current: ${formatBytes(latestSize)}</p>`;
        }

        $container.html(html);
    }

    /**
     * Save settings
     */
    function saveSettings() {
        const $btn = $('#save-settings-btn');
        $btn.prop('disabled', true).html('<span class="dashicons dashicons-update spin" style="margin-right: 6px;"></span>Saving...');

        const autoCleanItems = [];
        $('input[name="auto_clean_items[]"]:checked').each(function() {
            autoCleanItems.push($(this).val());
        });

        $.ajax({
            url: switchboardDbCleaner.ajaxurl,
            type: 'POST',
            data: {
                action: 'switchboard_dbcleaner_save_settings',
                nonce: switchboardDbCleaner.nonce,
                auto_clean: $('input[name="auto_clean_schedule"]:checked').val() || 'disabled',
                auto_clean_items: autoCleanItems,
                batch_size: $('#setting-batch-size').val()
            },
            success: function(response) {
                if (response.success) {
                    showToast(switchboardDbCleaner.i18n.saved, 'success');
                } else {
                    showToast(response.data?.message || switchboardDbCleaner.i18n.error, 'error');
                }
            },
            error: function() {
                showToast(switchboardDbCleaner.i18n.error, 'error');
            },
            complete: function() {
                $btn.prop('disabled', false).html('<span class="dashicons dashicons-saved" style="margin-right: 6px;"></span>Save Settings');
            }
        });
    }

    /**
     * Render pagination
     */
    function renderPagination(selector, totalPages, currentPage, callback) {
        const $container = $(selector);

        if (totalPages <= 1) {
            $container.html('');
            return;
        }

        let html = '<div class="pagination-links">';

        // Previous
        if (currentPage > 1) {
            html += `<button type="button" class="button pagination-btn" data-page="${currentPage - 1}">&laquo; Prev</button>`;
        }

        // Page numbers
        const startPage = Math.max(1, currentPage - 2);
        const endPage = Math.min(totalPages, currentPage + 2);

        for (let i = startPage; i <= endPage; i++) {
            const activeClass = i === currentPage ? 'active' : '';
            html += `<button type="button" class="button pagination-btn ${activeClass}" data-page="${i}">${i}</button>`;
        }

        // Next
        if (currentPage < totalPages) {
            html += `<button type="button" class="button pagination-btn" data-page="${currentPage + 1}">Next &raquo;</button>`;
        }

        html += '</div>';

        $container.html(html);

        // Bind click handlers
        $container.find('.pagination-btn').on('click', function() {
            const page = parseInt($(this).data('page'));
            callback(page);
        });
    }

    /**
     * Get item label from key
     */
    function getItemLabel(key) {
        const labels = {
            'revisions': 'revisions',
            'auto_drafts': 'auto-drafts',
            'trashed_posts': 'trashed posts',
            'spam_comments': 'spam comments',
            'trashed_comments': 'trashed comments',
            'unapproved_comments': 'unapproved comments',
            'pingbacks': 'pingbacks',
            'orphaned_postmeta': 'orphaned post meta',
            'duplicated_postmeta': 'duplicated post meta',
            'orphaned_commentmeta': 'orphaned comment meta',
            'orphaned_usermeta': 'orphaned user meta',
            'orphaned_termmeta': 'orphaned term meta',
            'oembed_cache': 'oEmbed caches',
            'expired_transients': 'expired transients',
            'all_transients': 'transients',
            'unused_terms': 'unused terms',
            'orphaned_term_relationships': 'orphaned term relationships'
        };
        return labels[key] || key;
    }

    /**
     * Show toast notification
     */
    function showToast(message, type = 'info') {
        const $toast = $('#dbcleaner-toast');
        const icons = {
            success: '',
            error: '',
            warning: '',
            info: ''
        };

        $toast.find('.toast-icon').text(icons[type] || icons.info);
        $toast.find('.toast-message').text(message);
        $toast.removeClass('success error warning info').addClass(type).addClass('show');

        setTimeout(function() {
            $toast.removeClass('show');
        }, 4000);
    }

    /**
     * Format number with commas
     */
    function formatNumber(num) {
        return parseInt(num || 0).toLocaleString();
    }

    /**
     * Format bytes to human readable
     */
    function formatBytes(bytes) {
        if (!bytes || bytes === 0) return '0 B';

        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));

        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    /**
     * Format timestamp to relative time
     */
    function formatRelativeTime(timestamp) {
        const now = Math.floor(Date.now() / 1000);
        const diff = now - timestamp;

        if (diff < 60) return 'Just now';
        if (diff < 3600) return Math.floor(diff / 60) + ' min ago';
        if (diff < 86400) return Math.floor(diff / 3600) + ' hours ago';
        if (diff < 604800) return Math.floor(diff / 86400) + ' days ago';

        const date = new Date(timestamp * 1000);
        return date.toLocaleDateString();
    }

    /**
     * Escape HTML
     */
    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

})(jQuery);
