jQuery(document).ready(function ($) {
    $('#vulntitan-start-vulnerability-scan').off('click').on('click', function () {
        const $scanBtn = $(this);
        const $btnMal = $('#vulntitan-start-malware-scan');
        const $btnInt = $('#vulntitan-start-integrity-scan');
        const $integrityLegend = $('#vulntitan-integrity-legend-container');
        const $integrityProblematic = $('#vulntitan-integrity-problematic-container');
        const $integrityNextSteps = $('#vulntitan-integrity-next-steps-container');
        const $integrityProblematicSummary = $('#vulntitan-integrity-problematic-summary');
        const $integrityProblematicList = $('#vulntitan-integrity-problematic-list');
        const $integrityNextStepsList = $('#vulntitan-integrity-next-steps-list');
        const $malwareOverviewContainer = $('#vulntitan-malware-overview-container');
        const $malwareOverviewContent = $('#vulntitan-malware-overview-content');
        const $malwareProblematicContainer = $('#vulntitan-malware-problematic-container');
        const $malwareProblematicSummary = $('#vulntitan-malware-problematic-summary');
        const $malwareProblematicList = $('#vulntitan-malware-problematic-list');
        const $vulnOverviewContainer = $('#vulntitan-vuln-overview-container');
        const $vulnOverviewContent = $('#vulntitan-vuln-overview-content');
        const $results = $('#vulntitan-scan-results');
        const $progressBarContainer = $('#vulntitan-scan-progress-bar-container');
        const $progressBar = $('#vulntitan-scan-progress-bar');
        const $progressNote = $('#vulntitan-scan-progress-note');
        const $stopBtn = $('#vulntitan-stop-vulnerability-scan');
        const $retryBtn = $('#vulntitan-retry-vulnerability-failed');
        const $resultsContainer = $('#vulntitan-scan-results-container');
        const items = VulnTitan.scanItems || [];

        let $overviewScanned = $();
        let $overviewVulnerable = $();
        let $overviewFindings = $();
        let $overviewSeverity = $();
        let $overviewLastScan = $();
        let $overviewErrors = $();
        let $overviewDataAge = $();
        let $componentsList = $();
        let $detailsList = $();
        let $componentsEmpty = $();
        let $filterSeverity = $();
        let $filterType = $();
        let $filterStatus = $();
        let $filterFix = $();
        let $sortOrder = $();

        const stats = {
            scanned: 0,
            vulnerableTargets: 0,
            findings: 0,
            errors: 0,
            severity: {
                critical: 0,
                high: 0,
                medium: 0,
                low: 0,
                unknown: 0
            }
        };

        const severityOrder = ['critical', 'high', 'medium', 'low', 'unknown'];

        let scanQueue = [];
        let currentIndex = 0;
        let total = 0;
        let currentRowId = '';
        let stopRequested = false;
        let isScanning = false;
        let currentRequest = null;
        let failedItems = [];
        let cachedCount = 0;
        let maxCacheAge = 0;
        let autoScroll = true;
        let lastScanAt = null;
        const lastScanStorageKey = 'vulntitan_vuln_last_scan';
        const riskPayloads = new Map();
        const riskAuditCache = new Map();

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

        function normalizeArrayValue(value) {
            if (Array.isArray(value)) {
                return value.map(function (entry) {
                    if (entry === null || entry === undefined) {
                        return '';
                    }
                    if (typeof entry === 'string' || typeof entry === 'number') {
                        return String(entry);
                    }
                    if (typeof entry === 'object') {
                        const from = entry.from_version || entry.from || entry.start || '';
                        const to = entry.to_version || entry.to || entry.end || '';
                        if (from && to) {
                            return `${from} - ${to}`;
                        }
                        if (from) {
                            return `${from}+`;
                        }
                        if (to) {
                            return `<= ${to}`;
                        }
                        if (entry.version) {
                            return String(entry.version);
                        }
                    }
                    return String(entry);
                }).filter(Boolean).join(', ');
            }

            if (value && typeof value === 'object') {
                if (!Array.isArray(value)) {
                    const keys = Object.keys(value || {});
                    if (keys.length && typeof value[keys[0]] === 'object') {
                        const ranges = keys.map(function (key) {
                            const entry = value[key] || {};
                            if (typeof entry !== 'object') {
                                return String(entry);
                            }
                            return {
                                from_version: entry.from_version || entry.from || entry.start || entry.min || entry.gte || entry.gt || '',
                                to_version: entry.to_version || entry.to || entry.end || entry.max || entry.lte || entry.lt || ''
                            };
                        });
                        return normalizeArrayValue(ranges);
                    }
                }

                const pickVersion = function (candidate) {
                    if (!candidate) {
                        return '';
                    }
                    if (typeof candidate === 'string' || typeof candidate === 'number') {
                        return String(candidate);
                    }
                    if (typeof candidate === 'object') {
                        return String(candidate.version || candidate.ver || candidate.name || '');
                    }
                    return '';
                };

                const from = pickVersion(value.from_version || value.from || value.start || value.min || value.gte || value.gt);
                const to = pickVersion(value.to_version || value.to || value.end || value.max || value.lte || value.lt);
                const operator = value.operator || value.op || value.constraint || '';
                if (from || to) {
                    if (from && to) {
                        return `${from} - ${to}`;
                    }
                    if (from) {
                        return `${from}+`;
                    }
                    return `<= ${to}`;
                }

                if (operator && value.version) {
                    return `${operator} ${value.version}`;
                }

                if (Array.isArray(value.ranges)) {
                    return normalizeArrayValue(value.ranges);
                }

                if (Array.isArray(value.versions)) {
                    return normalizeArrayValue(value.versions);
                }

                if (Array.isArray(value.affected_versions)) {
                    return normalizeArrayValue(value.affected_versions);
                }

                if (value.version) {
                    return String(value.version);
                }

                try {
                    return JSON.stringify(value);
                } catch (error) {
                    return '';
                }
            }

            if (value === null || value === undefined) {
                return '';
            }

            return String(value);
        }

        function formatPublishedAt(value) {
            if (!value) {
                return '--';
            }

            const normalized = typeof value === 'string' ? value.replace(' ', 'T') : value;
            const parsed = new Date(normalized);
            if (isNaN(parsed.getTime())) {
                return escapeHtml(String(value));
            }

            return parsed.toLocaleDateString();
        }

        function formatCvssScore(value) {
            const numeric = Number(value);
            if (Number.isFinite(numeric)) {
                return numeric.toFixed(1);
            }

            return '';
        }

        function formatExploitStatus(value) {
            if (value === null || value === undefined || value === '') {
                return VulnTitan.i18n.vuln_exploit_unknown || 'Unknown';
            }

            if (typeof value === 'boolean') {
                return value ? (VulnTitan.i18n.vuln_exploit_known || 'Known exploit') : (VulnTitan.i18n.vuln_exploit_none || 'No exploit');
            }

            const raw = String(value);
            if (/^(true|yes|known|active|weaponized|exploited)$/i.test(raw)) {
                return VulnTitan.i18n.vuln_exploit_known || 'Known exploit';
            }

            if (/^(false|no|none|not available)$/i.test(raw)) {
                return VulnTitan.i18n.vuln_exploit_none || 'No exploit';
            }

            return raw.charAt(0).toUpperCase() + raw.slice(1);
        }

        function computeRiskScore(vuln, item) {
            const cvssScore = Number(vuln.cvss_score || vuln.cvss || vuln.cvssScore);
            const severity = normalizeSeverity(vuln.cvss_rating || vuln.severity || '');
            let base = Number.isFinite(cvssScore) ? cvssScore : 0;

            if (!Number.isFinite(cvssScore)) {
                switch (severity) {
                    case 'critical':
                        base = 9.0;
                        break;
                    case 'high':
                        base = 7.5;
                        break;
                    case 'medium':
                        base = 5.5;
                        break;
                    case 'low':
                        base = 3.5;
                        break;
                    default:
                        base = 2.0;
                }
            }

            let exposure = 0;
            if (item && item.active) {
                exposure += 1.4;
            }

            const exploit = vuln.exploit_status || vuln.exploit || vuln.exploited || vuln.exploit_known;
            if (exploit === true || /^(true|yes|known|active|weaponized|exploited)$/i.test(String(exploit))) {
                exposure += 2.0;
            }

            if (item && item.type === 'core') {
                exposure += 0.6;
            }

            const score = Math.min(10, Math.max(0, base + exposure));
            let level = 'low';
            if (score >= 9) {
                level = 'critical';
            } else if (score >= 7) {
                level = 'high';
            } else if (score >= 5) {
                level = 'medium';
            }

            return {
                score: score,
                level: level
            };
        }

        function setProgressNote(text) {
            if (!$progressNote.length) {
                return;
            }

            if (text) {
                $progressNote.text(text).show();
                return;
            }

            $progressNote.text('').hide();
        }

        function renderLayout() {
            $vulnOverviewContent.html(`
                <div class="vulntitan-vuln-overview">
                    <div class="vulntitan-vuln-overview-head">
                        <div>
                            <div class="vulntitan-panel-title">${escapeHtml(VulnTitan.i18n.vuln_overview_title || 'Vulnerability Overview')}</div>
                            <div class="vulntitan-panel-subtitle">${escapeHtml(VulnTitan.i18n.vuln_overview_subtitle || 'Live intelligence snapshot across plugins, themes, and WordPress core.')}</div>
                        </div>
                        <span class="vulntitan-vuln-overview-badge">${escapeHtml(VulnTitan.i18n.vuln_overview_badge || 'Live Intelligence')}</span>
                    </div>
                    <div class="vulntitan-vuln-overview-meta">
                        <span id="vulntitan-vuln-last-scan" class="vulntitan-vuln-meta-chip">${escapeHtml(VulnTitan.i18n.vuln_last_scan || 'Last scan')}: --</span>
                        <span id="vulntitan-vuln-errors" class="vulntitan-vuln-meta-chip">${escapeHtml(VulnTitan.i18n.vuln_errors || 'Errors')}: 0</span>
                        <span id="vulntitan-vuln-data-age" class="vulntitan-vuln-meta-chip">${escapeHtml(VulnTitan.i18n.vuln_data_age || 'Data age')}: ${escapeHtml(VulnTitan.i18n.vuln_data_age_live || 'live')}</span>
                    </div>
                    <div class="vulntitan-vuln-stat-grid">
                        <article class="vulntitan-vuln-stat-card is-neutral">
                            <span class="vulntitan-vuln-stat-label">${escapeHtml(VulnTitan.i18n.vuln_scanned_targets || 'Scanned Targets')}</span>
                            <strong id="vulntitan-vuln-count-scanned" class="vulntitan-vuln-stat-value">0</strong>
                        </article>
                        <article class="vulntitan-vuln-stat-card is-danger">
                            <span class="vulntitan-vuln-stat-label">${escapeHtml(VulnTitan.i18n.vuln_vulnerable_targets || 'Vulnerable Targets')}</span>
                            <strong id="vulntitan-vuln-count-targets" class="vulntitan-vuln-stat-value">0</strong>
                        </article>
                        <article class="vulntitan-vuln-stat-card is-accent">
                            <span class="vulntitan-vuln-stat-label">${escapeHtml(VulnTitan.i18n.vuln_total_findings || 'Total Findings')}</span>
                            <strong id="vulntitan-vuln-count-findings" class="vulntitan-vuln-stat-value">0</strong>
                        </article>
                    </div>
                    <div id="vulntitan-vuln-severity-breakdown" class="vulntitan-vuln-severity-row"></div>
                </div>
            `);

            $results.html(`
                <div class="vulntitan-vuln-shell">
                    <div class="vulntitan-vuln-toolbar">
                        <div class="vulntitan-vuln-toolbar-group">
                            <span class="vulntitan-vuln-toolbar-label">${escapeHtml(VulnTitan.i18n.vuln_filters_title || 'Filters')}</span>
                            <label class="vulntitan-vuln-filter">
                                <span>${escapeHtml(VulnTitan.i18n.vuln_filter_severity || 'Severity')}</span>
                                <select id="vulntitan-filter-severity" class="vulntitan-vuln-select">
                                    <option value="all">${escapeHtml(VulnTitan.i18n.vuln_filter_all || 'All')}</option>
                                    <option value="critical">${escapeHtml(VulnTitan.i18n.vuln_severity_critical || 'Critical')}</option>
                                    <option value="high">${escapeHtml(VulnTitan.i18n.vuln_severity_high || 'High')}</option>
                                    <option value="medium">${escapeHtml(VulnTitan.i18n.vuln_severity_medium || 'Medium')}</option>
                                    <option value="low">${escapeHtml(VulnTitan.i18n.vuln_severity_low || 'Low')}</option>
                                    <option value="unknown">${escapeHtml(VulnTitan.i18n.vuln_severity_unknown || 'Unknown')}</option>
                                </select>
                            </label>
                            <label class="vulntitan-vuln-filter">
                                <span>${escapeHtml(VulnTitan.i18n.vuln_filter_type || 'Component')}</span>
                                <select id="vulntitan-filter-type" class="vulntitan-vuln-select">
                                    <option value="all">${escapeHtml(VulnTitan.i18n.vuln_filter_all || 'All')}</option>
                                    <option value="plugin">${escapeHtml(VulnTitan.i18n.vuln_type_plugin || 'Plugin')}</option>
                                    <option value="theme">${escapeHtml(VulnTitan.i18n.vuln_type_theme || 'Theme')}</option>
                                    <option value="core">${escapeHtml(VulnTitan.i18n.vuln_type_core || 'Core')}</option>
                                </select>
                            </label>
                            <label class="vulntitan-vuln-filter">
                                <span>${escapeHtml(VulnTitan.i18n.vuln_filter_status || 'Status')}</span>
                                <select id="vulntitan-filter-status" class="vulntitan-vuln-select">
                                    <option value="all">${escapeHtml(VulnTitan.i18n.vuln_filter_all || 'All')}</option>
                                    <option value="active">${escapeHtml(VulnTitan.i18n.vuln_filter_active || 'Active')}</option>
                                    <option value="inactive">${escapeHtml(VulnTitan.i18n.vuln_filter_inactive || 'Inactive')}</option>
                                </select>
                            </label>
                            <label class="vulntitan-vuln-filter">
                                <span>${escapeHtml(VulnTitan.i18n.vuln_filter_fix || 'Has fix')}</span>
                                <select id="vulntitan-filter-fix" class="vulntitan-vuln-select">
                                    <option value="all">${escapeHtml(VulnTitan.i18n.vuln_filter_all || 'All')}</option>
                                    <option value="yes">${escapeHtml(VulnTitan.i18n.vuln_filter_has_fix || 'Yes')}</option>
                                    <option value="no">${escapeHtml(VulnTitan.i18n.vuln_filter_no_fix || 'No')}</option>
                                </select>
                            </label>
                        </div>
                        <div class="vulntitan-vuln-toolbar-group">
                            <label class="vulntitan-vuln-filter">
                                <span>${escapeHtml(VulnTitan.i18n.vuln_sort_label || 'Sort')}</span>
                                <select id="vulntitan-sort-order" class="vulntitan-vuln-select">
                                    <option value="severity">${escapeHtml(VulnTitan.i18n.vuln_sort_severity || 'Severity (high to low)')}</option>
                                    <option value="findings">${escapeHtml(VulnTitan.i18n.vuln_sort_findings || 'Findings (high to low)')}</option>
                                    <option value="name">${escapeHtml(VulnTitan.i18n.vuln_sort_name || 'Name (A-Z)')}</option>
                                </select>
                            </label>
                        </div>
                    </div>
                    <section class="vulntitan-vuln-section">
                        <div class="vulntitan-panel-title">${escapeHtml(VulnTitan.i18n.vuln_components_title || 'Vulnerable Components')}</div>
                        <div class="vulntitan-panel-subtitle">${escapeHtml(VulnTitan.i18n.vuln_components_subtitle || 'Components with one or more known issues discovered during this scan.')}</div>
                        <div id="vulntitan-vuln-components-empty" class="vulntitan-vuln-empty-state">
                            ${escapeHtml(VulnTitan.i18n.vuln_components_empty || 'No vulnerable components detected so far.')}
                        </div>
                        <div id="vulntitan-vuln-components-list" class="vulntitan-vuln-components-list"></div>
                    </section>

                    <section class="vulntitan-vuln-section">
                        <div class="vulntitan-panel-title">${escapeHtml(VulnTitan.i18n.vuln_details_title || 'Component Findings')}</div>
                        <div class="vulntitan-panel-subtitle">${escapeHtml(VulnTitan.i18n.vuln_details_subtitle || 'Each scanned target is summarized here as live results arrive.')}</div>
                        <div id="vulntitan-vuln-details-list" class="vulntitan-vuln-details-list"></div>
                    </section>
                </div>
            `);

            bindRiskActions();
            bindUpdateEvents();

            $vulnOverviewContainer.show();
            $overviewScanned = $('#vulntitan-vuln-count-scanned');
            $overviewVulnerable = $('#vulntitan-vuln-count-targets');
            $overviewFindings = $('#vulntitan-vuln-count-findings');
            $overviewSeverity = $('#vulntitan-vuln-severity-breakdown');
            $overviewLastScan = $('#vulntitan-vuln-last-scan');
            $overviewErrors = $('#vulntitan-vuln-errors');
            $overviewDataAge = $('#vulntitan-vuln-data-age');
            $componentsList = $('#vulntitan-vuln-components-list');
            $componentsEmpty = $('#vulntitan-vuln-components-empty');
            $detailsList = $('#vulntitan-vuln-details-list');
            $filterSeverity = $('#vulntitan-filter-severity');
            $filterType = $('#vulntitan-filter-type');
            $filterStatus = $('#vulntitan-filter-status');
            $filterFix = $('#vulntitan-filter-fix');
            $sortOrder = $('#vulntitan-sort-order');

            $filterSeverity.off('change').on('change', applyFilters);
            $filterType.off('change').on('change', applyFilters);
            $filterStatus.off('change').on('change', applyFilters);
            $filterFix.off('change').on('change', applyFilters);
            $sortOrder.off('change').on('change', applyFilters);
        }

        function normalizeSeverity(value) {
            const severity = String(value || 'unknown').toLowerCase();
            if (severity === 'critical' || severity === 'high' || severity === 'medium' || severity === 'low') {
                return severity;
            }
            return 'unknown';
        }

        function severityColor(severity) {
            switch (severity) {
                case 'critical':
                    return '#ef4444';
                case 'high':
                    return '#f97316';
                case 'medium':
                    return '#f59e0b';
                case 'low':
                    return '#33d1a0';
                default:
                    return '#94a3b8';
            }
        }

        function severityWeight(severity) {
            switch (severity) {
                case 'critical':
                    return 5;
                case 'high':
                    return 4;
                case 'medium':
                    return 3;
                case 'low':
                    return 2;
                default:
                    return 1;
            }
        }

        function severityLabel(severity) {
            switch (severity) {
                case 'critical':
                    return VulnTitan.i18n.vuln_severity_critical || 'Critical';
                case 'high':
                    return VulnTitan.i18n.vuln_severity_high || 'High';
                case 'medium':
                    return VulnTitan.i18n.vuln_severity_medium || 'Medium';
                case 'low':
                    return VulnTitan.i18n.vuln_severity_low || 'Low';
                default:
                    return VulnTitan.i18n.vuln_severity_unknown || 'Unknown';
            }
        }

        function componentTypeLabel(type) {
            switch (type) {
                case 'plugin':
                    return VulnTitan.i18n.vuln_type_plugin || 'Plugin';
                case 'theme':
                    return VulnTitan.i18n.vuln_type_theme || 'Theme';
                case 'core':
                    return VulnTitan.i18n.vuln_type_core || 'Core';
                default:
                    return VulnTitan.i18n.vuln_type_unknown || 'Component';
            }
        }

        function componentDisplayName(item) {
            if ((item.type || '') === 'core') {
                return VulnTitan.i18n.vuln_core_name || 'WordPress Core';
            }

            const rawLabel = String(item.label || '').trim();
            if (rawLabel) {
                return rawLabel
                    .replace(/^Plugin:\s*/i, '')
                    .replace(/^Theme:\s*/i, '')
                    .trim();
            }

            return String(item.slug || componentTypeLabel(item.type));
        }

        function componentMetaBits(item) {
            const bits = [componentTypeLabel(item.type)];

            if (item.version) {
                bits.push(`v${item.version}`);
            }

            if (item.slug && String(item.slug).trim() !== '' && String(item.slug).trim() !== componentDisplayName(item)) {
                bits.push(item.slug);
            }

            return bits;
        }

        function renderComponentActions(item) {
            if (!item) {
                return '';
            }

            const actions = item.actions || {};
            const buttons = [];
            const type = item.type || '';
            const pluginFile = item.plugin_file || '';
            const themeSlug = item.theme_slug || item.slug || '';
            const slug = item.slug || '';

            if (actions.update) {
                buttons.push(`<a class="vulntitan-vuln-action is-primary vulntitan-vuln-action-link" href="#" data-action-kind="update" data-item-type="${escapeHtml(type)}" data-item-slug="${escapeHtml(slug)}" data-plugin-file="${escapeHtml(pluginFile)}" data-theme-slug="${escapeHtml(themeSlug)}" data-action-url="${escapeHtml(actions.update)}">${escapeHtml(VulnTitan.i18n.vuln_action_update || 'Update now')}</a>`);
            }

            if ((item.type || '') === 'plugin' && item.active && actions.deactivate) {
                buttons.push(`<a class="vulntitan-vuln-action is-danger vulntitan-vuln-action-link" href="#" data-action-kind="deactivate" data-item-type="plugin" data-item-slug="${escapeHtml(slug)}" data-plugin-file="${escapeHtml(pluginFile)}" data-action-url="${escapeHtml(actions.deactivate)}">${escapeHtml(VulnTitan.i18n.vuln_action_deactivate || 'Deactivate')}</a>`);
            }

            if (actions.open) {
                buttons.push(`<a class="vulntitan-vuln-action is-ghost vulntitan-vuln-action-link" href="#" data-action-kind="open" data-action-url="${escapeHtml(actions.open)}">${escapeHtml(VulnTitan.i18n.vuln_action_open || 'Open plugin page')}</a>`);
            }

            if (!buttons.length) {
                return '';
            }

            return `<div class="vulntitan-vuln-actions">${buttons.join('')}</div>`;
        }

        function formatAge(seconds) {
            const totalSeconds = Math.max(0, Number(seconds) || 0);

            if (totalSeconds < 60) {
                return VulnTitan.i18n.data_age_just_now || 'just now';
            }

            const minutes = Math.floor(totalSeconds / 60);
            if (minutes < 60) {
                return `${minutes}m`;
            }

            const hours = Math.floor(minutes / 60);
            if (hours < 24) {
                return `${hours}h`;
            }

            const days = Math.floor(hours / 24);
            return `${days}d`;
        }

        function buildMetaNote(meta) {
            if (!meta || !meta.cached) {
                return '';
            }

            const age = formatAge(meta.cache_age);
            return `${VulnTitan.i18n.data_age_prefix || 'Data age'}: ${age}`;
        }

        function formatTimestamp(date) {
            if (!date) {
                return '--';
            }

            try {
                return date.toLocaleString();
            } catch (error) {
                return '--';
            }
        }

        function loadLastScanAt() {
            if (!window.localStorage) {
                return;
            }

            const stored = window.localStorage.getItem(lastScanStorageKey);
            if (!stored) {
                return;
            }

            const parsed = new Date(stored);
            if (!isNaN(parsed.getTime())) {
                lastScanAt = parsed;
            }
        }

        function setLastScanAt(date) {
            lastScanAt = date;

            if (window.localStorage && date instanceof Date) {
                window.localStorage.setItem(lastScanStorageKey, date.toISOString());
            }

            updateMetaRow();
        }

        function updateMetaRow() {
            if ($overviewLastScan.length) {
                const label = VulnTitan.i18n.vuln_last_scan || 'Last scan';
                const value = lastScanAt ? formatTimestamp(lastScanAt) : '--';
                $overviewLastScan.text(`${label}: ${value}`);
            }

            if ($overviewErrors.length) {
                const label = VulnTitan.i18n.vuln_errors || 'Errors';
                $overviewErrors.text(`${label}: ${stats.errors}`);
            }

            if ($overviewDataAge.length) {
                const label = VulnTitan.i18n.vuln_data_age || 'Data age';
                const value = cachedCount > 0
                    ? formatAge(maxCacheAge)
                    : (VulnTitan.i18n.vuln_data_age_live || 'live');
                $overviewDataAge.text(`${label}: ${value}`);
            }
        }

        function resetStats() {
            stats.scanned = 0;
            stats.vulnerableTargets = 0;
            stats.findings = 0;
            stats.errors = 0;
            stats.severity = {
                critical: 0,
                high: 0,
                medium: 0,
                low: 0,
                unknown: 0
            };
        }

        function resetCacheStats() {
            cachedCount = 0;
            maxCacheAge = 0;
        }

        function updateRetryButton() {
            if (!$retryBtn.length) {
                return;
            }

            $retryBtn.prop('disabled', isScanning || failedItems.length === 0);
        }

        function prepareScanUI() {
            $scanBtn.prop('disabled', true).addClass('scanning').text((VulnTitan.i18n.scanning || 'Scanning') + '...');
            $btnMal.prop('disabled', true);
            $btnInt.prop('disabled', true);
            $stopBtn.prop('disabled', false);
            $retryBtn.prop('disabled', true);
            $integrityLegend.hide();
            $integrityProblematic.hide();
            $integrityNextSteps.hide();
            $integrityProblematicSummary.empty();
            $integrityProblematicList.empty();
            $integrityNextStepsList.empty();
            $malwareOverviewContainer.hide();
            $malwareOverviewContent.empty();
            $malwareProblematicContainer.hide();
            $malwareProblematicSummary.empty();
            $malwareProblematicList.empty();
            $vulnOverviewContainer.hide();
            $vulnOverviewContent.empty();
            $results.empty();
            $resultsContainer
                .find('.vuln-scan-result-item, .vulntitan-scan-result')
                .remove();
            $progressBarContainer.show();
            $resultsContainer.show().addClass('is-vulnerability-layout');
            $progressBar.css('width', '0%');
            $('#vulntitan-scan-progress-text').text('0%');
            setProgressNote(VulnTitan.i18n.preparing || 'Preparing...');
            autoScroll = true;
            $resultsContainer.off('scroll.vulntitan').on('scroll.vulntitan', function () {
                const container = $resultsContainer.get(0);
                if (!container) {
                    return;
                }

                const distance = container.scrollHeight - container.scrollTop - container.clientHeight;
                autoScroll = distance < 40;
            });
        }

        function resetUI() {
            isScanning = false;
            $scanBtn.prop('disabled', false).removeClass('scanning').text(VulnTitan.i18n.scan_now || 'Scan Now');
            $btnMal.prop('disabled', false);
            $btnInt.prop('disabled', false);
            $stopBtn.prop('disabled', true);
            updateRetryButton();
        }

        function startScan(queue, options) {
            scanQueue = Array.isArray(queue) ? queue.slice() : [];
            total = scanQueue.length;
            currentIndex = 0;
            currentRowId = '';
            stopRequested = false;
            currentRequest = null;
            failedItems = [];
            resetStats();
            resetCacheStats();
            riskPayloads.clear();
            riskAuditCache.clear();
            isScanning = true;

            prepareScanUI();
            renderLayout();
            loadLastScanAt();
            updateOverview();

            if (!scanQueue.length) {
                $results.append(`<p>${escapeHtml(VulnTitan.i18n.no_targets || 'No scan targets found.')}</p>`);
                $resultsContainer.removeClass('is-vulnerability-layout');
                setProgressNote('');
                resetUI();
                return;
            }

            scanNext();
        }

        function componentCleanMessage(item) {
            if ((item.type || '') === 'core') {
                return VulnTitan.i18n.vuln_component_clean_core || 'No vulnerabilities found for WordPress core.';
            }

            return `${VulnTitan.i18n.vuln_component_clean_prefix || 'No vulnerabilities found for'} ${componentTypeLabel(item.type).toLowerCase()} ${componentDisplayName(item)}.`;
        }

        function highestSeverity(vulnerabilities) {
            let highest = 'unknown';

            vulnerabilities.forEach(function (vuln) {
                const severity = normalizeSeverity(vuln.cvss_rating);
                if (severityWeight(severity) > severityWeight(highest)) {
                    highest = severity;
                }
            });

            return highest;
        }

        function updateOverview() {
            $overviewScanned.text(stats.scanned);
            $overviewVulnerable.text(stats.vulnerableTargets);
            $overviewFindings.text(stats.findings);

            const severityHtml = severityOrder.map(function (severity) {
                return `
                    <span class="vulntitan-vuln-severity-chip">
                        <span class="vulntitan-vuln-severity-dot" style="background:${severityColor(severity)};"></span>
                        ${escapeHtml(severityLabel(severity))}: ${stats.severity[severity]}
                    </span>
                `;
            }).join('');

            const errorHtml = stats.errors > 0
                ? `<span class="vulntitan-vuln-severity-chip">${escapeHtml(VulnTitan.i18n.vuln_errors || 'Errors')}: ${stats.errors}</span>`
                : '';

            $overviewSeverity.html(severityHtml + errorHtml);
            updateMetaRow();
        }

        function recalculateStatsFromDOM() {
            const $vulnerable = $detailsList.children('.vulntitan-vuln-detail-item[data-kind="vulnerable"]');
            stats.vulnerableTargets = $vulnerable.length;
            stats.findings = $detailsList.find('.vulntitan-vuln-finding-card').length;
            stats.severity = {
                critical: 0,
                high: 0,
                medium: 0,
                low: 0,
                unknown: 0
            };

            $detailsList.find('.vulntitan-vuln-finding-card').each(function () {
                const sev = String($(this).data('severity') || 'unknown');
                if (stats.severity[sev] === undefined) {
                    stats.severity.unknown += 1;
                } else {
                    stats.severity[sev] += 1;
                }
            });

            updateOverview();
        }

        function appendVulnerableComponent(item, vulnerabilities) {
            if (!Array.isArray(vulnerabilities) || !vulnerabilities.length) {
                return;
            }

            $componentsEmpty.hide();

            const severity = highestSeverity(vulnerabilities);
            const componentName = componentDisplayName(item);
            const metaBits = componentMetaBits(item);
            const isActive = item && item.active ? 'active' : 'inactive';
            const hasFix = item && item.has_fix ? 'yes' : 'no';
            const actionsHtml = renderComponentActions(item);

            $componentsList.append(`
                <article class="vulntitan-vuln-component-card" data-type="${escapeHtml(item.type || '')}" data-item-slug="${escapeHtml(item.slug || '')}" data-plugin-file="${escapeHtml(item.plugin_file || '')}" data-theme-slug="${escapeHtml(item.theme_slug || '')}" data-severity="${escapeHtml(severity)}" data-active="${escapeHtml(isActive)}" data-has-fix="${escapeHtml(hasFix)}" data-name="${escapeHtml(componentName.toLowerCase())}" data-findings="${vulnerabilities.length}">
                    <div class="vulntitan-vuln-component-top">
                        <span class="vulntitan-vuln-type-pill">${escapeHtml(componentTypeLabel(item.type))}</span>
                        <span class="vulntitan-vuln-severity-pill is-${escapeHtml(severity)}">${escapeHtml(severityLabel(severity))}</span>
                    </div>
                    <div class="vulntitan-vuln-component-title">${escapeHtml(componentName)}</div>
                    <div class="vulntitan-vuln-component-meta">
                        ${escapeHtml(`${vulnerabilities.length} ${VulnTitan.i18n.vuln_issues_found || 'issue(s) found'}`)}
                        ${metaBits.length ? ` • ${escapeHtml(metaBits.slice(1).join(' • '))}` : ''}
                    </div>
                    ${actionsHtml}
                </article>
            `);

            applyFilters();
        }

        function renderFindingCard(vuln, item) {
            const severity = normalizeSeverity(vuln.cvss_rating);
            const severityLabelText = severityLabel(severity);
            const cve = vuln.cve ? escapeHtml(vuln.cve) : 'N/A';
            const remediation = vuln.remediation ? escapeHtml(vuln.remediation) : '';
            const vulnTitle = vuln.title ? escapeHtml(vuln.title) : 'Untitled vulnerability';
            const detailsUrl = vuln.id
                ? `https://vulntitan.com/vulnerabilities/${encodeURIComponent(vuln.id)}?utm_source=vulntitan-plugin&utm_medium=scan-result&utm_campaign=vulntitan-tracking`
                : '';
            const fixedVersion = normalizeArrayValue(vuln.fixed_version || vuln.fix_version || vuln.fixed);
            const affectedVersions = normalizeArrayValue(vuln.affected_versions || vuln.affected_version || vuln.affected);
            const cvssScore = formatCvssScore(vuln.cvss_score || vuln.cvss || vuln.cvssScore);
            const cvssVector = normalizeArrayValue(vuln.cvss_vector || vuln.cvss_vector_string || vuln.cvssVector);
            const publishedAt = formatPublishedAt(vuln.published_at || vuln.published || vuln.disclosure_date);
            const exploitStatus = formatExploitStatus(vuln.exploit_status || vuln.exploit || vuln.exploited || vuln.exploit_known);
            const risk = computeRiskScore(vuln, item);
            const riskUid = vuln.risk_uid ? String(vuln.risk_uid) : '';
            const decision = vuln.risk_decision && vuln.risk_decision.status ? vuln.risk_decision : null;
            const decisionLabel = decision
                ? `${decision.status === 'ignore' ? (VulnTitan.i18n.vuln_risk_status_ignored || 'Ignored') : (VulnTitan.i18n.vuln_risk_status_accepted || 'Risk accepted')}${decision.expires_at ? ` • ${escapeHtml(VulnTitan.i18n.vuln_risk_expires || 'Expires')}: ${escapeHtml(formatPublishedAt(decision.expires_at))}` : ''}`
                : '';

            if (riskUid) {
                riskPayloads.set(riskUid, {
                    item: item,
                    vulnerability: vuln
                });
            }

            return `
                <article class="vulntitan-vuln-finding-card${decision ? ' is-decided' : ''}${decision && decision.status === 'ignore' ? ' is-ignored' : ''}" data-risk-uid="${escapeHtml(riskUid)}" data-severity="${escapeHtml(severity)}">
                    <div class="vulntitan-vuln-finding-top">
                        <strong class="vulntitan-vuln-finding-title">${vulnTitle}</strong>
                        <div class="vulntitan-vuln-finding-badges">
                            <span class="vulntitan-vuln-risk-pill is-${escapeHtml(risk.level)}">${escapeHtml(VulnTitan.i18n.vuln_risk_score || 'Risk score')} ${risk.score.toFixed(1)}</span>
                            <span class="vulntitan-vuln-severity-pill is-${escapeHtml(severity)}">${escapeHtml(severityLabelText)}</span>
                        </div>
                    </div>
                    ${decisionLabel ? `<div class="vulntitan-vuln-risk-status">${escapeHtml(decisionLabel)}</div>` : ''}
                    <div class="vulntitan-vuln-finding-meta">${escapeHtml(VulnTitan.i18n.cve || 'CVE')}: ${cve}</div>
                    <div class="vulntitan-vuln-finding-data">
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_fixed_version || 'Fixed version')}</span><strong>${escapeHtml(fixedVersion || '--')}</strong></div>
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_affected_versions || 'Affected versions')}</span><strong>${escapeHtml(affectedVersions || '--')}</strong></div>
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_cvss_score || 'CVSS score')}</span><strong>${escapeHtml(cvssScore || '--')}</strong></div>
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_cvss_vector || 'CVSS vector')}</span><strong>${escapeHtml(cvssVector || '--')}</strong></div>
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_published_at || 'Published')}</span><strong>${escapeHtml(publishedAt || '--')}</strong></div>
                        <div class="vulntitan-vuln-finding-row"><span>${escapeHtml(VulnTitan.i18n.vuln_exploit_status || 'Exploit status')}</span><strong>${escapeHtml(exploitStatus || '--')}</strong></div>
                    </div>
                    ${remediation ? `<div class="vulntitan-vuln-finding-copy">${remediation}</div>` : ''}
                    <div class="vulntitan-vuln-finding-actions">
                        <label class="vulntitan-vuln-risk-expiry">
                            <span>${escapeHtml(VulnTitan.i18n.vuln_expires_in || 'Expires in')}</span>
                            <select class="vulntitan-vuln-select">
                                <option value="7">${escapeHtml(VulnTitan.i18n.vuln_expires_7 || '7 days')}</option>
                                <option value="30" selected>${escapeHtml(VulnTitan.i18n.vuln_expires_30 || '30 days')}</option>
                                <option value="90">${escapeHtml(VulnTitan.i18n.vuln_expires_90 || '90 days')}</option>
                                <option value="365">${escapeHtml(VulnTitan.i18n.vuln_expires_365 || '1 year')}</option>
                            </select>
                        </label>
                        <button type="button" class="vulntitan-vuln-action vulntitan-risk-action" data-risk-action="accept">${escapeHtml(VulnTitan.i18n.vuln_action_accept_risk || 'Accept risk')}</button>
                        <button type="button" class="vulntitan-vuln-action is-ghost vulntitan-risk-action" data-risk-action="ignore">${escapeHtml(VulnTitan.i18n.vuln_action_ignore || 'Ignore')}</button>
                        <button type="button" class="vulntitan-vuln-action is-ghost vulntitan-risk-clear">${escapeHtml(VulnTitan.i18n.vuln_action_clear_decision || 'Clear decision')}</button>
                        <button type="button" class="vulntitan-vuln-action is-ghost vulntitan-risk-audit-toggle">${escapeHtml(VulnTitan.i18n.vuln_risk_audit || 'Audit log')}</button>
                        ${detailsUrl ? `<a href="${detailsUrl}" class="vulntitan-vuln-link" target="_blank" rel="noopener noreferrer">${escapeHtml(VulnTitan.i18n.read_more || 'Read More')}</a>` : ''}
                    </div>
                    <div class="vulntitan-vuln-risk-audit" hidden></div>
                </article>
            `;
        }

        function bindRiskActions() {
            if (!$results || !$results.length) {
                return;
            }

            $results.off('click.vulntitanRisk');
            $results.on('click.vulntitanRisk', '.vulntitan-vuln-action-link', function (event) {
                event.preventDefault();
                const $link = $(this);
                const actionKind = String($link.data('action-kind') || '');

                if (actionKind === 'update') {
                    handleInlineUpdate($link);
                    return;
                }

                if (actionKind === 'deactivate') {
                    handleInlineDeactivate($link);
                    return;
                }

                if (actionKind === 'open') {
                    const rawUrl = String($link.data('action-url') || '');
                    if (!rawUrl) {
                        return;
                    }
                    const url = rawUrl.replace(/&amp;/g, '&').replace(/&#038;/g, '&');
                    window.open(url, '_blank', 'noopener');
                    return;
                }
            });
            $results.on('click.vulntitanRisk', '.vulntitan-risk-action', function () {
                handleRiskDecision($(this));
            });
            $results.on('click.vulntitanRisk', '.vulntitan-risk-clear', function () {
                handleRiskClear($(this));
            });
            $results.on('click.vulntitanRisk', '.vulntitan-risk-audit-toggle', function () {
                handleRiskAudit($(this));
            });
        }

        function handleRiskDecision($button) {
            const $card = $button.closest('.vulntitan-vuln-finding-card');
            const uid = String($card.data('risk-uid') || '');
            const action = String($button.data('risk-action') || '');

            if (!uid || !riskPayloads.has(uid)) {
                return;
            }

            const payload = riskPayloads.get(uid);
            const expiresIn = parseInt($card.find('.vulntitan-vuln-risk-expiry select').val(), 10) || 30;
            const notePrompt = VulnTitan.i18n.vuln_risk_note_prompt || 'Add a short note for the audit log (optional):';
            const noteInput = window.prompt(notePrompt, '');
            if (noteInput === null) {
                return;
            }
            const note = noteInput || '';

            $button.prop('disabled', true);

            $.ajax({
                url: VulnTitan.ajaxUrl,
                method: 'POST',
                data: {
                    action: 'vulntitan_vuln_risk_update',
                    nonce: VulnTitan.nonce,
                    decision: action,
                    expires_in: expiresIn,
                    note: note,
                    item: payload.item || {},
                    vulnerability: payload.vulnerability || {}
                }
            }).done(function (response) {
                if (!response || !response.success) {
                    return;
                }

                const decision = response.data && response.data.decision ? response.data.decision : null;
                if (decision) {
                    updateRiskCard($card, decision);
                }
            }).always(function () {
                $button.prop('disabled', false);
            });
        }

        function handleRiskClear($button) {
            const $card = $button.closest('.vulntitan-vuln-finding-card');
            const uid = String($card.data('risk-uid') || '');

            if (!uid || !riskPayloads.has(uid)) {
                return;
            }

            const payload = riskPayloads.get(uid);
            const notePrompt = VulnTitan.i18n.vuln_risk_note_prompt || 'Add a short note for the audit log (optional):';
            const noteInput = window.prompt(notePrompt, '');
            if (noteInput === null) {
                return;
            }
            const note = noteInput || '';

            $button.prop('disabled', true);

            $.ajax({
                url: VulnTitan.ajaxUrl,
                method: 'POST',
                data: {
                    action: 'vulntitan_vuln_risk_clear',
                    nonce: VulnTitan.nonce,
                    note: note,
                    item: payload.item || {},
                    vulnerability: payload.vulnerability || {}
                }
            }).done(function (response) {
                if (!response || !response.success) {
                    return;
                }

                updateRiskCard($card, null);
            }).always(function () {
                $button.prop('disabled', false);
            });
        }

        function handleRiskAudit($button) {
            const $card = $button.closest('.vulntitan-vuln-finding-card');
            const uid = String($card.data('risk-uid') || '');
            const $panel = $card.find('.vulntitan-vuln-risk-audit');

            if (!uid || !$panel.length) {
                return;
            }

            if (riskAuditCache.has(uid)) {
                $panel.html(riskAuditCache.get(uid));
                $panel.prop('hidden', !$panel.prop('hidden'));
                return;
            }

            $panel.prop('hidden', false).html(`<div class="vulntitan-vuln-risk-audit-loading">${escapeHtml(VulnTitan.i18n.loading || 'Loading...')}</div>`);

            $.ajax({
                url: VulnTitan.ajaxUrl,
                method: 'POST',
                data: {
                    action: 'vulntitan_vuln_risk_audit',
                    nonce: VulnTitan.nonce,
                    risk_uid: uid
                }
            }).done(function (response) {
                if (!response || !response.success) {
                    return;
                }

                const rows = response.data && Array.isArray(response.data.audit) ? response.data.audit : [];
                let html = '';
                if (!rows.length) {
                    html = `<div class="vulntitan-vuln-risk-audit-empty">${escapeHtml(VulnTitan.i18n.vuln_risk_audit_empty || 'No risk decisions logged yet.')}</div>`;
                } else {
                    html = `
                        <ul class="vulntitan-vuln-risk-audit-list">
                            ${rows.map(function (row) {
                                const who = row.user_label ? row.user_label : (row.user_id ? `User #${row.user_id}` : 'System');
                                const when = row.created_at ? formatPublishedAt(row.created_at) : '--';
                                const expires = row.expires_at ? `${escapeHtml(VulnTitan.i18n.vuln_risk_expires || 'Expires')}: ${escapeHtml(formatPublishedAt(row.expires_at))}` : '';
                                const note = row.note ? ` • ${escapeHtml(row.note)}` : '';
                                return `<li><strong>${escapeHtml(String(row.action || ''))}</strong> — ${escapeHtml(who)} • ${escapeHtml(when)} ${expires}${note}</li>`;
                            }).join('')}
                        </ul>
                    `;
                }

                riskAuditCache.set(uid, html);
                $panel.html(html);
            });
        }

        function updateRiskCard($card, decision) {
            const $status = $card.find('.vulntitan-vuln-risk-status');
            if (!decision) {
                $card.removeClass('is-decided is-ignored');
                $status.remove();
                return;
            }

            const label = decision.status === 'ignore'
                ? (VulnTitan.i18n.vuln_risk_status_ignored || 'Ignored')
                : (VulnTitan.i18n.vuln_risk_status_accepted || 'Risk accepted');
            const expiresLabel = decision.expires_at
                ? `${VulnTitan.i18n.vuln_risk_expires || 'Expires'}: ${formatPublishedAt(decision.expires_at)}`
                : '';
            const text = `${label}${expiresLabel ? ' • ' + expiresLabel : ''}`;

            if ($status.length) {
                $status.text(text);
            } else {
                $card.find('.vulntitan-vuln-finding-meta').first().before(`<div class="vulntitan-vuln-risk-status">${escapeHtml(text)}</div>`);
            }

            $card.toggleClass('is-ignored', decision.status === 'ignore');
            $card.addClass('is-decided');
        }

        function ensureToastContainer() {
            let $container = $('.vulntitan-firewall-feedback');
            if (!$container.length) {
                $container = $('<div class="vulntitan-firewall-feedback"></div>');
                $('body').append($container);
            }

            return $container;
        }

        function showToast(type, label, message) {
            const $container = ensureToastContainer();
            const normalizedType = String(type || 'info');
            const badge = label || '';
            const text = message || '';
            const $toast = $(`
                <div class="vulntitan-firewall-toast is-${escapeHtml(normalizedType)}" role="status" aria-live="polite">
                    <span class="vulntitan-firewall-toast-badge">${escapeHtml(badge)}</span>
                    <div class="vulntitan-firewall-toast-message">${escapeHtml(text)}</div>
                    <button type="button" class="vulntitan-firewall-toast-close" aria-label="Dismiss">x</button>
                </div>
            `);

            $container.append($toast);
            requestAnimationFrame(function () {
                $container.addClass('is-visible');
            });

            const close = function () {
                $toast.remove();
                if (!$container.children().length) {
                    $container.removeClass('is-visible');
                }
            };

            $toast.on('click', '.vulntitan-firewall-toast-close', close);
            setTimeout(close, 4500);
        }

        function handleInlineUpdate($link) {
            const type = String($link.data('item-type') || '');
            const pluginFile = String($link.data('plugin-file') || '');
            const themeSlug = String($link.data('theme-slug') || '');
            const itemSlug = String($link.data('item-slug') || '');
            const rawUrl = String($link.data('action-url') || '');

            if (type === 'core') {
                showToast('warning', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_core_update_notice || 'Open the Updates page to apply the WordPress core update.');
                if (rawUrl) {
                    window.open(rawUrl.replace(/&amp;/g, '&').replace(/&#038;/g, '&'), '_blank', 'noopener');
                }
                return;
            }

            if (!window.wp || !wp.updates) {
                showToast('error', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_failed || 'Update failed.');
                return;
            }

            showToast('info', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_started || 'Starting update...');

            const onSuccess = function (response) {
                showToast('success', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_success || 'Update completed.');
                if (type === 'plugin' && pluginFile) {
                    $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`).attr('data-has-fix', 'no');
                    $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"] [data-action-kind="update"]`).remove();
                }
                if (type === 'theme' && themeSlug) {
                    $(`[data-theme-slug="${themeSlug.replace(/"/g, '\\"')}"]`).attr('data-has-fix', 'no');
                    $(`[data-theme-slug="${themeSlug.replace(/"/g, '\\"')}"] [data-action-kind="update"]`).remove();
                }
                applyFilters();
                refreshItemAfterUpdate(type, pluginFile, themeSlug, itemSlug);
            };

            const onError = function () {
                showToast('error', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_failed || 'Update failed.');
            };

            if (type === 'plugin' && pluginFile && wp.updates.ajax) {
                wp.updates.ajax('update-plugin', {
                    plugin: pluginFile,
                    slug: themeSlug || '',
                    success: onSuccess,
                    error: onError
                });
            } else if (type === 'theme' && themeSlug && wp.updates.ajax) {
                wp.updates.ajax('update-theme', {
                    slug: themeSlug,
                    success: onSuccess,
                    error: onError
                });
            } else {
                onError();
            }
        }

        function refreshItemAfterUpdate(type, pluginFile, themeSlug, slug) {
            $.ajax({
                url: VulnTitan.ajaxUrl,
                method: 'POST',
                data: {
                    action: 'vulntitan_vulnerability_rescan_item',
                    nonce: VulnTitan.nonce,
                    type: type,
                    plugin_file: pluginFile,
                    theme_slug: themeSlug,
                    slug: slug
                }
            }).done(function (response) {
                if (!response || !response.success) {
                    return;
                }

                const item = response.data && response.data.item ? response.data.item : null;
                const vulnerabilities = response.data && Array.isArray(response.data.vulnerabilities)
                    ? response.data.vulnerabilities
                    : [];
                const metaNote = buildMetaNote(response.data && response.data.meta ? response.data.meta : null);

                if (!item) {
                    return;
                }

                const selector = buildItemSelector(item);
                const $detail = $detailsList.find(selector).first();
                const rowId = $detail.attr('id') || ('scan-item-refresh-' + Date.now());
                const mode = vulnerabilities.length > 0 ? 'vulnerable' : 'clean';

                if ($detail.length) {
                    $detail.replaceWith(renderDetailItem(item, {
                        rowId: rowId,
                        mode: mode,
                        vulnerabilities: vulnerabilities,
                        metaNote: metaNote
                    }));
                }

                $componentsList.find(selector).remove();
                if (vulnerabilities.length > 0) {
                    appendVulnerableComponent(item, vulnerabilities);
                }

                applyFilters();
                recalculateStatsFromDOM();
            });
        }

        function buildItemSelector(item) {
            const type = String(item.type || '');
            const pluginFile = String(item.plugin_file || '');
            const themeSlug = String(item.theme_slug || '');
            const slug = String(item.slug || '');

            if (pluginFile) {
                return `[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`;
            }

            if (themeSlug) {
                return `[data-theme-slug="${themeSlug.replace(/"/g, '\\"')}"]`;
            }

            if (slug) {
                return `[data-item-slug="${slug.replace(/"/g, '\\"')}"][data-type="${type.replace(/"/g, '\\"')}"]`;
            }

            return `[data-type="${type.replace(/"/g, '\\"')}"]`;
        }

        function handleInlineDeactivate($link) {
            const pluginFile = String($link.data('plugin-file') || '');
            const rawUrl = String($link.data('action-url') || '');
            if (!rawUrl) {
                return;
            }

            const url = rawUrl.replace(/&amp;/g, '&').replace(/&#038;/g, '&');
            showToast('info', VulnTitan.i18n.vuln_deactivate_label || 'Deactivate', VulnTitan.i18n.vuln_deactivate_started || VulnTitan.i18n.vuln_update_started || 'Starting...');

            fetch(url, { credentials: 'same-origin' })
                .then(function (response) {
                    if (!response.ok) {
                        throw new Error('request_failed');
                    }
                    return response.text();
                })
                .then(function () {
                    showToast('success', VulnTitan.i18n.vuln_deactivate_label || 'Deactivate', VulnTitan.i18n.vuln_deactivate_success || 'Plugin deactivated.');
                    if (pluginFile) {
                        $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`).closest('.vulntitan-vuln-detail-item').attr('data-active', 'inactive');
                        $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`).closest('.vulntitan-vuln-component-card').attr('data-active', 'inactive');
                        $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`).remove();
                    }
                    applyFilters();
                })
                .catch(function () {
                    showToast('error', VulnTitan.i18n.vuln_deactivate_label || 'Deactivate', VulnTitan.i18n.vuln_deactivate_failed || 'Deactivate failed.');
                });
        }

        function bindUpdateEvents() {
            if (!window.wp || !wp.updates) {
                return;
            }

            $(document)
                .off('wp-plugin-update-success.vulntitan wp-theme-update-success.vulntitan wp-plugin-update-error.vulntitan wp-theme-update-error.vulntitan')
                .on('wp-plugin-update-success.vulntitan', function (event, response) {
                    const pluginFile = response && response.plugin ? String(response.plugin) : '';
                    showToast('success', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_success || 'Update completed.');
                    if (pluginFile) {
                        $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"]`).attr('data-has-fix', 'no');
                        $(`[data-plugin-file="${pluginFile.replace(/"/g, '\\"')}"] [data-action-kind="update"]`).remove();
                    }
                })
                .on('wp-theme-update-success.vulntitan', function (event, response) {
                    const themeSlug = response && response.slug ? String(response.slug) : '';
                    showToast('success', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_success || 'Update completed.');
                    if (themeSlug) {
                        $(`[data-theme-slug="${themeSlug.replace(/"/g, '\\"')}"]`).attr('data-has-fix', 'no');
                        $(`[data-theme-slug="${themeSlug.replace(/"/g, '\\"')}"] [data-action-kind="update"]`).remove();
                    }
                })
                .on('wp-plugin-update-error.vulntitan wp-theme-update-error.vulntitan', function () {
                    showToast('error', VulnTitan.i18n.vuln_update_label || 'Update', VulnTitan.i18n.vuln_update_failed || 'Update failed.');
                });
        }

        function renderDetailItem(item, options) {
            const config = $.extend({
                rowId: '',
                mode: 'pending',
                vulnerabilities: [],
                errorMessage: '',
                metaNote: ''
            }, options || {});
            const componentName = componentDisplayName(item);
            const metaBits = componentMetaBits(item);
            if (config.metaNote) {
                metaBits.push(config.metaNote);
            }
            const vulnerabilities = Array.isArray(config.vulnerabilities) ? config.vulnerabilities : [];
            const severity = highestSeverity(vulnerabilities);
            const isActive = item && item.active ? 'active' : 'inactive';
            const hasFix = item && item.has_fix ? 'yes' : 'no';
            const dataSeverity = config.mode === 'vulnerable'
                ? severity
                : (config.mode === 'clean' ? 'clean' : (config.mode === 'error' ? 'error' : (config.mode === 'stopped' ? 'stopped' : 'pending')));
            const badgesHtml = config.mode === 'vulnerable'
                ? `
                    <div class="vulntitan-vuln-detail-badges">
                        <span class="vulntitan-vuln-type-pill">${escapeHtml(componentTypeLabel(item.type))}</span>
                        <span class="vulntitan-vuln-severity-pill is-${escapeHtml(severity)}">${escapeHtml(severityLabel(severity))}</span>
                    </div>
                `
                : `<span class="vulntitan-vuln-type-pill">${escapeHtml(componentTypeLabel(item.type))}</span>`;

            let bodyHtml = '';

            if (config.mode === 'pending') {
                bodyHtml = `<div class="vulntitan-vuln-notice is-pending">${escapeHtml(VulnTitan.i18n.vuln_scanning_status || 'Scanning live intelligence...')}</div>`;
            } else if (config.mode === 'stopped') {
                bodyHtml = `<div class="vulntitan-vuln-notice is-error">${escapeHtml(config.errorMessage || (VulnTitan.i18n.vuln_scan_stopped || 'Scan stopped by user.'))}</div>`;
            } else if (config.mode === 'error') {
                bodyHtml = `<div class="vulntitan-vuln-notice is-error">${escapeHtml(VulnTitan.i18n.error || 'Error')}: ${escapeHtml(config.errorMessage || 'Unknown error')}</div>`;
            } else if (config.mode === 'clean') {
                bodyHtml = `<div class="vulntitan-vuln-notice is-clean">${escapeHtml(componentCleanMessage(item))}</div>`;
            } else {
                bodyHtml = `
                    <div class="vulntitan-vuln-detail-status">${vulnerabilities.length} ${escapeHtml(VulnTitan.i18n.vuln_issues_found || 'issue(s) found')}</div>
                    <div class="vulntitan-vuln-findings">
                        ${vulnerabilities.map(function (vuln) { return renderFindingCard(vuln, item); }).join('')}
                    </div>
                `;
            }

            const actionsHtml = renderComponentActions(item);

            return `
                <article id="${escapeHtml(config.rowId)}" class="vulntitan-vuln-detail-item is-${escapeHtml(config.mode)}" data-type="${escapeHtml(item.type || '')}" data-item-slug="${escapeHtml(item.slug || '')}" data-plugin-file="${escapeHtml(item.plugin_file || '')}" data-theme-slug="${escapeHtml(item.theme_slug || '')}" data-severity="${escapeHtml(dataSeverity)}" data-active="${escapeHtml(isActive)}" data-has-fix="${escapeHtml(hasFix)}" data-name="${escapeHtml(componentName.toLowerCase())}" data-findings="${vulnerabilities.length}" data-kind="${escapeHtml(config.mode)}">
                    <div class="vulntitan-vuln-detail-top">
                        <div>
                            <div class="vulntitan-vuln-detail-title">${escapeHtml(componentName)}</div>
                            <div class="vulntitan-vuln-detail-meta">${escapeHtml(metaBits.join(' • '))}</div>
                        </div>
                        ${badgesHtml}
                    </div>
                    ${actionsHtml}
                    ${bodyHtml}
                </article>
            `;
        }

        function getFilterState() {
            return {
                severity: $filterSeverity.length ? $filterSeverity.val() : 'all',
                type: $filterType.length ? $filterType.val() : 'all',
                status: $filterStatus.length ? $filterStatus.val() : 'all',
                fix: $filterFix.length ? $filterFix.val() : 'all',
                sort: $sortOrder.length ? $sortOrder.val() : 'severity'
            };
        }

        function itemMatchesFilters($item, filters) {
            const kind = String($item.data('kind') || '');
            if (kind === 'pending' || kind === 'notice') {
                return true;
            }

            const type = String($item.data('type') || '');
            const severity = String($item.data('severity') || '');
            const status = String($item.data('active') || '');
            const hasFix = String($item.data('has-fix') || '');

            if (filters.type !== 'all' && type !== filters.type) {
                return false;
            }

            if (filters.status !== 'all' && status !== filters.status) {
                return false;
            }

            if (filters.fix !== 'all' && hasFix !== filters.fix) {
                return false;
            }

            if (filters.severity !== 'all' && severity !== filters.severity) {
                return false;
            }

            return true;
        }

        function applyFilters() {
            const filters = getFilterState();
            applyFiltersToList($componentsList, '.vulntitan-vuln-component-card', filters);
            applyFiltersToList($detailsList, '.vulntitan-vuln-detail-item', filters);

            if ($componentsEmpty.length) {
                const visibleComponents = $componentsList.children('.vulntitan-vuln-component-card:visible').length;
                if (visibleComponents === 0) {
                    $componentsEmpty.show();
                } else {
                    $componentsEmpty.hide();
                }
            }
        }

        function applyFiltersToList($list, selector, filters) {
            if (!$list || !$list.length) {
                return;
            }

            const $items = $list.children(selector);
            $items.each(function () {
                const $item = $(this);
                if (itemMatchesFilters($item, filters)) {
                    $item.show();
                } else {
                    $item.hide();
                }
            });

            sortList($list, selector, filters.sort);
        }

        function severityRankForSort(value) {
            switch (String(value || '').toLowerCase()) {
                case 'critical':
                    return 5;
                case 'high':
                    return 4;
                case 'medium':
                    return 3;
                case 'low':
                    return 2;
                case 'unknown':
                    return 1;
                case 'clean':
                    return 0;
                case 'error':
                    return -1;
                case 'stopped':
                    return -2;
                default:
                    return -3;
            }
        }

        function sortList($list, selector, sortBy) {
            if (!$list || !$list.length) {
                return;
            }

            const items = $list.children(selector).get();
            items.sort(function (a, b) {
                const aKind = String(a.dataset.kind || '');
                const bKind = String(b.dataset.kind || '');

                if (aKind === 'notice' && bKind !== 'notice') {
                    return 1;
                }

                if (bKind === 'notice' && aKind !== 'notice') {
                    return -1;
                }

                if (sortBy === 'name') {
                    const aName = String(a.dataset.name || '').toLowerCase();
                    const bName = String(b.dataset.name || '').toLowerCase();
                    return aName.localeCompare(bName);
                }

                if (sortBy === 'findings') {
                    const aFindings = parseInt(a.dataset.findings || '0', 10);
                    const bFindings = parseInt(b.dataset.findings || '0', 10);
                    if (aFindings !== bFindings) {
                        return bFindings - aFindings;
                    }
                }

                const aSeverity = severityRankForSort(a.dataset.severity || '');
                const bSeverity = severityRankForSort(b.dataset.severity || '');
                if (aSeverity !== bSeverity) {
                    return bSeverity - aSeverity;
                }

                const aName = String(a.dataset.name || '').toLowerCase();
                const bName = String(b.dataset.name || '').toLowerCase();
                return aName.localeCompare(bName);
            });

            items.forEach(function (item) {
                $list.append(item);
            });
        }

        function updateProgress() {
            const percent = total > 0 ? Math.round((currentIndex / total) * 100) : 0;
            $progressBar.css('width', percent + '%');
            $('#vulntitan-scan-progress-text').text(percent + '%');
        }

        function scanNext() {
            if (stopRequested) {
                finalizeStop();
                return;
            }

            if (currentIndex >= total) {
                updateProgress();
                setProgressNote(VulnTitan.i18n.scan_finished || 'Scan finished.');
                $detailsList.append(`
                    <article class="vulntitan-vuln-detail-item is-finished" data-kind="notice">
                        <div class="vulntitan-vuln-notice is-finished">${escapeHtml(VulnTitan.i18n.scan_finished || 'Scan finished.')}</div>
                    </article>
                `);
                setLastScanAt(new Date());
                resetUI();
                applyFilters();
                return;
            }

            const item = scanQueue[currentIndex];
            const rowId = 'scan-item-' + currentIndex;
            currentRowId = rowId;
            setProgressNote(`${VulnTitan.i18n.scanning || 'Scanning'}: ${componentDisplayName(item)}`);

            $detailsList.append(renderDetailItem(item, {
                rowId: rowId,
                mode: 'pending'
            }));

            currentRequest = $.ajax({
                url: VulnTitan.ajaxUrl,
                method: 'POST',
                data: {
                    action: 'vulntitan_vulnerability_scan_item',
                    nonce: VulnTitan.nonce,
                    item: item
                }
            }).done(function (response) {
                stats.scanned += 1;

                const meta = response && response.data ? response.data.meta : null;
                const metaNote = buildMetaNote(meta);
                if (meta && meta.cached) {
                    cachedCount += 1;
                    maxCacheAge = Math.max(maxCacheAge, Number(meta.cache_age) || 0);
                }

                if (!response.success) {
                    stats.errors += 1;
                    failedItems.push(item);

                    $('#' + rowId).replaceWith(renderDetailItem(item, {
                        rowId: rowId,
                        mode: 'error',
                        errorMessage: response.data && response.data.message ? response.data.message : 'Unknown error',
                        metaNote: metaNote
                    }));

                    currentIndex++;
                    updateOverview();
                    updateProgress();
                    applyFilters();
                    scanNext();
                    return;
                }

                const vulnerabilities = Array.isArray(response.data.vulnerabilities)
                    ? response.data.vulnerabilities
                    : [];

                if (vulnerabilities.length > 0) {
                    stats.vulnerableTargets += 1;
                    stats.findings += vulnerabilities.length;

                    vulnerabilities.forEach(function (vuln) {
                        const severity = normalizeSeverity(vuln.cvss_rating);
                        stats.severity[severity] += 1;
                    });

                    appendVulnerableComponent(item, vulnerabilities);

                    $('#' + rowId).replaceWith(renderDetailItem(item, {
                        rowId: rowId,
                        mode: 'vulnerable',
                        vulnerabilities: vulnerabilities,
                        metaNote: metaNote
                    }));
                } else {
                    $('#' + rowId).replaceWith(renderDetailItem(item, {
                        rowId: rowId,
                        mode: 'clean',
                        metaNote: metaNote
                    }));
                }

                if (autoScroll) {
                    const container = document.getElementById('vulntitan-scan-results-container');
                    if (container) {
                        container.scrollTop = container.scrollHeight;
                    }
                }

                currentIndex++;
                updateOverview();
                updateProgress();
                applyFilters();
                scanNext();
            }).fail(function (jqXHR, textStatus) {
                if (stopRequested && textStatus === 'abort') {
                    $('#' + rowId).replaceWith(renderDetailItem(item, {
                        rowId: rowId,
                        mode: 'stopped',
                        errorMessage: VulnTitan.i18n.vuln_scan_stopped || 'Scan stopped by user.'
                    }));
                    finalizeStop();
                    return;
                }

                stats.scanned += 1;
                stats.errors += 1;
                failedItems.push(item);

                $('#' + rowId).replaceWith(renderDetailItem(item, {
                    rowId: rowId,
                    mode: 'error',
                    errorMessage: VulnTitan.i18n.error || 'Error'
                }));

                currentIndex++;
                updateOverview();
                updateProgress();
                applyFilters();
                scanNext();
            });
        }

        function requestStop() {
            if (!isScanning) {
                return;
            }

            stopRequested = true;
            setProgressNote(VulnTitan.i18n.vuln_scan_stopped || 'Scan stopped by user.');
            $stopBtn.prop('disabled', true);

            if (currentRequest && typeof currentRequest.abort === 'function') {
                currentRequest.abort();
                return;
            }

            finalizeStop();
        }

        function finalizeStop() {
            if (!isScanning) {
                return;
            }

            updateProgress();
            $detailsList.append(`
                <article class="vulntitan-vuln-detail-item is-stopped" data-kind="notice">
                    <div class="vulntitan-vuln-notice is-error">${escapeHtml(VulnTitan.i18n.vuln_scan_stopped || 'Scan stopped by user.')}</div>
                </article>
            `);
            setLastScanAt(new Date());
            resetUI();
            applyFilters();
        }

        $stopBtn.off('click').on('click', function () {
            requestStop();
        });

        $retryBtn.off('click').on('click', function () {
            if (!failedItems.length) {
                return;
            }

            startScan(failedItems, { isRetry: true });
        });

        startScan(items, { isRetry: false });
    });
});
