// SeoHealthPanel — real-time SEO analysis of the current blog form state
// Warnings only. Never blocks publishing.

const SEO_HEALTH_LANGS = [
  { id: 'en',     label: 'EN',  name: 'English'  },
  { id: 'fr',     label: 'FR',  name: 'Français' },
  { id: 'darija', label: 'DAR', name: 'Darija'   },
  { id: 'ar',     label: 'AR',  name: 'العربية'  },
];

// ─── Content parser ───────────────────────────────────────────────────────────

function parseContent(html) {
  if (!html || !html.trim()) {
    return { words: 0, h2: 0, h3: 0, images: 0, imagesWithAlt: 0, internalLinks: 0, externalLinks: 0 };
  }
  try {
    const doc  = new DOMParser().parseFromString(html, 'text/html');
    const text = (doc.body.textContent || '').trim();
    const words = text ? text.split(/\s+/).filter(Boolean).length : 0;
    const imgs  = [...doc.querySelectorAll('img')];
    const links = [...doc.querySelectorAll('a[href]')];
    return {
      words,
      h2:            doc.querySelectorAll('h2').length,
      h3:            doc.querySelectorAll('h3').length,
      images:        imgs.length,
      imagesWithAlt: imgs.filter(i => (i.getAttribute('alt') || '').trim()).length,
      internalLinks: links.filter(a => {
        const h = a.getAttribute('href') || '';
        return h.includes('wablan.com') || h.startsWith('/');
      }).length,
      externalLinks: links.filter(a => {
        const h = a.getAttribute('href') || '';
        return h.startsWith('http') && !h.includes('wablan.com');
      }).length,
    };
  } catch {
    return { words: 0, h2: 0, h3: 0, images: 0, imagesWithAlt: 0, internalLinks: 0, externalLinks: 0 };
  }
}

// ─── Check builder ────────────────────────────────────────────────────────────

function buildChecks(form, analysis) {
  const enTitle    = (i18nOf(form.title, 'en') || '').trim();
  const metaTitle  = (i18nOf(form.meta_title, 'en') || '').trim();
  const metaDesc   = (i18nOf(form.meta_description, 'en') || '').trim();
  const { words, h2, h3, images, imagesWithAlt, internalLinks } = analysis;

  return [
    // ── Critical ──
    { group: 'SEO', id: 'cover',      label: 'Cover image',          level: form.cover_url ? 'good' : 'critical',                hint: 'Required for social sharing' },
    { group: 'SEO', id: 'category',   label: 'Category',             level: form.category ? 'good' : 'critical',                  hint: 'Required for topic relevance' },
    { group: 'SEO', id: 'meta_title', label: 'Meta title',           level: !metaTitle ? 'critical' : metaTitle.length > 70 ? 'warn' : 'good', hint: `${metaTitle.length}/70 chars` },
    { group: 'SEO', id: 'meta_desc',  label: 'Meta description',     level: !metaDesc ? 'critical' : metaDesc.length > 160 ? 'warn' : 'good', hint: `${metaDesc.length}/160 chars` },
    { group: 'SEO', id: 'slug',       label: `Slug`,                 level: !form.slug ? 'critical' : form.slug.length < 5 ? 'warn' : 'good', hint: form.slug || 'Missing' },
    { group: 'SEO', id: 'tags',       label: `Tags (${form.tags?.length || 0})`, level: (form.tags?.length || 0) >= 3 ? 'good' : (form.tags?.length || 0) > 0 ? 'warn' : 'critical', hint: 'Target 3–6 tags' },
    { group: 'SEO', id: 'cluster',    label: 'Topic cluster',        level: form.cluster ? 'good' : 'warn',                       hint: 'Builds topical authority' },
    { group: 'SEO', id: 'og_image',   label: 'OG image',             level: form.og_image ? 'good' : 'warn',                      hint: '1200×630 for social' },

    // ── Content ──
    { group: 'Content', id: 'words',   label: `Word count (${words})`,  level: words >= 700 ? 'good' : words >= 350 ? 'warn' : 'critical', hint: 'Aim for 700+ for SEO depth' },
    { group: 'Content', id: 'h2s',     label: `H2 headings (${h2})`,    level: h2 >= 2 ? 'good' : h2 >= 1 ? 'warn' : 'critical',           hint: 'Structure with 2+ H2s' },
    { group: 'Content', id: 'h3s',     label: `H3 headings (${h3})`,    level: h3 >= 1 ? 'good' : 'warn',                                   hint: 'Optional but improves skim-ability' },
    { group: 'Content', id: 'images',  label: `Images (${images})`,     level: images >= 1 ? 'good' : 'warn',                               hint: 'At least 1 image recommended' },
    { group: 'Content', id: 'alt',     label: `Alt text (${imagesWithAlt}/${images || 0})`, level: images === 0 || imagesWithAlt === images ? 'good' : 'warn', hint: 'All images need alt text' },
    { group: 'Content', id: 'intlinks',label: `Internal links (${internalLinks})`, level: internalLinks >= 2 ? 'good' : internalLinks >= 1 ? 'warn' : 'warn', hint: 'Link to 2+ related articles' },

    // ── Title ──
    { group: 'Title',   id: 'title_len', label: `EN title (${enTitle.length} chars)`, level: !enTitle ? 'critical' : enTitle.length < 10 ? 'critical' : enTitle.length > 70 ? 'warn' : 'good', hint: '10–70 characters ideal' },
  ];
}

