<?php
/**
 * include/seo_analysis.php
 * Drop inside pages_edit.php form — after the SEO fields include.
 * All analysis runs client-side in real-time via JS + TinyMCE content.
 * Requires: $input array (page data), tinymce already initialized.
 */
?>

<!-- ════════════════════════════════════════════════
     SEO ANALYSIS PANEL
════════════════════════════════════════════════ -->
<div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden" id="seoAnalysisCard">

    <!-- Header -->
    <div class="px-5 py-4 border-b border-gray-100 flex items-center justify-between">
        <div class="flex items-center gap-2">
            <i class="fas fa-microscope text-purple-600"></i>
            <h2 class="font-semibold text-gray-700">SEO Content Analysis</h2>
        </div>
        <div class="flex items-center gap-2">
            <button type="button" onclick="runSeoAnalysis()"
                class="text-xs bg-purple-600 hover:bg-purple-700 text-white px-3 py-1.5 rounded-lg font-medium flex items-center gap-1.5 transition">
                <i class="fas fa-sync-alt" id="analyzeIcon"></i> Analyse Now
            </button>
        </div>
    </div>

    <!-- Focus Keyword Input -->
    <div class="px-5 pt-4 pb-3 border-b border-gray-100 bg-gray-50">
        <label class="block text-xs font-semibold text-gray-600 uppercase tracking-wide mb-1.5">
            <i class="fas fa-key text-purple-500 mr-1"></i>Focus Keyword
            <span class="text-gray-400 font-normal normal-case ml-1">— the main keyword you want this page to rank for</span>
        </label>
        <input type="text" id="focusKeyword"
            value="<?= htmlspecialchars(explode(',', $input['meta_keywords'] ?? '')[0] ?? '') ?>"
            class="form-input max-w-sm"
            placeholder="e.g. social science research journal"
            oninput="scheduleAnalysis()">
        <p class="text-xs text-gray-400 mt-1">Auto-filled from first meta keyword. Edit to override.</p>
    </div>

    <!-- Overall Score -->
    <div class="px-5 py-4 flex items-center gap-4 border-b border-gray-100">
        <!-- Donut -->
        <div class="relative flex-shrink-0">
            <svg width="72" height="72" viewBox="0 0 72 72">
                <circle cx="36" cy="36" r="28" fill="none" stroke="#e5e7eb" stroke-width="8"/>
                <circle id="scoreDonut" cx="36" cy="36" r="28" fill="none"
                    stroke="#8b5cf6" stroke-width="8"
                    stroke-dasharray="176" stroke-dashoffset="176"
                    stroke-linecap="round"
                    transform="rotate(-90 36 36)"
                    style="transition:stroke-dashoffset .6s ease,stroke .3s;"/>
            </svg>
            <div class="absolute inset-0 flex items-center justify-center flex-col">
                <span class="text-lg font-bold text-gray-800 leading-none" id="overallScore">—</span>
                <span class="text-[9px] text-gray-400">/ 100</span>
            </div>
        </div>
        <div class="flex-1">
            <div class="text-sm font-semibold text-gray-700 mb-1" id="scoreLabel">Run analysis to see results</div>
            <div class="h-2 bg-gray-100 rounded-full overflow-hidden">
                <div id="scoreBar" class="h-full rounded-full transition-all duration-500" style="width:0%;background:#8b5cf6;"></div>
            </div>
            <div class="flex gap-3 mt-2 text-xs">
                <span class="text-green-600 font-medium"><span id="passCount">0</span> passed</span>
                <span class="text-yellow-600 font-medium"><span id="improveCount">0</span> to improve</span>
                <span class="text-red-500 font-medium"><span id="failCount">0</span> failed</span>
            </div>
        </div>
    </div>

    <!-- Results list -->
    <div id="seoResults" class="divide-y divide-gray-50">
        <div class="px-5 py-8 text-center text-gray-400 text-sm">
            <i class="fas fa-search text-2xl mb-2 block text-gray-300"></i>
            Enter a focus keyword above and click <strong>Analyse Now</strong>
        </div>
    </div>

</div>

