/* global csdtSiteAudit */
'use strict';

(function () {
    var ajaxUrl = csdtSiteAudit.ajaxUrl;
    var nonce   = csdtSiteAudit.nonce;

    var auditBtn      = document.getElementById('csdt-site-audit-btn');
    var progressWrap  = document.getElementById('csdt-site-audit-progress');
    var progressText  = document.getElementById('csdt-site-audit-progress-text');
    var resultsDiv    = document.getElementById('csdt-site-audit-results');

    var SEV_ORDER = { critical: 1, high: 2, medium: 3, low: 4, info: 5 };
    var SEV_COLOR = {
        critical: { bg: '#fef2f2', border: '#fca5a5', badge: '#dc2626', text: '#7f1d1d' },
        high:     { bg: '#fff7ed', border: '#fed7aa', badge: '#ea580c', text: '#7c2d12' },
        medium:   { bg: '#fefce8', border: '#fde68a', badge: '#ca8a04', text: '#713f12' },
        low:      { bg: '#f0fdf4', border: '#86efac', badge: '#16a34a', text: '#14532d' },
        info:     { bg: '#f0f9ff', border: '#7dd3fc', badge: '#0284c7', text: '#0c4a6e' },
    };
    var CAT_ICON = {
        'SEO': '📈', 'Content': '📝', 'Performance': '⚡', 'Database': '🗄️',
        'Security': '🔒', 'Plugins': '🔌', 'info': 'ℹ️',
    };

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

    // Convert "Title" (https://url) patterns in detail text to clickable links
    function linkifyDetail(text) {
        var parts = [];
        var re = /"([^"]+)"\s*\((https?:\/\/[^)]+)\)/g;
        var last = 0, m;
        while ((m = re.exec(text)) !== null) {
            parts.push(escHtml(text.slice(last, m.index)));
            parts.push('<a href="' + escHtml(m[2]) + '" target="_blank" rel="noopener" style="color:#2563eb;text-decoration:underline;">' + escHtml(m[1]) + '</a>');
            last = re.lastIndex;
        }
        parts.push(escHtml(text.slice(last)));
        return parts.join('');
    }

    function post(action, params) {
        var fd = new FormData();
        fd.append('action', action);
        fd.append('nonce', nonce);
        if (params) Object.keys(params).forEach(function (k) { fd.append(k, params[k]); });
        return fetch(ajaxUrl, { method: 'POST', body: fd, credentials: 'same-origin' })
            .then(function (r) { return r.json(); });
    }

    function secPost(action, params) {
        var fd = new FormData();
        fd.append('action', action);
        fd.append('nonce', csdtSiteAudit.secNonce || '');
        if (params) Object.keys(params).forEach(function (k) { fd.append(k, params[k]); });
        return fetch(ajaxUrl, { method: 'POST', body: fd, credentials: 'same-origin' })
            .then(function (r) { return r.json(); });
    }

    function renderScorecard(counts) {
        var total = Object.values(counts).reduce(function (s, n) { return s + n; }, 0);
        if (total === 0) return '';
        var items = ['critical', 'high', 'medium', 'low', 'info'].map(function (sev) {
            var c = counts[sev] || 0;
            if (c === 0) return '';
            var col = SEV_COLOR[sev];
            return '<div style="display:flex;flex-direction:column;align-items:center;background:' + col.bg +
                ';border:1px solid ' + col.border + ';border-radius:8px;padding:10px 16px;min-width:70px;">' +
                '<span style="font-size:1.5em;font-weight:800;color:' + col.badge + ';">' + c + '</span>' +
                '<span style="font-size:.75em;font-weight:600;color:' + col.text + ';text-transform:capitalize;">' + sev + '</span>' +
                '</div>';
        }).join('');
        var html = '<div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:16px;">' + items + '</div>';

        // Show security scan critical/high alongside audit scorecard so both sources are visible.
        var scanCrit = parseInt(csdtSiteAudit.scanCritical || 0, 10);
        var scanHigh = parseInt(csdtSiteAudit.scanHigh || 0, 10);
        if (scanCrit > 0 || scanHigh > 0) {
            var scanUrl = csdtSiteAudit.scanUrl || '#';
            var pills = '';
            if (scanCrit > 0) {
                pills += '<span style="background:#fef2f2;border:1px solid #fca5a5;border-radius:6px;padding:4px 12px;font-size:.82em;font-weight:700;color:#dc2626;">' + scanCrit + ' Critical</span>';
            }
            if (scanHigh > 0) {
                pills += '<span style="background:#fff7ed;border:1px solid #fed7aa;border-radius:6px;padding:4px 12px;font-size:.82em;font-weight:700;color:#ea580c;">' + scanHigh + ' High</span>';
            }
            html += '<div style="background:#fff7ed;border:1px solid #fed7aa;border-radius:8px;padding:10px 14px;margin-bottom:16px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:.85em;">' +
                '<span style="font-size:1em;">🛡️</span>' +
                '<strong style="color:#92400e;">Security scan also found:</strong>' +
                pills +
                '<a href="' + escHtml(scanUrl) + '" style="margin-left:auto;color:#b45309;font-weight:600;font-size:.9em;white-space:nowrap;">View security scan →</a>' +
                '</div>';
        }
        return html;
    }

    function renderFindingCard(f) {
        var sev = (f.severity || 'info').toLowerCase();
        var col = SEV_COLOR[sev] || SEV_COLOR.info;
        var icon = CAT_ICON[f.category] || '🔍';
        var ctaHtml = '';
        if (f.cta && f.cta.url && f.cta.label) {
            ctaHtml = '<div style="margin-top:10px;background:linear-gradient(135deg,#0f172a 0%,#1e3a5f 100%);border-radius:6px;padding:12px 14px;">' +
                '<div style="font-size:.78em;font-weight:700;color:#a5b4fc;text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px;">CloudScale Recommendation</div>' +
                '<div style="font-size:.83em;color:#cbd5e1;line-height:1.5;margin-bottom:10px;">' + escHtml(f.cta.desc || '') + '</div>' +
                '<a href="' + escHtml(f.cta.url) + '" target="_blank" rel="noopener" style="display:inline-block;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;text-decoration:none;font-size:.8em;font-weight:700;padding:7px 14px;border-radius:6px;white-space:nowrap;">' +
                escHtml(f.cta.label) + '</a>' +
                '</div>';
        }
        var fixActionHtml = '';
        var effectiveFixAction = f.fix_action;
        if (!effectiveFixAction && f.title && f.title.toLowerCase().indexOf('wp-config.php') !== -1) {
            effectiveFixAction = 'wpconfig_perms';
        }
        if (effectiveFixAction) {
            var seoFixActions   = { seo_ai_desc: 1, seo_ai_title: 1 };
            var quickFixActions = { cron_health: 'cron_health', expired_transients: 'expired_transients', wpconfig_perms: 'wpconfig_perms' };
            var modalFixActions = { db_prefix_modal: 'csdt-db-prefix-modal' };
            if (seoFixActions[effectiveFixAction]) {
                fixActionHtml = '<div style="margin-top:8px;"><a href="' + escHtml(csdtSiteAudit.seoAiUrl || '') +
                    '" style="display:inline-block;background:#10b981;color:#fff;text-decoration:none;font-size:.8em;font-weight:700;padding:6px 14px;border-radius:6px;">⚡ Fix It, Open SEO AI</a></div>';
            } else if (quickFixActions[effectiveFixAction]) {
                var dismissBtn = '';
                if (f.dismiss_id) {
                    dismissBtn = ' <button class="csdt-dismiss-btn" data-dismiss-id="' + escHtml(f.dismiss_id) +
                        '" style="background:none;color:#6b7280;border:1px solid #d1d5db;font-size:.8em;font-weight:600;padding:5px 12px;border-radius:6px;cursor:pointer;margin-left:6px;">' +
                        escHtml(f.dismiss_label || 'Acknowledge') + '</button>';
                }
                fixActionHtml = '<div style="margin-top:8px;">' +
                    '<button class="csdt-fix-it-btn" data-fix-id="' + escHtml(quickFixActions[effectiveFixAction]) +
                    '" style="background:#10b981;color:#fff;border:none;font-size:.8em;font-weight:700;padding:6px 14px;border-radius:6px;cursor:pointer;">⚡ Fix It</button>' +
                    dismissBtn +
                    '<span class="csdt-fix-it-status" style="display:none;margin-left:8px;font-size:.82em;color:#374151;"></span></div>';
            } else if (modalFixActions[effectiveFixAction]) {
                fixActionHtml = '<div style="margin-top:8px;">' +
                    '<button class="csdt-modal-fix-btn" data-modal="' + escHtml(modalFixActions[effectiveFixAction]) +
                    '" style="background:#10b981;color:#fff;border:none;font-size:.8em;font-weight:700;padding:6px 14px;border-radius:6px;cursor:pointer;">⚡ Fix It →</button>' +
                    '</div>';
            }
        }
        var linksHtml = '';
        if (f.links && f.links.length) {
            linksHtml = '<ul style="margin:0 0 8px;padding-left:0;list-style:none;font-size:.83em;">' +
                f.links.map(function (l) {
                    var linkText = l.label ? escHtml(l.label) : escHtml(l.url);
                    return '<li style="margin-bottom:3px;">' +
                        '<a href="' + escHtml(l.url) + '" target="_blank" rel="noopener" style="color:#2563eb;">' + linkText + '</a>' +
                        (l.words ? ' <span style="color:#6b7280;">(' + l.words + ' words)</span>' : '') +
                        '</li>';
                }).join('') + '</ul>';
        }
        return '<div style="background:' + col.bg + ';border:1px solid ' + col.border +
            ';border-radius:8px;padding:16px 20px;margin-bottom:12px;">' +
            '<div style="display:flex;align-items:flex-start;gap:12px;">' +
            '<span style="font-size:1.1em;margin-top:1px;">' + icon + '</span>' +
            '<div style="flex:1;min-width:0;">' +
            '<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px;">' +
            '<span style="background:' + col.badge + ';color:#fff;font-size:.7em;font-weight:700;padding:2px 8px;border-radius:20px;text-transform:uppercase;letter-spacing:.04em;">' + escHtml(sev) + '</span>' +
            '<span style="background:#e2e8f0;color:#475569;font-size:.7em;font-weight:600;padding:2px 8px;border-radius:20px;">' + escHtml(f.category || '') + '</span>' +
            ( f.affected ? '<span style="color:#94a3b8;font-size:.78em;">→ ' + escHtml(f.affected) + '</span>' : '' ) +
            '</div>' +
            '<p style="margin:0 0 6px;font-weight:700;color:#0f172a;font-size:.95em;line-height:1.4;">' + escHtml(f.title || '') +
            ( f.bf_last_attempt ? ' <span style="font-size:.75em;font-weight:400;color:#6b7280;margin-left:6px;">Last attempt: ' + escHtml(new Date(f.bf_last_attempt * 1000).toLocaleString()) + '</span>' : '' ) +
            '</p>' +
            '<p style="margin:0 0 8px;color:#4b5563;font-size:.87em;line-height:1.6;">' + linkifyDetail(f.detail || '') + '</p>' +
            linksHtml +
            '<div style="background:rgba(255,255,255,.7);border-left:2px solid ' + col.badge + ';padding:8px 12px;border-radius:0 4px 4px 0;font-size:.85em;color:#374151;line-height:1.5;">' +
            '<strong style="color:' + col.text + ';">Fix: </strong>' + escHtml(f.fix || '') +
            '</div>' +
            fixActionHtml +
            ctaHtml +
            '</div></div></div>';
    }

    function renderResults(data, runAt) {
        var findings  = (data.findings || []).slice().sort(function (a, b) {
            return (SEV_ORDER[a.severity] || 4) - (SEV_ORDER[b.severity] || 4);
        });
        var counts    = data.counts || {};
        var postCount = data.post_count || 0;
        var aiUsed    = data.ai_used;

        var html = '';

        // Header bar
        var runLabel = runAt
            ? '<span style="color:#6b7280;font-size:.8em;background:#f8fafc;border:1px solid #e2e8f0;border-radius:4px;padding:2px 8px;">Last run: ' + escHtml(new Date(runAt * 1000).toLocaleString()) + '</span>'
            : '';
        html += '<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;">' +
            '<h3 style="margin:0;color:#0f172a;font-size:1em;font-weight:700;">Site Audit Results</h3>' +
            '<span style="color:#6b7280;font-size:.85em;">,  ' + postCount + ' posts/pages scanned</span>' +
            ( aiUsed
                ? '<span style="background:#f0fdf4;border:1px solid #86efac;color:#15803d;font-size:.75em;font-weight:600;padding:2px 8px;border-radius:20px;">🤖 AI analysis</span>'
                : '<span style="background:#f0f9ff;border:1px solid #7dd3fc;color:#0369a1;font-size:.75em;font-weight:600;padding:2px 8px;border-radius:20px;">Rule-based</span>' ) +
            runLabel +
            '<div style="display:flex;gap:8px;margin-left:auto;">' +
            '<button id="cs-copy-all-btn" class="cs-copy-all-btn" style="background:#3b82f6;color:#fff;border:none;border-radius:6px;padding:5px 12px;font-size:.78em;font-weight:600;cursor:pointer;">📋 Copy All</button>' +
            '<button id="csdt-audit-pdf-btn" style="background:#0f172a;color:#fff;border:none;border-radius:6px;padding:5px 12px;font-size:.78em;font-weight:600;cursor:pointer;">⬇ Download PDF</button>' +
            '</div>' +
            '</div>';

        // Scorecard
        html += renderScorecard(counts);

        // Severity filter chips
        var SEV_KEYS = ['critical', 'high', 'medium', 'low', 'info'];
        html += '<div id="csdt-sev-filters" style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px;">';
        html += '<button class="csdt-sev-filter-btn csdt-sev-active" data-sev="all" style="font-size:.78em;padding:3px 11px;border-radius:20px;border:1px solid #6366f1;background:#6366f1;color:#fff;cursor:pointer;font-weight:600;">All</button>';
        SEV_KEYS.forEach(function (sev) {
            var cnt = findings.filter(function (f) { return (f.severity || 'info').toLowerCase() === sev; }).length;
            if (cnt === 0) return;
            var col = SEV_COLOR[sev];
            html += '<button class="csdt-sev-filter-btn" data-sev="' + sev + '" style="font-size:.78em;padding:3px 11px;border-radius:20px;border:1px solid ' + col.border + ';background:#fff;color:' + col.badge + ';cursor:pointer;font-weight:600;">' +
                sev.charAt(0).toUpperCase() + sev.slice(1) +
                ' <span style="display:inline-block;background:' + col.badge + ';color:#fff;border-radius:10px;padding:0 5px;font-size:.82em;">' + cnt + '</span></button>';
        });
        html += '</div>';

        // Category filter chips
        var categories = [];
        findings.forEach(function (f) {
            if (f.category && categories.indexOf(f.category) === -1) categories.push(f.category);
        });

        if (categories.length > 1) {
            html += '<div id="csdt-audit-filters" style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px;">' +
                '<button class="csdt-audit-filter-btn csdt-filter-active" data-filter="all" style="font-size:.78em;padding:3px 11px;border-radius:20px;border:1px solid #6366f1;background:#6366f1;color:#fff;cursor:pointer;font-weight:600;">All</button>';
            categories.forEach(function (cat) {
                var icon = CAT_ICON[cat] || '';
                html += '<button class="csdt-audit-filter-btn" data-filter="' + escHtml(cat) +
                    '" style="font-size:.78em;padding:3px 11px;border-radius:20px;border:1px solid #e5e7eb;background:#fff;color:#374151;cursor:pointer;">' +
                    icon + ' ' + escHtml(cat) + '</button>';
            });
            html += '</div>';
        }

        // Finding cards, wrapped in a single collapsible section
        var total = findings.length;
        html += '<details id="csdt-audit-cards-details">' +
            '<summary style="cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px;' +
            'padding:8px 14px;margin-bottom:12px;border-radius:6px;background:#f1f5f9;border:1px solid #e2e8f0;' +
            'font-size:.85em;font-weight:600;color:#374151;user-select:none;" id="csdt-audit-cards-toggle">' +
            '<span id="csdt-audit-cards-arrow" style="font-size:.8em;transition:transform .15s;transform:rotate(-90deg);">▼</span>' +
            '<span id="csdt-audit-cards-label">Show ' + total + ' findings</span>' +
            '</summary>' +
            '<div id="csdt-audit-cards">';
        findings.forEach(function (f) { html += renderFindingCard(f); });
        html += '</div></details>';

        resultsDiv.innerHTML = html;
        resultsDiv.style.display = '';
        var emptyDiv = document.getElementById('csdt-site-audit-empty');
        if (emptyDiv) { emptyDiv.style.display = 'none'; }

        // Wire the single show/hide toggle for all findings
        var detWrap = document.getElementById('csdt-audit-cards-details');
        if (detWrap) {
            var togArrow = document.getElementById('csdt-audit-cards-arrow');
            var togLabel = document.getElementById('csdt-audit-cards-label');
            detWrap.addEventListener('toggle', function () {
                var open = detWrap.open;
                if (togArrow) togArrow.style.transform = open ? '' : 'rotate(-90deg)';
                if (togLabel) togLabel.textContent = (open ? 'Hide ' : 'Show ') + findings.length + ' findings';
            });
        }

        // Combined severity + category filter logic
        var filterState = { sev: 'all', cat: 'all' };
        var cards = resultsDiv.querySelectorAll('#csdt-audit-cards > div');

        function applyFilters() {
            cards.forEach(function (card, i) {
                var f = findings[i];
                var matchSev = filterState.sev === 'all' || (f && (f.severity || 'info').toLowerCase() === filterState.sev);
                var matchCat = filterState.cat === 'all' || (f && f.category === filterState.cat);
                card.style.display = (matchSev && matchCat) ? '' : 'none';
            });
        }

        // Severity chips
        var sevBtns = resultsDiv.querySelectorAll('.csdt-sev-filter-btn');
        sevBtns.forEach(function (btn) {
            btn.addEventListener('click', function () {
                filterState.sev = btn.getAttribute('data-sev');
                sevBtns.forEach(function (b) {
                    var sev = b.getAttribute('data-sev');
                    if (sev === 'all') {
                        b.style.background  = filterState.sev === 'all' ? '#6366f1' : '#fff';
                        b.style.color       = filterState.sev === 'all' ? '#fff'    : '#374151';
                        b.style.borderColor = filterState.sev === 'all' ? '#6366f1' : '#e5e7eb';
                    } else {
                        var col = SEV_COLOR[sev];
                        b.style.background  = filterState.sev === sev ? col.badge : '#fff';
                        b.style.color       = filterState.sev === sev ? '#fff'    : col.badge;
                        b.style.borderColor = col.border;
                    }
                });
                applyFilters();
            });
        });

        // Category chips
        var filterBtns = resultsDiv.querySelectorAll('.csdt-audit-filter-btn');
        filterBtns.forEach(function (btn) {
            btn.addEventListener('click', function () {
                filterState.cat = btn.getAttribute('data-filter');
                filterBtns.forEach(function (b) {
                    b.style.background  = '#fff';
                    b.style.color       = '#374151';
                    b.style.borderColor = '#e5e7eb';
                    b.classList.remove('csdt-filter-active');
                });
                btn.style.background  = '#6366f1';
                btn.style.color       = '#fff';
                btn.style.borderColor = '#6366f1';
                btn.classList.add('csdt-filter-active');
                applyFilters();
            });
        });

        // Wire modal Fix It buttons
        resultsDiv.addEventListener('click', function (e) {
            var mBtn = e.target.closest('.csdt-modal-fix-btn');
            if (mBtn) {
                var modal = document.getElementById(mBtn.getAttribute('data-modal'));
                if (modal) modal.style.display = 'flex';
            }
        });

        // Wire Fix It buttons
        resultsDiv.addEventListener('click', function (e) {
            var btn = e.target.closest('.csdt-fix-it-btn');
            if (!btn) return;
            var fixId  = btn.getAttribute('data-fix-id');
            var status = btn.parentNode.querySelector('.csdt-fix-it-status');
            btn.disabled = true;
            btn.textContent = '⏳ Fixing…';
            if (status) { status.style.display = 'none'; }
            secPost('csdt_devtools_quick_fix', { fix_action: 'apply', fix_id: fixId })
                .then(function (res) {
                    if (res && res.success) {
                        btn.textContent = '✓ Fixed';
                        btn.style.cssText = 'background:#16a34a;color:#fff;border:none;font-size:.8em;font-weight:700;padding:6px 14px;border-radius:6px;cursor:default;';
                        btn.disabled = true;
                        if (status) { status.style.display = 'inline'; status.style.color = '#374151'; status.style.fontWeight = 'normal'; status.textContent = res.data && res.data.message ? res.data.message : ''; }
                    } else {
                        btn.disabled = false;
                        btn.textContent = '⚡ Fix It';
                        if (status) { status.style.display = 'inline'; status.style.color = '#dc2626'; status.textContent = (res && res.data) || 'Error'; }
                    }
                })
                .catch(function () {
                    btn.disabled = false;
                    btn.textContent = '⚡ Fix It';
                    if (status) { status.style.display = 'inline'; status.style.color = '#dc2626'; status.textContent = 'Request failed'; }
                });
        });

        // Wire Dismiss/Acknowledge buttons
        resultsDiv.addEventListener('click', function (e) {
            var btn = e.target.closest('.csdt-dismiss-btn');
            if (!btn) return;
            var dismissId = btn.getAttribute('data-dismiss-id');
            var card = btn.closest('[style]');
            btn.disabled = true;
            btn.textContent = '⏳';
            secPost('csdt_devtools_quick_fix', { fix_action: 'dismiss', fix_id: dismissId })
                .then(function (res) {
                    if (res && res.success) {
                        btn.textContent = '✓ Acknowledged';
                        btn.style.cssText = 'background:#f1f5f9;color:#64748b;border:1px solid #e2e8f0;font-size:.8em;font-weight:600;padding:5px 12px;border-radius:6px;cursor:default;margin-left:6px;';
                        if (card) { card.style.opacity = '0.5'; }
                    } else {
                        btn.disabled = false;
                        btn.textContent = btn.getAttribute('data-original-label') || 'Acknowledge';
                    }
                })
                .catch(function () { btn.disabled = false; });
        });

        // Wire PDF button
        var pdfBtn = document.getElementById('csdt-audit-pdf-btn');
        if (pdfBtn) {
            pdfBtn.addEventListener('click', function () { exportAuditPDF(findings, postCount, aiUsed); });
        }
    }

    function exportAuditPDF(findings, postCount, aiUsed) {
        var now  = new Date().toLocaleString();
        var site = window.location.hostname;
        var SEV_LABEL = { critical: 'Critical', high: 'High', medium: 'Medium', low: 'Low', info: 'Info' };
        var SEV_BG    = { critical: '#dc2626', high: '#ea580c', medium: '#ca8a04', low: '#16a34a', info: '#0284c7' };

        function esc(s) { return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }

        var cardsHtml = '';
        ['critical','high','medium','low','info'].forEach(function (sev) {
            var group = findings.filter(function (f) { return (f.severity || 'info').toLowerCase() === sev; });
            if (!group.length) return;
            cardsHtml += '<div style="margin:0 0 18px">' +
                '<div style="background:' + SEV_BG[sev] + ';color:#fff;font-weight:700;font-size:11px;padding:5px 10px;border-radius:4px 4px 0 0;letter-spacing:.05em;">' +
                SEV_LABEL[sev].toUpperCase() + ' (' + group.length + ')</div>';
            group.forEach(function (f) {
                cardsHtml += '<div style="border:1px solid #e5e7eb;border-top:none;padding:10px 12px;">' +
                    '<div style="font-weight:600;font-size:13px;color:#111;margin-bottom:3px;">' + esc(f.title) + '</div>' +
                    ( f.affected ? '<div style="font-size:11px;color:#6b7280;margin-bottom:3px;">→ ' + esc(f.affected) + '</div>' : '' ) +
                    '<div style="font-size:12px;color:#374151;margin-bottom:3px;">' + linkifyDetail(f.detail) + '</div>' +
                    '<div style="font-size:11px;color:#4b5563;font-style:italic;">Fix: ' + esc(f.fix) + '</div>' +
                    '</div>';
            });
            cardsHtml += '</div>';
        });

        var html = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Site Audit Report, ' + esc(site) + '</title>' +
            '<style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#111;margin:0;padding:32px 40px;max-width:900px;}' +
            'h1{font-size:22px;font-weight:800;color:#0f172a;margin:0 0 4px;}' +
            '.meta{font-size:12px;color:#6b7280;margin-bottom:24px;}' +
            '@media print{body{padding:0;}@page{margin:20mm 18mm;}.no-print{display:none;}}</style></head><body>' +
            '<h1>Site Audit Report</h1>' +
            '<div class="meta">' + esc(site) + ' &nbsp;·&nbsp; ' + esc(now) +
            ' &nbsp;·&nbsp; ' + postCount + ' posts/pages' +
            ' &nbsp;·&nbsp; ' + ( aiUsed ? '🤖 AI analysis' : 'Rule-based' ) + '</div>' +
            cardsHtml + '</body></html>';

        var win = window.open('', '_blank');
        if (!win) { alert('Please allow pop-ups for this page to export the PDF.'); return; }
        win.document.write(html);
        win.document.close();
        win.focus();
        setTimeout(function () { win.print(); }, 400);
    }

    if (auditBtn) {
        auditBtn.addEventListener('click', function () {
            auditBtn.disabled    = true;
            auditBtn.textContent = '⏳ Running…';
            if (progressWrap) progressWrap.style.display = '';
            if (progressText) progressText.textContent  = 'Gathering site data…';
            resultsDiv.style.display = 'none';

            var progressSteps = [
                [1200, 'Analysing content and SEO…'],
                [2400, 'Checking database health…'],
                [4000, 'Running AI analysis…'],
            ];
            progressSteps.forEach(function (step) {
                setTimeout(function () {
                    if (progressText && progressWrap.style.display !== 'none') {
                        progressText.textContent = step[1];
                    }
                }, step[0]);
            });

            post('csdt_site_audit').then(function (res) {
                auditBtn.disabled    = false;
                auditBtn.textContent = '🔄 Re-run Audit';
                if (progressWrap) progressWrap.style.display = 'none';

                if (!res.success) {
                    resultsDiv.innerHTML = '<p style="color:#dc2626;font-size:.9em;">Audit failed, please reload and try again.</p>';
                    resultsDiv.style.display = '';
                    return;
                }
                renderResults(res.data, Math.floor(Date.now() / 1000));
            }).catch(function () {
                auditBtn.disabled    = false;
                auditBtn.textContent = '🔄 Re-run Audit';
                if (progressWrap) progressWrap.style.display = 'none';
                resultsDiv.innerHTML = '<p style="color:#dc2626;font-size:.9em;">Request failed, please reload and try again.</p>';
                resultsDiv.style.display = '';
            });
        });
    }

    // Load cached results on page open
    if (csdtSiteAudit.cached && csdtSiteAudit.cachedAt) {
        renderResults(csdtSiteAudit.cached, csdtSiteAudit.cachedAt);
        if (auditBtn) { auditBtn.textContent = '🔄 Re-run Audit'; }
    }
}());