// ─── Score calculator ─────────────────────────────────────────────────────────

function calcScore(checks) {
  if (!checks.length) return 0;
  const points = checks.reduce((sum, c) => {
    if (c.level === 'good')     return sum + 1;
    if (c.level === 'warn')     return sum + 0.5;
    return sum;
  }, 0);
  return Math.round((points / checks.length) * 100);
}

function scoreLabel(score) {
  if (score >= 85) return { label: 'Excellent', color: '#16a34a' };
  if (score >= 65) return { label: 'Good',      color: '#65a30d' };
  if (score >= 40) return { label: 'Needs work', color: '#d97706' };
  return              { label: 'Critical',   color: '#dc2626' };
}

// ─── Language status ──────────────────────────────────────────────────────────

function langStatus(form, langId) {
  const title   = (i18nOf(form.title,   langId) || '').trim();
  const content = (i18nOf(form.content, langId) || '').trim();
  if (title && content)  return 'complete';
  if (title || content)  return 'partial';
  return 'missing';
}

// ─── Level indicator ──────────────────────────────────────────────────────────

function LevelDot({ level }) {
  const colors = { good: '#16a34a', warn: '#d97706', critical: '#dc2626' };
  return (
    <span style={{
      display: 'inline-block', width: 8, height: 8, borderRadius: '50%',
      background: colors[level] || '#ccc', flexShrink: 0,
    }} />
  );
}

// ─── Component ────────────────────────────────────────────────────────────────