<style>
/* Result row */
.seo-row { padding:.875rem 1.25rem; display:flex; align-items:flex-start; gap:.875rem; }
.seo-icon { width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:.7rem; flex-shrink:0; margin-top:1px; }
.seo-icon.pass    { background:#d1fae5; color:#059669; }
.seo-icon.improve { background:#fef3c7; color:#d97706; }
.seo-icon.fail    { background:#fee2e2; color:#dc2626; }
.seo-title { font-size:.8rem; font-weight:600; color:#374151; line-height:1.3; }
.seo-detail { font-size:.75rem; color:#6b7280; margin-top:.2rem; line-height:1.5; }
.seo-detail strong { color:#374151; }
.seo-detail .found  { color:#059669; font-weight:600; }
.seo-detail .warn   { color:#d97706; font-weight:600; }
.seo-detail .bad    { color:#dc2626; font-weight:600; }
.seo-badge { font-size:.65rem; font-weight:700; padding:.15rem .5rem; border-radius:9999px; flex-shrink:0; }
.badge-pass    { background:#d1fae5; color:#065f46; }
.badge-improve { background:#fef3c7; color:#92400e; }
.badge-fail    { background:#fee2e2; color:#991b1b; }
.form-input { width:100%; border:1px solid #d1d5db; border-radius:.5rem; padding:.6rem .875rem; font-size:.875rem; color:#374151; outline:none; transition:border-color .15s,box-shadow .15s; }
.form-input:focus { border-color:#3b82f6; box-shadow:0 0 0 3px rgba(59,130,246,.12); }
</style>

<script>
(function(){

var _timer = null;
function scheduleAnalysis() {
    clearTimeout(_timer);
    _timer = setTimeout(runSeoAnalysis, 800);
}

window.runSeoAnalysis = function() {
    // Get raw content from TinyMCE or textarea
    var rawHtml = '';
    if (typeof tinymce !== 'undefined' && tinymce.get('descriptionEditor')) {
        rawHtml = tinymce.get('descriptionEditor').getContent();
    } else {
        rawHtml = document.getElementById('descriptionEditor')?.value || '';
    }

    var keyword    = (document.getElementById('focusKeyword')?.value || '').trim().toLowerCase();
    var title      = (document.getElementById('titleInput')?.value   || '').trim();
    var slug       = (document.getElementById('slugInput')?.value    || '').trim();
    var metaTitle  = (document.getElementById('metaTitleInput')?.value  || title).trim();
    var metaDesc   = (document.getElementById('metaDescInput')?.value   || '').trim();
    var overview   = (document.querySelector('textarea[name="overview"]')?.value || '').trim();

    // Strip HTML for text analysis
    var tmp = document.createElement('div');
    tmp.innerHTML = rawHtml;

    // Plain text (no HTML tags)
    var plainText = (tmp.innerText || tmp.textContent || '').trim();

    // Word count
    var words = plainText.split(/\s+/).filter(function(w){ return w.length > 0; });
    var wordCount = words.length;

    // First paragraph
    var firstPTag = tmp.querySelector('p');
    var firstPara = firstPTag ? (firstPTag.innerText || firstPTag.textContent || '') : plainText.substring(0, 300);

    // Headings
    var h1s = tmp.querySelectorAll('h1');
    var h2s = tmp.querySelectorAll('h2');
    var h3s = tmp.querySelectorAll('h3');
    var allHeadings = tmp.querySelectorAll('h1,h2,h3,h4,h5,h6');

    // Images
    var imgs = tmp.querySelectorAll('img');

    // Links
    var siteHost = window.location.hostname;
    var allLinks = tmp.querySelectorAll('a[href]');
    var internalLinks = 0, externalLinks = 0;
    allLinks.forEach(function(a) {
        var href = a.getAttribute('href') || '';
        if (href.startsWith('/') || href.startsWith('#') || href.includes(siteHost) || (!href.startsWith('http'))) {
            internalLinks++;
        } else if (href.startsWith('http')) {
            externalLinks++;
        }
    });

    // Keyword occurrences in plain text
    var kwCount = 0, kwDensity = 0;
    if (keyword && wordCount > 0) {
        var re = new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'), 'gi');
        var matches = plainText.match(re);
        kwCount   = matches ? matches.length : 0;
        kwDensity = wordCount > 0 ? ((kwCount / wordCount) * 100) : 0;
    }

    // Keyword in headings
    var kwInHeadings = 0;
    allHeadings.forEach(function(h){
        if (keyword && (h.innerText||h.textContent||'').toLowerCase().includes(keyword)) kwInHeadings++;
    });

    // Image with kw in alt
    var imgWithAlt = 0, imgWithKwAlt = 0;
    imgs.forEach(function(img){
        var alt = (img.getAttribute('alt') || '').toLowerCase();
        if (alt) imgWithAlt++;
        if (keyword && alt.includes(keyword)) imgWithKwAlt++;
    });

    // Rotate analyse icon
    var icon = document.getElementById('analyzeIcon');
    icon.style.transform = 'rotate(360deg)';
    icon.style.transition = 'transform .5s';
    setTimeout(function(){ icon.style.transform = ''; icon.style.transition = ''; }, 500);

    // ── Build checks ──────────────────────────────────────────────────────
    var checks = [];

    // 1. Focus Keyword in Title
    if (!keyword) {
        checks.push({ status:'improve', title:'Focus Keyword', detail:'<span class="warn">No focus keyword set.</span> Enter one above to run keyword checks.' });
    } else {
        var inTitle = title.toLowerCase().includes(keyword);
        checks.push({
            status: inTitle ? 'pass' : 'fail',
            title: 'Keyword in Page Title',
            detail: inTitle
                ? 'Keyword <span class="found">"'+escHtml(keyword)+'"</span> found in title.'
                : 'Keyword <span class="bad">"'+escHtml(keyword)+'"</span> not found in title: <strong>'+escHtml(title)+'</strong>'
        });
    }

    // 2. Keyword in First Paragraph
    if (keyword) {
        var inFirst = firstPara.toLowerCase().includes(keyword);
        checks.push({
            status: inFirst ? 'pass' : 'fail',
            title: 'Keyword in First Paragraph',
            detail: inFirst
                ? 'Good — keyword appears early in the content.'
                : '<span class="bad">Keyword not found</span> in the first paragraph. Add it naturally near the start.'
        });
    }

    // 3. Keyword in Meta Description
    if (keyword) {
        var inMeta = metaDesc.toLowerCase().includes(keyword);
        checks.push({
            status: inMeta ? 'pass' : 'fail',
            title: 'Keyword in Meta Description',
            detail: inMeta
                ? 'Meta description contains the keyword.'
                : '<span class="bad">Missing keyword</span> in meta description.'
        });
    }

    // 4. Keyword in URL / Slug
    if (keyword) {
        var kwSlug  = keyword.replace(/\s+/g,'-').replace(/[^a-z0-9-]/g,'');
        var inSlug  = slug.toLowerCase().includes(kwSlug) || slug.toLowerCase().includes(keyword.replace(/\s+/g,'-'));
        checks.push({
            status: inSlug ? 'pass' : 'improve',
            title: 'Keyword in URL / Slug',
            detail: inSlug
                ? 'Slug <span class="found">'+escHtml(slug)+'</span> contains the keyword.'
                : 'Slug <span class="warn">'+escHtml(slug)+'</span> doesn\'t include keyword. Consider: <strong>'+kwSlug+'</strong>'
        });
    }

    // 5. Keyword in Headings (H1/H2/H3)
    if (keyword) {
        checks.push({
            status: kwInHeadings >= 1 ? 'pass' : kwInHeadings === 0 ? 'improve' : 'pass',
            title: 'Keyword in Headings (H1/H2/H3)',
            detail: kwInHeadings > 0
                ? 'Found in <span class="found">'+kwInHeadings+' heading(s)</span>. Good!'
                : '<span class="warn">Not found in any heading.</span> Use keyword naturally in at least 1–2 headings.'
        });
    }

    // 6. Keyword Density
    if (keyword) {
        var kd = kwDensity.toFixed(2);
        var kdStatus = (kwDensity >= 1 && kwDensity <= 2.5) ? 'pass' : (kwDensity < 1 ? 'improve' : 'improve');
        if (kwDensity > 3.5) kdStatus = 'fail';
        checks.push({
            status: kdStatus,
            title: 'Keyword Density (~1–2%)',
            detail: 'Keyword used <strong>'+kwCount+' times</strong> in '+wordCount+' words → <strong>'+kd+'%</strong> density. '
                + (kwDensity > 3.5 ? '<span class="bad">Too high — may look like keyword stuffing.</span>'
                : kwDensity < 1    ? '<span class="warn">Too low — use keyword more naturally.</span>'
                : '<span class="found">Good density range.</span>')
        });
    }

    // 7. Content Length
    var wStatus = wordCount >= 800 && wordCount <= 1500 ? 'pass' : (wordCount >= 500 ? 'improve' : 'fail');
    checks.push({
        status: wStatus,
        title: 'Content Length (800–1200 words)',
        detail: '<strong>'+wordCount+' words</strong> '
            + (wordCount >= 800 && wordCount <= 1500 ? '<span class="found">— ideal range.</span>'
             : wordCount >= 500                     ? '<span class="warn">— a bit short. Aim for 800–1200 words.</span>'
             : '<span class="bad">— too short. Add more quality content.</span>')
    });

    // 8. Headings Structure
    var hasH2 = h2s.length > 0;
    var hasH3 = h3s.length > 0;
    var headingStatus = (hasH2 && h2s.length >= 2) ? 'pass' : (hasH2 ? 'improve' : 'fail');
    checks.push({
        status: headingStatus,
        title: 'Heading Structure (H2, H3)',
        detail: 'H1: <strong>'+h1s.length+'</strong> | H2: <strong>'+h2s.length+'</strong> | H3: <strong>'+h3s.length+'</strong>. '
            + (!hasH2 ? '<span class="bad">No H2 headings found.</span> Break content into sections.'
            : h2s.length < 2 ? '<span class="warn">Only '+h2s.length+' H2 — add more to structure content.</span>'
            : '<span class="found">Good heading structure.</span>')
    });

    // 9. Internal Links (1–2)
    var ilStatus = internalLinks >= 1 ? 'pass' : 'fail';
    checks.push({
        status: ilStatus,
        title: 'Internal Links (1–2 recommended)',
        detail: '<strong>'+internalLinks+' internal link(s)</strong> found. '
            + (internalLinks === 0 ? '<span class="bad">Add 1–2 links to related pages on your site.</span>'
            : internalLinks > 5    ? '<span class="warn">'+internalLinks+' internal links — keep it natural, avoid over-linking.</span>'
            : '<span class="found">Good internal linking.</span>')
    });

    // 10. External Links (1)
    var elStatus = externalLinks >= 1 ? 'pass' : 'improve';
    checks.push({
        status: elStatus,
        title: 'External Links (1 authority link)',
        detail: '<strong>'+externalLinks+' external link(s)</strong> found. '
            + (externalLinks === 0 ? '<span class="warn">Add 1 link to a trusted external source (government site, research paper, authority).</span>'
            : '<span class="found">Good — external links add credibility.</span>')
    });

    // 11. Images
    var imgStatus = imgs.length >= 1 ? 'pass' : 'fail';
    checks.push({
        status: imgStatus,
        title: 'Images (at least 1)',
        detail: '<strong>'+imgs.length+' image(s)</strong> found. '
            + (imgs.length === 0 ? '<span class="bad">Add at least 1 image for better engagement and SEO.</span>'
            : imgWithAlt < imgs.length ? '<span class="warn">'+imgWithAlt+'/'+imgs.length+' images have alt text.</span> All images need descriptive alt text.'
            : keyword && imgWithKwAlt === 0 ? '<span class="warn">Images have alt text but none include the focus keyword.</span>'
            : '<span class="found">'+imgs.length+' image(s) with alt text.</span>')
    });

    // 12. Image Alt Text with Keyword
    if (keyword && imgs.length > 0) {
        checks.push({
            status: imgWithKwAlt > 0 ? 'pass' : 'improve',
            title: 'Keyword in Image Alt Text',
            detail: imgWithKwAlt > 0
                ? '<span class="found">'+imgWithKwAlt+' image(s)</span> have alt text containing the keyword.'
                : '<span class="warn">No image alt text contains the keyword.</span> Add keyword to at least 1 image alt attribute.'
        });
    }

    // 13. Meta Description Length
    var mdLen = metaDesc.length;
    var mdStatus = (mdLen >= 150 && mdLen <= 165) ? 'pass' : (mdLen > 0 && mdLen < 150 ? 'improve' : mdLen > 165 ? 'improve' : 'fail');
    checks.push({
        status: mdStatus,
        title: 'Meta Description (150–160 chars)',
        detail: metaDesc
            ? '<strong>'+mdLen+' characters</strong>. '
              + (mdLen >= 150 && mdLen <= 165 ? '<span class="found">Perfect length.</span>'
              : mdLen < 150 ? '<span class="warn">Too short ('+mdLen+'). Expand to 150–160 chars.</span>'
              : '<span class="warn">Too long ('+mdLen+'). Trim to 160 chars max — Google will cut it off.</span>')
            : '<span class="bad">No meta description set.</span> Add one in the SEO panel above.'
    });

    // 14. SEO Title (with keyword)
    if (keyword) {
        var inSeoTitle = metaTitle.toLowerCase().includes(keyword);
        checks.push({
            status: inSeoTitle ? 'pass' : 'fail',
            title: 'SEO Title Contains Keyword',
            detail: inSeoTitle
                ? 'SEO title contains the keyword: <span class="found">'+escHtml(metaTitle)+'</span>'
                : '<span class="bad">Keyword missing</span> from SEO title. Add it naturally — ideally near the start.'
        });
    }

    // ── Calculate score ──────────────────────────────────────────────────
    var passed   = checks.filter(function(c){ return c.status==='pass';    }).length;
    var improved = checks.filter(function(c){ return c.status==='improve'; }).length;
    var failed   = checks.filter(function(c){ return c.status==='fail';    }).length;
    var total    = checks.length;
    var score    = total > 0 ? Math.round(((passed + improved * 0.5) / total) * 100) : 0;

    // Update donut
    var circumference = 176;
    var offset = circumference - (score / 100) * circumference;
    var donut = document.getElementById('scoreDonut');
    donut.style.strokeDashoffset = offset;
    donut.style.stroke = score >= 70 ? '#10b981' : score >= 40 ? '#f59e0b' : '#ef4444';

    document.getElementById('overallScore').textContent = score;
    document.getElementById('scoreBar').style.width     = score + '%';
    document.getElementById('scoreBar').style.background= score >= 70 ? '#10b981' : score >= 40 ? '#f59e0b' : '#ef4444';
    document.getElementById('passCount').textContent    = passed;
    document.getElementById('improveCount').textContent = improved;
    document.getElementById('failCount').textContent    = failed;

    var labels = { pass:'Good', improve:'Needs work', fail:'Poor' };
    document.getElementById('scoreLabel').textContent =
        score >= 70 ? '✅ Good SEO — keep it up!'
        : score >= 40 ? '⚠️ Moderate — several improvements needed'
        : '❌ Needs significant SEO work';

    // ── Render results ────────────────────────────────────────────────────
    var icons = { pass:'fa-check', improve:'fa-exclamation', fail:'fa-times' };
    var labels2 = { pass:'Good', improve:'Improve', fail:'Missing' };
    var html = checks.map(function(c){
        return '<div class="seo-row">'
            + '<div class="seo-icon '+c.status+'"><i class="fas '+icons[c.status]+'"></i></div>'
            + '<div class="flex-1 min-w-0">'
            + '<div class="flex items-start gap-2">'
            + '<div class="seo-title flex-1">'+escHtml(c.title)+'</div>'
            + '<span class="seo-badge badge-'+c.status+'">'+labels2[c.status]+'</span>'
            + '</div>'
            + '<div class="seo-detail">'+c.detail+'</div>'
            + '</div>'
            + '</div>';
    }).join('');

    document.getElementById('seoResults').innerHTML = html || '<div class="p-5 text-gray-400 text-sm text-center">No results</div>';
};

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

// Auto-run when TinyMCE content changes
document.addEventListener('DOMContentLoaded', function(){
    var attempts = 0;
    var interval = setInterval(function(){
        if (typeof tinymce !== 'undefined' && tinymce.get('descriptionEditor')) {
            tinymce.get('descriptionEditor').on('input keyup', scheduleAnalysis);
            clearInterval(interval);
            // Auto-run once if keyword is pre-filled
            if (document.getElementById('focusKeyword')?.value?.trim()) {
                setTimeout(runSeoAnalysis, 1500);
            }
        }
        if (++attempts > 30) clearInterval(interval);
    }, 500);
});

})();
</script>