/**
 * DiveWP Plugins Management JavaScript
 * 
 * Handles drawer interactions, search/filter, and AJAX for plugin management.
 * 
 * @package DiveWP
 * @version 1.0.0
 */

jQuery(document).ready(function($) {
    'use strict';

    // Check if localized data exists
    if (typeof divewpPluginsData === 'undefined') {
        return;
    }

    // Session cache for wp.org plugin details (keyed by plugin file)
    var pluginDetailsCache = {};

    // Session cache for wp.org plugin versions (keyed by plugin file)
    var pluginVersionsCache = {};

    // Session cache for wp.org plugin ratings (keyed by slug)
    var pluginRatingsCache = {};

    // Session cache for wp.org plugin icon URLs (keyed by slug)
    var pluginIconsCache = {};

    // Track how many versions are currently visible per plugin
    var versionsVisibleCount = {};

    // Plugin Card Click Handler - Opens Drawer
    $(document).on('click', '.divewp-plugin-card', function(e) {
        e.preventDefault();
        const $card = $(this);
        openDrawer($card);
    });

    // Drawer Close Button
    $(document).on('click', '.divewp-plugins-drawer__close', function(e) {
        e.preventDefault();
        closeDrawer();
    });

    // Drawer Overlay Click
    $(document).on('click', '.divewp-plugins-drawer__overlay', function(e) {
        e.preventDefault();
        closeDrawer();
    });

    // Escape Key to Close Drawer
    $(document).on('keydown', function(e) {
        if (e.key === 'Escape' && $('.divewp-plugins-drawer').hasClass('open')) {
            closeDrawer();
        }
    });

    // Toggle Button (Activate/Deactivate)
    $(document).on('click', '.divewp-plugins-drawer__action[data-action="toggle"]', function(e) {
        e.preventDefault();
        handleTogglePlugin();
    });

    // Update Button (AJAX in-modal update)
    $(document).on('click', '.divewp-plugins-drawer__action[data-action="update"]', function(e) {
        e.preventDefault();
        handleUpdatePlugin();
    });

    // Tab Navigation
    $(document).on('click', '.divewp-plugins-drawer__tab', function(e) {
        e.preventDefault();
        const tabName = $(this).data('tab');
        const drawer = $('.divewp-plugins-drawer');
        showTab(drawer, tabName);
    });

    // =========================================================================
    // Ratings bootstrap — fetch card rating summaries on page load
    // =========================================================================

    (function bootstrapCardRatings() {
        var slugs = [];
        $('.divewp-plugin-card').each(function() {
            var slug = $(this).data('plugin-wporg-slug');
            if (slug && slugs.indexOf(slug) === -1) {
                slugs.push(slug);
            }
        });

        if (slugs.length === 0) {
            return;
        }

        // Process in batches of 50
        var BATCH_SIZE = 50;
        for (var i = 0; i < slugs.length; i += BATCH_SIZE) {
            var batch = slugs.slice(i, i + BATCH_SIZE);
            fetchRatingsBatch(batch);
        }
    })();

    // =========================================================================
    // Icons bootstrap — fetch wp.org plugin logos and swap into cards/drawer
    // =========================================================================

    (function bootstrapCardIcons() {
        var slugs = [];
        $('.divewp-plugin-card').each(function() {
            var slug = $(this).data('plugin-wporg-slug');
            if (slug && slugs.indexOf(slug) === -1) {
                slugs.push(slug);
            }
        });
        if (slugs.length === 0) return;
        var BATCH_SIZE = 50;
        for (var i = 0; i < slugs.length; i += BATCH_SIZE) {
            fetchIconsBatch(slugs.slice(i, i + BATCH_SIZE));
        }
    })();

    function getDashiconPlaceholder() {
        return '<span class="dashicons dashicons-admin-plugins"></span>';
    }

    function getCardIconHtml(iconUrl) {
        if (!iconUrl) return getDashiconPlaceholder();
        return '<img class="divewp-plugin-logo divewp-plugin-logo--card" src="' + escapeHtml(iconUrl) + '" alt="" />';
    }

    function getDrawerIconHtml(iconUrl) {
        if (!iconUrl) return getDashiconPlaceholder();
        return '<img class="divewp-plugin-logo divewp-plugin-logo--drawer" src="' + escapeHtml(iconUrl) + '" alt="" />';
    }

    function fetchIconsBatch(slugs) {
        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_get_plugin_icons_batch',
                slugs: slugs.join(','),
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (!response.success || !response.data) return;
                $.each(response.data, function(slug, item) {
                    var iconUrl = (item && item.icon_url) ? item.icon_url : null;
                    pluginIconsCache[slug] = item;

                    $('.divewp-plugin-card[data-plugin-wporg-slug="' + slug + '"]').each(function() {
                        var $card = $(this);
                        var $icon = $card.find('.recommendation-icon');
                        if (!$icon.length) return;
                        if (iconUrl) {
                            $card.attr('data-plugin-icon-url', iconUrl);
                            $icon.html(getCardIconHtml(iconUrl));
                            $icon.find('img.divewp-plugin-logo').on('error', function() {
                                $icon.html(getDashiconPlaceholder());
                            });
                        }
                    });

                    var drawer = $('.divewp-plugins-drawer');
                    if (drawer.hasClass('open') && drawer.data('wporg-slug') === slug && iconUrl) {
                        var $drawerIcon = drawer.find('.divewp-plugin-details__icon');
                        if ($drawerIcon.length) {
                            $drawerIcon.html(getDrawerIconHtml(iconUrl));
                            $drawerIcon.find('img.divewp-plugin-logo').on('error', function() {
                                $drawerIcon.html(getDashiconPlaceholder());
                            });
                        }
                    }
                });
            }
        });
    }

    /**
     * Fetch ratings for a batch of slugs and inject into cards
     */
    function fetchRatingsBatch(slugs) {
        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_get_plugin_ratings_batch',
                slugs: slugs.join(','),
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (response.success && response.data) {
                    $.each(response.data, function(slug, ratingData) {
                        // Store in session cache
                        pluginRatingsCache[slug] = ratingData;

                        // Inject into matching cards
                        $('.divewp-rating-summary[data-rating-slug="' + slug + '"]').each(function() {
                            var $el = $(this);
                            $el.removeClass('divewp-rating-summary--loading');
                            $el.html(buildRatingSummaryHtml(ratingData.avg_rating, ratingData.num_ratings));
                        });
                    });

                    // Mark remaining loading placeholders as empty (no data found)
                    slugs.forEach(function(slug) {
                        if (!response.data[slug]) {
                            $('.divewp-rating-summary[data-rating-slug="' + slug + '"]')
                                .removeClass('divewp-rating-summary--loading')
                                .html('');
                        }
                    });
                }
            },
            error: function() {
                // Remove loading state on error
                slugs.forEach(function(slug) {
                    $('.divewp-rating-summary[data-rating-slug="' + slug + '"]')
                        .removeClass('divewp-rating-summary--loading')
                        .html('');
                });
            }
        });
    }

    /**
     * Build rating summary HTML (custom stars + text)
     *
     * @param {number} avg     Average rating 0.0–5.0
     * @param {number} count   Number of ratings
     * @return {string} HTML string
     */
    function buildRatingSummaryHtml(avg, count) {
        if (!count || count === 0) {
            return '';
        }

        var tierClass = getRatingTierClass(avg);
        var html = '<span class="divewp-rating-stars ' + tierClass + '">';

        // Render 5 stars (full, half, or empty)
        for (var i = 1; i <= 5; i++) {
            if (avg >= i) {
                html += '<span class="divewp-star divewp-star--full">&#9733;</span>';
            } else if (avg >= i - 0.5) {
                html += '<span class="divewp-star divewp-star--half">&#9733;</span>';
            } else {
                html += '<span class="divewp-star divewp-star--empty">&#9734;</span>';
            }
        }

        html += '</span>';
        html += '<span class="divewp-rating-text">';
        html += '<span class="divewp-rating-avg">' + avg + '</span>';
        html += '<span class="divewp-rating-count">(' + count + ')</span>';
        html += '</span>';

        return html;
    }

    /**
     * Get tier CSS class based on average rating
     *
     * @param {number} avg Average rating 0.0–5.0
     * @return {string} CSS class name
     */
    function getRatingTierClass(avg) {
        if (avg >= 4.5) {
            return 'divewp-rating--green';
        } else if (avg >= 4.0) {
            return 'divewp-rating--blue';
        } else if (avg >= 3.0) {
            return 'divewp-rating--orange';
        }
        return 'divewp-rating--red';
    }

    /**
     * Open the drawer with plugin details
     */
    function openDrawer($card) {
        const drawer = $('.divewp-plugins-drawer');
        const content = drawer.find('.divewp-plugins-drawer__content');

        // Extract plugin data from card
        const pluginFile = $card.data('plugin-file');
        const pluginName = $card.data('plugin-name');
        const pluginVersion = $card.data('plugin-version');
        const pluginDescription = $card.data('plugin-description');
        const pluginAuthor = $card.data('plugin-author');
        const isActive = $card.data('plugin-active') === 1;
        const hasUpdate = $card.data('plugin-update') === 1;
        const updateVersion = $card.data('plugin-update-version');
        const pluginUrl = $card.data('plugin-url') || '';
        const authorUrl = $card.data('plugin-author-url') || '';
        const wporgSlug = $card.data('plugin-wporg-slug') || '';
        const iconUrl = $card.data('plugin-icon-url') || (wporgSlug && pluginIconsCache[wporgSlug] && pluginIconsCache[wporgSlug].icon_url) || null;

        // Build Overview tab content
        let overviewHtml = '<div class="divewp-plugin-details">';
        overviewHtml += '<div class="divewp-plugin-details__header">';
        overviewHtml += '<div class="divewp-plugin-details__icon">' + getDrawerIconHtml(iconUrl) + '</div>';
        overviewHtml += '<div>';
        overviewHtml += '<h3 class="divewp-plugin-details__name">' + escapeHtml(pluginName) + '</h3>';
        if (pluginAuthor) {
            overviewHtml += '<p class="divewp-plugin-details__author">By ' + escapeHtml(pluginAuthor) + '</p>';
        }
        overviewHtml += '</div>';
        overviewHtml += '</div>';

        // Status & version grid
        overviewHtml += '<div class="divewp-plugin-details__grid">';
        overviewHtml += '<div class="divewp-plugin-details__item">';
        overviewHtml += '<span class="divewp-plugin-details__item-label">Status</span>';
        const statusClass = isActive ? 'divewp-plugin-status--active' : 'divewp-plugin-status--inactive';
        const statusText = isActive ? divewpPluginsData.strings.active : divewpPluginsData.strings.inactive;
        overviewHtml += '<span class="divewp-plugin-status ' + statusClass + '">';
        overviewHtml += '<span class="dashicons ' + (isActive ? 'dashicons-yes-alt' : 'dashicons-dismiss') + '"></span>';
        overviewHtml += escapeHtml(statusText);
        overviewHtml += '</span>';
        overviewHtml += '</div>';

        overviewHtml += '<div class="divewp-plugin-details__item">';
        overviewHtml += '<span class="divewp-plugin-details__item-label">Version</span>';
        overviewHtml += '<span class="divewp-plugin-details__item-value">' + escapeHtml(pluginVersion) + '</span>';
        overviewHtml += '</div>';

        if (hasUpdate) {
            overviewHtml += '<div class="divewp-plugin-details__item">';
            overviewHtml += '<span class="divewp-plugin-details__item-label">Update Available</span>';
            overviewHtml += '<span class="divewp-plugin-details__item-value">' + escapeHtml(updateVersion) + '</span>';
            overviewHtml += '</div>';
        }

        overviewHtml += '</div>';

        // Description
        if (pluginDescription) {
            overviewHtml += '<div class="divewp-plugin-details__description">';
            overviewHtml += escapeHtml(pluginDescription);
            overviewHtml += '</div>';
        }

        // Rating summary in overview (if cached from batch load)
        if (wporgSlug && pluginRatingsCache[wporgSlug]) {
            var rd = pluginRatingsCache[wporgSlug];
            overviewHtml += '<div class="divewp-plugin-details__rating">';
            overviewHtml += buildRatingSummaryHtml(rd.avg_rating, rd.num_ratings);
            overviewHtml += '</div>';
        } else if (wporgSlug) {
            // Placeholder — will be filled after details fetch
            overviewHtml += '<div class="divewp-plugin-details__rating" data-overview-rating-slug="' + escapeHtml(wporgSlug) + '"></div>';
        }

        // Links
        overviewHtml += '<div>';
        if (pluginUrl) {
            overviewHtml += '<a href="' + escapeHtml(pluginUrl) + '" target="_blank" rel="noopener noreferrer" class="divewp-plugin-details__link">Visit Plugin Page</a>';
        }
        overviewHtml += '</div>';

        overviewHtml += '</div>';

        // Store current plugin info in drawer
        drawer.data('overview-content', overviewHtml);
        drawer.data('wporg-slug', wporgSlug);
        drawer.data('current-plugin-file', pluginFile);
        drawer.data('current-tab', 'overview');

        // Set initial content (Overview tab)
        showTab(drawer, 'overview');

        // Update toggle button
        const toggleBtn = drawer.find('.divewp-plugins-drawer__action[data-action="toggle"]');
        const updateBtn = drawer.find('.divewp-plugins-drawer__update');
        const actionLabel = toggleBtn.find('.action-label');

        if (isActive) {
            toggleBtn.removeClass('button-primary').addClass('button-secondary');
            actionLabel.text(divewpPluginsData.strings.deactivate);
        } else {
            toggleBtn.removeClass('button-secondary').addClass('button-primary');
            actionLabel.text(divewpPluginsData.strings.activate);
        }

        // Reset and update button visibility
        updateBtn.stop(true, true);
        updateBtn.prop('disabled', false);
        updateBtn.removeClass('button-success button-danger').addClass('button-primary');
        updateBtn.find('.update-label').text(divewpPluginsData.strings.updatePlugin);

        if (hasUpdate) {
            updateBtn.show();
        } else {
            updateBtn.hide();
        }

        // Store plugin file for AJAX handler
        drawer.data('plugin-file', pluginFile);
        drawer.data('plugin-is-active', isActive);
        drawer.data('plugin-card', $card);

        // Show drawer
        drawer.attr('aria-hidden', 'false').addClass('open');

        // Fetch wp.org details if slug available
        if (wporgSlug) {
            fetchPluginWporgDetails(pluginFile, wporgSlug, drawer);
        }
    }

    /**
     * Show specific tab in drawer
     */
    function showTab(drawer, tabName) {
        const content = drawer.find('.divewp-plugins-drawer__content');
        const wporgSlug = drawer.data('wporg-slug');
        const pluginFile = drawer.data('current-plugin-file');
        const cached = pluginFile ? pluginDetailsCache[pluginFile] : null;

        // Track current tab
        drawer.data('current-tab', tabName);

        if (tabName === 'overview') {
            const overviewContent = drawer.data('overview-content');
            content.html(overviewContent);
            var $iconContainer = drawer.find('.divewp-plugin-details__icon');
            if (wporgSlug && pluginIconsCache[wporgSlug] && pluginIconsCache[wporgSlug].icon_url) {
                $iconContainer.html(getDrawerIconHtml(pluginIconsCache[wporgSlug].icon_url));
            }
            $iconContainer.find('img.divewp-plugin-logo').on('error', function() {
                $iconContainer.html(getDashiconPlaceholder());
            });
        } else if (tabName === 'description') {
            if (cached && cached.description) {
                content.html(cached.description);
            } else if (wporgSlug) {
                content.html('<p>' + divewpPluginsData.strings.loadingDetails + '</p>');
            } else {
                content.html('<p>' + divewpPluginsData.strings.notAvailable + '</p>');
            }
        } else if (tabName === 'changelog') {
            if (cached && cached.changelog) {
                content.html(cached.changelog);
            } else if (wporgSlug) {
                content.html('<p>' + divewpPluginsData.strings.loadingDetails + '</p>');
            } else {
                content.html('<p>' + divewpPluginsData.strings.notAvailable + '</p>');
            }
        } else if (tabName === 'reviews') {
            if (cached && typeof cached.reviews_html !== 'undefined') {
                content.html(buildReviewsTabContent(cached, wporgSlug));
            } else if (wporgSlug) {
                content.html('<p>' + divewpPluginsData.strings.loadingReviews + '</p>');
            } else {
                content.html('<div class="divewp-versions-unavailable"><span class="dashicons dashicons-info-outline"></span><p>' + escapeHtml(divewpPluginsData.strings.reviewsNotAvailable) + '</p></div>');
            }
        } else if (tabName === 'versions') {
            loadVersionsTab(drawer, pluginFile, wporgSlug, content);
        }

        // Update active tab button
        drawer.find('.divewp-plugins-drawer__tab').removeClass('divewp-plugins-drawer__tab--active');
        drawer.find('.divewp-plugins-drawer__tab[data-tab="' + tabName + '"]').addClass('divewp-plugins-drawer__tab--active');
    }

    /**
     * Fetch wp.org details for a plugin
     */
    function fetchPluginWporgDetails(pluginFile, wporgSlug, drawer) {
        // If we already have details in session cache, don't fetch again
        if (pluginDetailsCache[pluginFile]) {
            return;
        }

        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_get_plugin_details',
                plugin_file: pluginFile,
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (response.success && response.data.wporg_available) {
                    const descriptionHtml = '<div class="divewp-plugin-wporg-description">' + response.data.description + '</div>';
                    const changelogHtml = '<div class="divewp-plugin-wporg-changelog">' + response.data.changelog + '</div>';

                    // Store in session cache (including reviews + rating data)
                    pluginDetailsCache[pluginFile] = {
                        description: descriptionHtml,
                        changelog: changelogHtml,
                        reviews_html: response.data.reviews_html || '',
                        avg_rating: response.data.avg_rating || 0,
                        num_ratings: response.data.num_ratings || 0,
                        rating_percent: response.data.rating_percent || 0,
                        ratings_breakdown: response.data.ratings_breakdown || {},
                        wporg_slug: response.data.wporg_slug || wporgSlug
                    };

                    // Also update the ratings session cache for cards
                    if (wporgSlug && response.data.avg_rating) {
                        pluginRatingsCache[wporgSlug] = {
                            avg_rating: response.data.avg_rating,
                            num_ratings: response.data.num_ratings,
                            rating_percent: response.data.rating_percent
                        };
                    }
                } else {
                    pluginDetailsCache[pluginFile] = {
                        description: '<p>' + divewpPluginsData.strings.notAvailable + '</p>',
                        changelog: '<p>' + divewpPluginsData.strings.notAvailable + '</p>',
                        reviews_html: '',
                        avg_rating: 0,
                        num_ratings: 0,
                        rating_percent: 0,
                        ratings_breakdown: {},
                        wporg_slug: ''
                    };
                }

                // Auto-refresh current tab if drawer is still showing this plugin
                if (drawer.data('current-plugin-file') === pluginFile) {
                    const currentTab = drawer.data('current-tab');
                    if (currentTab === 'description' || currentTab === 'changelog' || currentTab === 'reviews') {
                        showTab(drawer, currentTab);
                    }
                }
            },
            error: function() {
                pluginDetailsCache[pluginFile] = {
                    description: '<p>' + divewpPluginsData.strings.error + '</p>',
                    changelog: '<p>' + divewpPluginsData.strings.error + '</p>',
                    reviews_html: '',
                    avg_rating: 0,
                    num_ratings: 0,
                    rating_percent: 0,
                    ratings_breakdown: {},
                    wporg_slug: ''
                };

                // Auto-refresh current tab on error too
                if (drawer.data('current-plugin-file') === pluginFile) {
                    const currentTab = drawer.data('current-tab');
                    if (currentTab === 'description' || currentTab === 'changelog' || currentTab === 'reviews') {
                        showTab(drawer, currentTab);
                    }
                }
            }
        });
    }

    // =========================================================================
    // Reviews tab content builder
    // =========================================================================

    /**
     * Build the full Reviews tab HTML
     *
     * @param {object} cached  Plugin details cache entry
     * @param {string} wporgSlug  The wp.org plugin slug
     * @return {string} HTML string
     */
    function buildReviewsTabContent(cached, wporgSlug) {
        var html = '<div class="divewp-reviews-tab">';

        // Rating summary header
        if (cached.avg_rating && cached.num_ratings) {
            html += '<div class="divewp-reviews-tab__summary">';
            html += buildRatingSummaryHtml(cached.avg_rating, cached.num_ratings);
            html += '</div>';
        }

        // Reviews HTML from wp.org (sanitized server-side)
        if (cached.reviews_html && cached.reviews_html.trim() !== '') {
            html += '<div class="divewp-plugin-wporg-reviews">' + cached.reviews_html + '</div>';
        } else {
            html += '<div class="divewp-versions-unavailable"><span class="dashicons dashicons-info-outline"></span><p>' + escapeHtml(divewpPluginsData.strings.noReviewsFound) + '</p></div>';
        }

        // "View all reviews" link
        if (wporgSlug) {
            html += '<div class="divewp-reviews-tab__link">';
            html += '<a href="https://wordpress.org/plugins/' + encodeURIComponent(wporgSlug) + '/#reviews" target="_blank" rel="noopener noreferrer">';
            html += escapeHtml(divewpPluginsData.strings.viewAllReviews);
            html += ' &rarr;</a>';
            html += '</div>';
        }

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

    // =========================================================================
    // Versions / Rollback tab
    // =========================================================================

    /**
     * Load the versions tab content
     */
    function loadVersionsTab(drawer, pluginFile, wporgSlug, content) {
        if (!wporgSlug) {
            content.html('<div class="divewp-versions-unavailable"><span class="dashicons dashicons-info-outline"></span><p>' + escapeHtml(divewpPluginsData.strings.versionsNotAvailable) + '</p></div>');
            return;
        }

        // Check session cache
        if (pluginVersionsCache[pluginFile]) {
            renderVersionsList(drawer, pluginFile, content, pluginVersionsCache[pluginFile]);
            return;
        }

        // Show loading state
        content.html('<div class="divewp-versions-loading"><span class="spinner is-active"></span><p>' + escapeHtml(divewpPluginsData.strings.loadingVersions) + '</p></div>');

        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_get_plugin_versions',
                plugin_file: pluginFile,
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (response.success && response.data.wporg_available) {
                    pluginVersionsCache[pluginFile] = response.data;
                    // Only render if still on this plugin and tab
                    if (drawer.data('current-plugin-file') === pluginFile && drawer.data('current-tab') === 'versions') {
                        renderVersionsList(drawer, pluginFile, content, response.data);
                    }
                } else {
                    var msg = (response.data && response.data.message) ? response.data.message : divewpPluginsData.strings.versionsNotAvailable;
                    content.html('<div class="divewp-versions-unavailable"><span class="dashicons dashicons-info-outline"></span><p>' + escapeHtml(msg) + '</p></div>');
                }
            },
            error: function() {
                content.html('<p>' + escapeHtml(divewpPluginsData.strings.error) + '</p>');
            }
        });
    }

    /**
     * Render the versions list with pagination (5 at a time)
     */
    function renderVersionsList(drawer, pluginFile, content, data) {
        var installedVersion = data.installed_version;
        var versions = data.versions || [];
        var VERSIONS_PER_PAGE = 5;

        if (versions.length === 0) {
            content.html('<div class="divewp-versions-unavailable"><span class="dashicons dashicons-info-outline"></span><p>' + escapeHtml(divewpPluginsData.strings.noVersionsFound) + '</p></div>');
            return;
        }

        // Reset visible count
        versionsVisibleCount[pluginFile] = VERSIONS_PER_PAGE;

        var html = '<div class="divewp-versions-container">';
        html += '<p class="divewp-versions-rollback-notice">' + escapeHtml(divewpPluginsData.strings.rollbackNotice) + '</p>';

        // Installed version header
        html += '<div class="divewp-versions-installed">';
        html += '<span class="divewp-versions-installed__label">' + escapeHtml(divewpPluginsData.strings.installedVersion) + '</span>';
        html += '<span class="divewp-versions-installed__value">v' + escapeHtml(installedVersion) + '</span>';
        html += '</div>';

        // Versions list
        html += '<div class="divewp-versions-list">';
        for (var i = 0; i < versions.length; i++) {
            var v = versions[i];
            var isCurrent = (v.version === installedVersion);
            var hiddenClass = (i >= VERSIONS_PER_PAGE) ? ' divewp-version-item--hidden' : '';

            html += '<div class="divewp-version-item' + (isCurrent ? ' divewp-version-item--current' : '') + hiddenClass + '" data-version="' + escapeHtml(v.version) + '">';
            html += '<span class="divewp-version-item__label">v' + escapeHtml(v.version) + '</span>';
            if (isCurrent) {
                html += '<span class="divewp-version-item__badge">' + escapeHtml(divewpPluginsData.strings.installed) + '</span>';
            } else {
                html += '<button type="button" class="divewp-version-item__install" data-version="' + escapeHtml(v.version) + '">' + escapeHtml(divewpPluginsData.strings.installThisVersion) + '</button>';
            }
            html += '</div>';
        }
        html += '</div>';

        // Load more button (if more than VERSIONS_PER_PAGE)
        if (versions.length > VERSIONS_PER_PAGE) {
            html += '<button type="button" class="divewp-versions-load-more">' + escapeHtml(divewpPluginsData.strings.loadMore) + '</button>';
        }

        // Rollback confirmation container (initially hidden)
        html += '<div class="divewp-rollback-confirm" style="display:none;"></div>';

        html += '</div>';
        content.html(html);
    }

    /**
     * Handle "Load more" button for versions list
     */
    $(document).on('click', '.divewp-versions-load-more', function(e) {
        e.preventDefault();
        var drawer = $('.divewp-plugins-drawer');
        var pluginFile = drawer.data('current-plugin-file');
        var cached = pluginVersionsCache[pluginFile];
        if (!cached) return;

        var VERSIONS_PER_PAGE = 5;
        var currentVisible = versionsVisibleCount[pluginFile] || VERSIONS_PER_PAGE;
        var newVisible = currentVisible + VERSIONS_PER_PAGE;
        versionsVisibleCount[pluginFile] = newVisible;

        // Show next batch
        var $items = drawer.find('.divewp-version-item--hidden');
        $items.slice(0, VERSIONS_PER_PAGE).removeClass('divewp-version-item--hidden');

        // Hide button if all are visible
        if (newVisible >= cached.versions.length) {
            $(this).hide();
        }
    });

    /**
     * Handle "Install this version" button click — show rollback confirmation
     */
    $(document).on('click', '.divewp-version-item__install', function(e) {
        e.preventDefault();
        var targetVersion = $(this).data('version');
        var drawer = $('.divewp-plugins-drawer');
        var $confirmContainer = drawer.find('.divewp-rollback-confirm');

        // Build confirmation UI
        var warningText = divewpPluginsData.strings.rollbackWarning.replace('%s', targetVersion);

        var html = '<div class="divewp-rollback-warning">';
        html += '<span class="dashicons dashicons-warning"></span>';
        html += '<p>' + escapeHtml(warningText) + '</p>';
        html += '</div>';

        html += '<div class="divewp-rollback-options">';
        html += '<label class="divewp-rollback-reactivate">';
        html += '<input type="checkbox" class="divewp-rollback-reactivate__checkbox" />';
        html += '<span class="divewp-rollback-reactivate__label">' + escapeHtml(divewpPluginsData.strings.rollbackReactivateLabel) + '</span>';
        html += '</label>';
        html += '<span class="divewp-rollback-reactivate__hint">' + escapeHtml(divewpPluginsData.strings.rollbackReactivateHint) + '</span>';
        html += '</div>';

        html += '<div class="divewp-rollback-actions">';
        html += '<button type="button" class="button button-primary divewp-rollback-execute" data-version="' + escapeHtml(targetVersion) + '">' + escapeHtml(divewpPluginsData.strings.confirmRollback) + '</button>';
        html += '<button type="button" class="button button-secondary divewp-rollback-cancel">' + escapeHtml(divewpPluginsData.strings.cancel) + '</button>';
        html += '</div>';

        $confirmContainer.html(html).slideDown(200);

        // Scroll confirmation into view
        $confirmContainer[0].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
    });

    /**
     * Handle rollback cancel
     */
    $(document).on('click', '.divewp-rollback-cancel', function(e) {
        e.preventDefault();
        $(this).closest('.divewp-rollback-confirm').slideUp(200);
    });

    /**
     * Handle rollback execution
     */
    $(document).on('click', '.divewp-rollback-execute', function(e) {
        e.preventDefault();
        var $btn = $(this);
        var targetVersion = $btn.data('version');
        var drawer = $('.divewp-plugins-drawer');
        var pluginFile = drawer.data('current-plugin-file');
        var reactivate = drawer.find('.divewp-rollback-reactivate__checkbox').is(':checked');
        var $confirmContainer = drawer.find('.divewp-rollback-confirm');

        // Disable button and show spinner
        $btn.prop('disabled', true).text(divewpPluginsData.strings.rollingBack);
        drawer.find('.divewp-rollback-cancel').prop('disabled', true);

        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_rollback_plugin_version',
                plugin_file: pluginFile,
                target_version: targetVersion,
                reactivate: reactivate ? '1' : '0',
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                var result = response.data || {};

                if (response.success && result.success) {
                    var successMsg = divewpPluginsData.strings.rollbackSuccess
                        .replace('%1$s', result.previous_version || '')
                        .replace('%2$s', result.target_version || targetVersion);

                    var html = '<div class="divewp-rollback-result divewp-rollback-result--success">';
                    html += '<span class="dashicons dashicons-yes-alt"></span>';
                    html += '<p>' + escapeHtml(successMsg) + '</p>';
                    if (result.warnings && result.warnings.length) {
                        html += '<ul class="divewp-rollback-warnings">';
                        for (var i = 0; i < result.warnings.length; i++) {
                            html += '<li>' + escapeHtml(result.warnings[i]) + '</li>';
                        }
                        html += '</ul>';
                    }
                    html += '</div>';
                    $confirmContainer.html(html);

                    // Invalidate caches so next open is fresh
                    delete pluginVersionsCache[pluginFile];
                    delete pluginDetailsCache[pluginFile];

                    // Update card data and visible text
                    var $card = drawer.data('plugin-card');
                    if ($card) {
                        $card.data('plugin-version', targetVersion);
                        $card.attr('data-plugin-version', targetVersion);

                        // Update visible version text on card
                        $card.find('.divewp-plugin-version').text('v' + targetVersion);

                        // Update active status if changed
                        if (typeof result.is_active !== 'undefined') {
                            updateCardStatus($card, result.is_active);
                            drawer.data('plugin-is-active', result.is_active);

                            // Update toggle button to match new state
                            var toggleBtn = drawer.find('.divewp-plugins-drawer__action[data-action="toggle"]');
                            var actionLabel = toggleBtn.find('.action-label');
                            if (result.is_active) {
                                toggleBtn.removeClass('button-primary').addClass('button-secondary');
                                actionLabel.text(divewpPluginsData.strings.deactivate);
                            } else {
                                toggleBtn.removeClass('button-secondary').addClass('button-primary');
                                actionLabel.text(divewpPluginsData.strings.activate);
                            }
                        }
                    }

                    // Update cached overview HTML so Overview tab shows new version
                    var cachedOverview = drawer.data('overview-content') || '';
                    if (cachedOverview && result.previous_version) {
                        cachedOverview = cachedOverview.replace(
                            escapeHtml(result.previous_version),
                            escapeHtml(targetVersion)
                        );
                        // Also update status if activation changed
                        if (result.is_active) {
                            cachedOverview = cachedOverview
                                .replace('divewp-plugin-status--inactive', 'divewp-plugin-status--active')
                                .replace('dashicons-dismiss', 'dashicons-yes-alt')
                                .replace('>' + escapeHtml(divewpPluginsData.strings.inactive) + '<', '>' + escapeHtml(divewpPluginsData.strings.active) + '<');
                        }
                        drawer.data('overview-content', cachedOverview);
                    }

                    // Update the "Installed Version" display in the versions tab
                    drawer.find('.divewp-versions-installed__value').text('v' + targetVersion);

                    // Update version row highlights
                    drawer.find('.divewp-version-item').each(function() {
                        var $item = $(this);
                        var itemVersion = String($item.data('version'));

                        if (itemVersion === targetVersion) {
                            // Mark new current version
                            $item.addClass('divewp-version-item--current');
                            $item.find('.divewp-version-item__install').replaceWith(
                                '<span class="divewp-version-item__badge">' + escapeHtml(divewpPluginsData.strings.installed) + '</span>'
                            );
                        } else if ($item.hasClass('divewp-version-item--current')) {
                            // Unmark old current version and restore install button
                            $item.removeClass('divewp-version-item--current');
                            $item.find('.divewp-version-item__badge').replaceWith(
                                '<button type="button" class="divewp-version-item__install" data-version="' + escapeHtml(itemVersion) + '">' + escapeHtml(divewpPluginsData.strings.installThisVersion) + '</button>'
                            );
                        }
                    });
                } else {
                    var errorMsg = (result && result.message) ? result.message : divewpPluginsData.strings.rollbackError;
                    var html = '<div class="divewp-rollback-result divewp-rollback-result--error">';
                    html += '<span class="dashicons dashicons-dismiss"></span>';
                    html += '<p>' + escapeHtml(errorMsg) + '</p>';
                    html += '</div>';
                    $confirmContainer.html(html);
                }
            },
            error: function() {
                var html = '<div class="divewp-rollback-result divewp-rollback-result--error">';
                html += '<span class="dashicons dashicons-dismiss"></span>';
                html += '<p>' + escapeHtml(divewpPluginsData.strings.rollbackError) + '</p>';
                html += '</div>';
                $confirmContainer.html(html);
            }
        });
    });

    /**
     * Close the drawer
     */
    function closeDrawer() {
        const drawer = $('.divewp-plugins-drawer');
        drawer.attr('aria-hidden', 'true').removeClass('open');
        drawer.find('.divewp-plugins-drawer__content').html('');
    }

    /**
     * Handle toggle plugin activation/deactivation
     */
    function handleTogglePlugin() {
        const drawer = $('.divewp-plugins-drawer');
        const pluginFile = drawer.data('plugin-file');
        const isActive = drawer.data('plugin-is-active');
        const $card = drawer.data('plugin-card');

        if (!pluginFile) {
            alert(divewpPluginsData.strings.error);
            return;
        }

        // Confirm deactivation if active
        if (isActive && !confirm(divewpPluginsData.strings.confirmDeactivate)) {
            return;
        }

        const toggleBtn = drawer.find('.divewp-plugins-drawer__action[data-action="toggle"]');
        toggleBtn.prop('disabled', true);

        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_toggle_plugin_status',
                plugin_file: pluginFile,
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (response.success) {
                    const newStatus = response.data.is_active;
                    
                    // Update drawer button
                    const actionLabel = toggleBtn.find('.action-label');
                    if (newStatus) {
                        toggleBtn.removeClass('button-primary').addClass('button-secondary');
                        actionLabel.text(divewpPluginsData.strings.deactivate);
                    } else {
                        toggleBtn.removeClass('button-secondary').addClass('button-primary');
                        actionLabel.text(divewpPluginsData.strings.activate);
                    }

                    // Update card badges
                    updateCardStatus($card, newStatus);

                    // Update drawer data
                    drawer.data('plugin-is-active', newStatus);

                } else {
                    alert(response.data || divewpPluginsData.strings.error);
                }
            },
            error: function() {
                alert(divewpPluginsData.strings.error);
            },
            complete: function() {
                toggleBtn.prop('disabled', false);
            }
        });
    }

    /**
     * Handle AJAX plugin update inside the drawer
     */
    function handleUpdatePlugin() {
        var drawer = $('.divewp-plugins-drawer');
        var pluginFile = drawer.data('plugin-file');
        var $card = drawer.data('plugin-card');
        var $updateBtn = drawer.find('.divewp-plugins-drawer__update');
        var $updateLabel = $updateBtn.find('.update-label');
        var $toggleBtn = drawer.find('.divewp-plugins-drawer__action[data-action="toggle"]');

        if (!pluginFile) {
            alert(divewpPluginsData.strings.error);
            return;
        }

        $updateBtn.prop('disabled', true);
        $toggleBtn.prop('disabled', true);
        $updateLabel.text(divewpPluginsData.strings.updating);

        $.ajax({
            url: divewpPluginsData.ajaxurl,
            type: 'POST',
            data: {
                action: 'divewp_update_plugin',
                plugin_file: pluginFile,
                nonce: divewpPluginsData.nonce
            },
            success: function(response) {
                if (response.success && response.data) {
                    var result = response.data;
                    var successMsg = divewpPluginsData.strings.updateSuccess
                        .replace('%1$s', result.previous_version || '')
                        .replace('%2$s', result.new_version || '');

                    $updateLabel.text(successMsg);
                    $updateBtn.removeClass('button-primary').addClass('button-success');

                    // Update card data
                    if ($card) {
                        $card.data('plugin-version', result.new_version);
                        $card.attr('data-plugin-version', result.new_version);
                        $card.data('plugin-update', 0);
                        $card.attr('data-plugin-update', '0');
                        $card.data('plugin-update-version', '');
                        $card.attr('data-plugin-update-version', '');

                        $card.find('.divewp-plugin-version').text('v' + result.new_version);

                        updateCardStatus($card, result.is_active);
                    }

                    // Hide update button after short delay
                    setTimeout(function() {
                        $updateBtn.fadeOut(300);
                    }, 2000);

                    // Invalidate caches
                    delete pluginDetailsCache[pluginFile];
                    delete pluginVersionsCache[pluginFile];

                    // Update drawer state
                    drawer.data('plugin-is-active', result.is_active);

                    // Update overview content to reflect new version
                    var cachedOverview = drawer.data('overview-content') || '';
                    if (cachedOverview && result.previous_version) {
                        cachedOverview = cachedOverview.replace(
                            escapeHtml(result.previous_version),
                            escapeHtml(result.new_version)
                        );
                        // Remove "Update Available" row from overview
                        cachedOverview = cachedOverview.replace(
                            /<div class="divewp-plugin-details__item">[\s\S]*?Update Available[\s\S]*?<\/div>/,
                            ''
                        );
                        drawer.data('overview-content', cachedOverview);
                    }

                    updateFilterCounts();
                } else {
                    var errorMsg = (response.data && response.data.message) ? response.data.message : divewpPluginsData.strings.updateError;
                    $updateLabel.text(errorMsg);
                    $updateBtn.removeClass('button-primary').addClass('button-danger');

                    setTimeout(function() {
                        $updateBtn.removeClass('button-danger').addClass('button-primary');
                        $updateLabel.text(divewpPluginsData.strings.updatePlugin);
                        $updateBtn.prop('disabled', false);
                    }, 3000);
                }
            },
            error: function() {
                $updateLabel.text(divewpPluginsData.strings.updateError);
                $updateBtn.removeClass('button-primary').addClass('button-danger');

                setTimeout(function() {
                    $updateBtn.removeClass('button-danger').addClass('button-primary');
                    $updateLabel.text(divewpPluginsData.strings.updatePlugin);
                    $updateBtn.prop('disabled', false);
                }, 3000);
            },
            complete: function() {
                $toggleBtn.prop('disabled', false);
            }
        });
    }

    /**
     * Update card status badges after toggle
     */
    function updateCardStatus($card, isActive) {
        const badges = $card.find('.divewp-plugin-badges');
        
        // Update card data attribute so filters work correctly
        $card.data('plugin-active', isActive ? 1 : 0);
        $card.attr('data-plugin-active', isActive ? '1' : '0');
        
        // Get the current update status from card data
        const hasUpdate = $card.data('plugin-update') === 1;
        
        // Remove all status pills
        badges.find('.status-pill').remove();

        // Add new status badge (Active=blue info, Inactive=orange warning)
        if (isActive) {
            badges.append('<span class="status-pill status-pill-info">' + divewpPluginsData.strings.active + '</span>');
        } else {
            badges.append('<span class="status-pill status-pill-warning">' + divewpPluginsData.strings.inactive + '</span>');
        }
        
        // Show update badge for ALL plugins (active or inactive)
        if (hasUpdate) {
            badges.append('<span class="status-pill status-pill-danger">' + divewpPluginsData.strings.updateAvailable + '</span>');
        } else if (isActive) {
            // Only show "Up to date" for active plugins
            badges.append('<span class="status-pill status-pill-success">' + divewpPluginsData.strings.upToDate + '</span>');
        }

        // Update filter button counts
        updateFilterCounts();
    }

    /**
     * Recalculate and update filter button counts
     */
    function updateFilterCounts() {
        const $bar = $('#divewp-plugins-filter-bar');
        const cards = $('.divewp-plugin-card');
        var totalCount = cards.length;
        var activeCount = 0;
        var inactiveCount = 0;
        var updateCount = 0;

        cards.each(function() {
            var $c = $(this);
            if ($c.data('plugin-active') === 1) {
                activeCount++;
            } else {
                inactiveCount++;
            }
            if ($c.data('plugin-update') === 1) {
                updateCount++;
            }
        });

        $bar.find('.divewp-filter-bar__btn[data-filter="all"] .divewp-filter-bar__btn-count').text(totalCount);
        $bar.find('.divewp-filter-bar__btn[data-filter="active"] .divewp-filter-bar__btn-count').text(activeCount);
        $bar.find('.divewp-filter-bar__btn[data-filter="inactive"] .divewp-filter-bar__btn-count').text(inactiveCount);
        $bar.find('.divewp-filter-bar__btn[data-filter="updates"] .divewp-filter-bar__btn-count').text(updateCount);
    }

    // =========================================================================
    // Listen for filter bar events (from reusable divewp-filter-bar.js)
    // =========================================================================

    $('#divewp-plugins-filter-bar').on('divewp:filter-changed', function(e, data) {
        applyFilters(data.filterValue, data.searchQuery);
    });

    // =========================================================================
    // Combined filter + search logic
    // =========================================================================

    /**
     * Apply both filter button and search query to plugin cards
     *
     * @param {string} activeFilter The active filter key (all, active, inactive, updates)
     * @param {string} query The search query (lowercase, trimmed)
     */
    function applyFilters(activeFilter, query) {
        activeFilter = activeFilter || 'all';
        query = query || '';
        const cards = $('.divewp-plugin-card');

        cards.each(function() {
            const $card = $(this);
            const isActive = $card.data('plugin-active') === 1;
            const hasUpdate = $card.data('plugin-update') === 1;
            const name = String($card.data('plugin-name') || '').toLowerCase();
            const author = String($card.data('plugin-author') || '').toLowerCase();
            const description = String($card.data('plugin-description') || '').toLowerCase();

            // Check filter condition
            var passesFilter = true;
            if (activeFilter === 'active') {
                passesFilter = isActive;
            } else if (activeFilter === 'inactive') {
                passesFilter = !isActive;
            } else if (activeFilter === 'updates') {
                passesFilter = hasUpdate;
            }

            // Check search condition
            var passesSearch = true;
            if (query.length > 0) {
                passesSearch = name.includes(query) || author.includes(query) || description.includes(query);
            }

            // Show only if both conditions pass
            if (passesFilter && passesSearch) {
                $card.show();
            } else {
                $card.hide();
            }
        });
    }

    /**
     * Escape HTML special characters
     */
    function escapeHtml(text) {
        // Handle non-string values (jQuery .data() auto-converts numeric-looking values to numbers)
        if (text === null || text === undefined) {
            return '';
        }
        if (typeof text !== 'string') {
            text = String(text);
        }
        const map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return text.replace(/[&<>"']/g, function(m) { return map[m]; });
    }
});