function SeoHealthPanel({ form }) {
  const enContent = i18nOf(form.content, 'en') || '';

  // Debounced DOMParser analysis — avoids blocking the render thread on every
  // keystroke or import. useMemo was synchronous during render; this runs after.
  const [analysis, setAnalysis] = React.useState(() => parseContent(''));
  React.useEffect(() => {
    const id = setTimeout(() => {
      window.BLOG_DEBUG && console.time('[seo] parseContent');
      setAnalysis(parseContent(enContent));
      window.BLOG_DEBUG && console.timeEnd('[seo] parseContent');
    }, 300);
    return () => clearTimeout(id);
  }, [enContent]);

  const checks    = React.useMemo(() => buildChecks(form, analysis), [form, analysis]);
  const score     = calcScore(checks);
  const { label: scoreText, color: scoreColor } = scoreLabel(score);

  const critical = checks.filter(c => c.level === 'critical').length;
  const warnings = checks.filter(c => c.level === 'warn').length;

  const groups = ['SEO', 'Content', 'Title'];

  return (
    <div className="card" style={{ padding: 'var(--space-5)' }}>
      <div className="blog-section-label" style={{ marginBottom: 'var(--space-4)' }}>SEO Health</div>

      {/* Score bar */}
      <div style={{ marginBottom: 'var(--space-4)' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
          <span style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)' }}>Score</span>
          <span style={{ fontWeight: 'var(--fw-bold)', fontSize: 22, color: scoreColor }}>{score}<span style={{ fontSize: 13, fontWeight: 400, color: 'var(--fg-secondary)' }}>/100</span></span>
        </div>
        <div style={{ height: 6, background: 'var(--bg-surface-2)', borderRadius: 99, overflow: 'hidden' }}>
          <div style={{ height: '100%', width: `${score}%`, background: scoreColor, borderRadius: 99, transition: 'width 400ms ease' }} />
        </div>
        <div style={{ fontSize: 11, fontWeight: 600, color: scoreColor, marginTop: 4 }}>{scoreText}</div>
        {(critical > 0 || warnings > 0) && (
          <div style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)', marginTop: 2 }}>
            {critical > 0 && <span style={{ color: '#dc2626', marginRight: 8 }}>✕ {critical} critical</span>}
            {warnings > 0 && <span style={{ color: '#d97706' }}>⚠ {warnings} warning{warnings !== 1 ? 's' : ''}</span>}
          </div>
        )}
      </div>

      {/* Checks by group */}
      {groups.map(group => {
        const groupChecks = checks.filter(c => c.group === group);
        return (
          <div key={group} style={{ marginBottom: 'var(--space-4)' }}>
            <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--fg-secondary)', marginBottom: 'var(--space-2)' }}>
              {group}
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
              {groupChecks.map(c => (
                <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <LevelDot level={c.level} />
                  <span style={{ flex: 1, fontSize: 'var(--fs-caption)', color: c.level === 'critical' ? '#dc2626' : 'var(--fg-primary)' }}>
                    {c.label}
                  </span>
                  {c.hint && c.level !== 'good' && (
                    <span style={{ fontSize: 10, color: 'var(--fg-secondary)', whiteSpace: 'nowrap' }}>{c.hint}</span>
                  )}
                </div>
              ))}
            </div>
          </div>
        );
      })}

      {/* Multilingual status */}
      <div style={{ marginTop: 'var(--space-2)', paddingTop: 'var(--space-4)', borderTop: '1px solid var(--border-subtle)' }}>
        <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--fg-secondary)', marginBottom: 'var(--space-2)' }}>
          Translations
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
          {SEO_HEALTH_LANGS.map(l => {
            const status = langStatus(form, l.id);
            const colors = { complete: '#16a34a', partial: '#d97706', missing: '#9ca3af' };
            const icons  = { complete: '✓', partial: '◑', missing: '○' };
            return (
              <div key={l.id} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 'var(--fs-caption)' }}>
                <span style={{ color: colors[status], fontSize: 11, fontWeight: 700 }}>{icons[status]}</span>
                <span style={{ color: status === 'missing' ? 'var(--fg-secondary)' : 'var(--fg-primary)' }}>{l.name}</span>
              </div>
            );
          })}
        </div>
      </div>

      {/* Content stats */}
      <div style={{ marginTop: 'var(--space-4)', paddingTop: 'var(--space-4)', borderTop: '1px solid var(--border-subtle)' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)' }}>
          <span>Words: <strong style={{ color: 'var(--fg-primary)' }}>{analysis.words}</strong></span>
          <span>Read: <strong style={{ color: 'var(--fg-primary)' }}>{Math.max(1, Math.round(analysis.words / 200))} min</strong></span>
          <span>H2: <strong style={{ color: 'var(--fg-primary)' }}>{analysis.h2}</strong></span>
          <span>H3: <strong style={{ color: 'var(--fg-primary)' }}>{analysis.h3}</strong></span>
          <span>Images: <strong style={{ color: 'var(--fg-primary)' }}>{analysis.images}</strong></span>
          <span>Int. links: <strong style={{ color: 'var(--fg-primary)' }}>{analysis.internalLinks}</strong></span>
        </div>
      </div>

      <p style={{ fontSize: 10, color: 'var(--fg-secondary)', marginTop: 'var(--space-3)', lineHeight: 1.5 }}>
        Warnings only. Publishing is never blocked.
      </p>
    </div>
  );
}

window.SeoHealthPanel = SeoHealthPanel;
