// InternalLinkingPanel — suggests related published articles for internal linking.
//
// REQUIREMENTS:
// - Only fetches published posts (status = 'published')
// - Excludes the current post by slug
// - Scores by: cluster (strongest) > category > tag overlap > title keyword overlap
// - Requires at least 2 other published posts to show meaningful suggestions
//
// Architecture note: designed for future AI plugin replacement.
// The scoring engine (scoreCandidates) is the only part that needs swapping.

const BLOG_URL = 'https://blog.wablan.com';
const MAX_SUGGESTIONS = 8;

// ─── Scoring engine ───────────────────────────────────────────────────────────
// Returns candidates sorted by relevance. Replace this function with an AI call.

// Normalize a cluster string: lowercase + spaces → hyphens.
// Handles "branding-maroc", "text 1 - text 2", "Branding Maroc" all the same way.
function normalizeCluster(s) {
  return (s || '').toLowerCase().trim().replace(/\s+/g, '-');
}

function scoreCandidates(candidates, form) {
  const formCategory = (form.category || '').toLowerCase();
  const formCluster  = normalizeCluster(form.cluster);
  const formTags     = Array.isArray(form.tags) ? form.tags.map(t => t.toLowerCase()) : [];
  const formTitle    = i18nOf(form.title, 'en').toLowerCase();
  const formWords    = formTitle.split(/\s+/).filter(w => w.length > 3);
  const formContent  = i18nOf(form.content, 'en').toLowerCase();
  const formContentWords = formContent.replace(/<[^>]+>/g, ' ').split(/\s+/).filter(w => w.length > 4);

  return candidates
    .map(c => {
      let score = 0;
      const cTitle    = i18nOf(c.title, 'en').toLowerCase();
      const cTags     = Array.isArray(c.tags) ? c.tags.map(t => t.toLowerCase()) : [];
      const cCategory = (c.category || '').toLowerCase();
      const cCluster  = normalizeCluster(c.cluster); // normalize for flexible matching

      // Same cluster — strongest topical signal (handles spaces, case, dashes)
      if (formCluster && cCluster && formCluster === cCluster) score += 50;
      // Same category
      if (formCategory && cCategory && formCategory === cCategory) score += 30;
      // Tag overlap
      const tagOverlap = formTags.filter(t => cTags.includes(t)).length;
      score += tagOverlap * 15;
      // Title keyword overlap
      const titleMatches = formWords.filter(w => cTitle.includes(w)).length;
      score += titleMatches * 10;
      // Content keyword overlap (capped)
      const contentMatches = formContentWords.slice(0, 50).filter(w => cTitle.includes(w)).length;
      score += Math.min(contentMatches * 5, 20);

      const anchorText = i18nOf(c.title, 'en');
      return { ...c, _score: score, anchorText };
    })
    .filter(c => c._score > 0)
    .sort((a, b) => b._score - a._score)
    .slice(0, MAX_SUGGESTIONS);
}

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

function InternalLinkingPanel({ form, onInsertLink }) {
  const [open,          setOpen]          = React.useState(false);
  const [suggestions,   setSuggestions]   = React.useState(null); // null = not fetched yet
  const [totalFetched,  setTotalFetched]  = React.useState(0);    // raw published post count
  const [loading,       setLoading]       = React.useState(false);
  const [inserted,      setInserted]      = React.useState({}); // slugs marked as inserted
  const [copiedSlug,    setCopiedSlug]    = React.useState(null);
  const currentSlug = form.slug;

  const fetch = async () => {
    setLoading(true);
    const { data, error } = await db
      .from('blog_posts')
      .select('slug, title, category, tags, cluster')
      .eq('status', 'published')        // only published posts
      .neq('slug', currentSlug || '__none__'); // exclude current post

    setLoading(false);
    if (error || !data) { setSuggestions([]); setTotalFetched(0); return; }
    setTotalFetched(data.length);
    setSuggestions(scoreCandidates(data, form));
  };

  const handleOpen = () => {
    setOpen(o => !o);
    if (!open && suggestions === null) fetch();
  };

  const handleRefresh = (e) => {
    e.stopPropagation();
    setSuggestions(null);
    fetch();
  };

  const handleInsert = (c) => {
    const url  = `${BLOG_URL}/blog/${c.slug}`;
    const text = c.anchorText || i18nOf(c.title, 'en');
    onInsertLink(url, text);
    setInserted(prev => ({ ...prev, [c.slug]: true }));
  };

  const handleCopy = (c) => {
    const url  = `${BLOG_URL}/blog/${c.slug}`;
    const text = c.anchorText || i18nOf(c.title, 'en');
    const html = `<a href="${url}" target="_blank" rel="noopener noreferrer">${text}</a>`;
    navigator.clipboard.writeText(html).catch(() => {
      const ta = document.createElement('textarea');
      ta.value = html;
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      document.body.removeChild(ta);
    });
    setCopiedSlug(c.slug);
    setTimeout(() => setCopiedSlug(null), 2000);
  };

  const count = suggestions ? suggestions.length : 0;

  return (
    <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
      {/* Header — always visible */}
      <button
        type="button"
        onClick={handleOpen}
        style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          width: '100%', padding: 'var(--space-4) var(--space-5)',
          background: 'none', border: 'none', cursor: 'pointer',
          borderBottom: open ? '1px solid var(--border-subtle)' : 'none',
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 14 }}>🔗</span>
          <span style={{ fontWeight: 'var(--fw-semibold)', fontSize: 'var(--fs-body-sm)' }}>
            Internal Linking
          </span>
          {suggestions !== null && (
            <span style={{
              background: count > 0 ? 'var(--accent, #6366f1)' : 'var(--bg-surface-2)',
              color: count > 0 ? '#fff' : 'var(--fg-secondary)',
              borderRadius: 99, padding: '1px 7px', fontSize: 11, fontWeight: 600,
            }}>
              {count}
            </span>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {open && (
            <button
              type="button"
              onClick={handleRefresh}
              style={{ fontSize: 11, color: 'var(--fg-secondary)', background: 'none', border: 'none', cursor: 'pointer', padding: '2px 6px' }}
              title="Refresh suggestions"
            >
              ↻
            </button>
          )}
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"
            style={{ transform: open ? 'rotate(180deg)' : 'rotate(0deg)', transition: '160ms', flexShrink: 0 }}>
            <polyline points="2,4 6,8 10,4"/>
          </svg>
        </div>
      </button>

      {/* Body */}
      {open && (
        <div style={{ padding: 'var(--space-4) var(--space-5)' }}>
          {loading && (
            <div style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)', textAlign: 'center', padding: 'var(--space-4) 0' }}>
              Analyzing…
            </div>
          )}

          {!loading && suggestions !== null && count === 0 && totalFetched < 2 && (
            // Not enough published posts to suggest anything
            <div style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)', textAlign: 'center', padding: 'var(--space-3) 0', lineHeight: 1.6 }}>
              Internal linking needs at least 2 published articles.<br/>
              <span style={{ fontSize: 11 }}>Publish more related articles first.</span>
            </div>
          )}

          {!loading && suggestions !== null && count === 0 && totalFetched >= 2 && (
            // Posts exist but no category/tag/cluster match
            <div style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)', textAlign: 'center', padding: 'var(--space-3) 0', lineHeight: 1.6 }}>
              No strong matches found.<br/>
              <span style={{ fontSize: 11 }}>Try matching category, tags, or cluster with other published articles.</span>
            </div>
          )}

          {!loading && count > 0 && (
            <>
              <p style={{ fontSize: 'var(--fs-caption)', color: 'var(--fg-secondary)', marginBottom: 'var(--space-3)' }}>
                {count} opportunit{count !== 1 ? 'ies' : 'y'} — click Insert to add at cursor, or Copy to paste manually.
              </p>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-2)' }}>
                {suggestions.map(c => (
                  <div key={c.slug} style={{
                    padding: 'var(--space-3)',
                    background: inserted[c.slug] ? 'rgba(22,163,74,0.06)' : 'var(--bg-surface-2)',
                    borderRadius: 8,
                    border: '1px solid var(--border-subtle)',
                  }}>
                    <div style={{ fontSize: 'var(--fs-body-sm)', fontWeight: 'var(--fw-medium)', marginBottom: 3, lineHeight: 1.3 }}>
                      {i18nOf(c.title, 'en')}
                      {inserted[c.slug] && <span style={{ marginLeft: 6, color: '#16a34a', fontSize: 11 }}>✓ inserted</span>}
                    </div>
                    <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginBottom: 'var(--space-2)', flexWrap: 'wrap' }}>
                      {c.category && (
                        <span style={{ fontSize: 10, background: 'var(--bg-surface)', border: '1px solid var(--border-subtle)', borderRadius: 4, padding: '1px 6px', color: 'var(--fg-secondary)' }}>
                          {c.category}
                        </span>
                      )}
                      {c.cluster && (
                        <span style={{ fontSize: 10, background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 4, padding: '1px 6px', color: '#6366f1' }}>
                          {c.cluster}
                        </span>
                      )}
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--fg-secondary)', marginBottom: 'var(--space-2)', fontStyle: 'italic', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      Anchor: "{c.anchorText}"
                    </div>
                    <div style={{ display: 'flex', gap: 6 }}>
                      <button
                        type="button"
                        className="btn btn--primary"
                        style={{ fontSize: 11, padding: '3px 10px' }}
                        onClick={() => handleInsert(c)}
                        title="Insert link at current cursor position in the editor"
                      >
                        Insert
                      </button>
                      <button
                        type="button"
                        className="btn btn--ghost"
                        style={{ fontSize: 11, padding: '3px 10px' }}
                        onClick={() => handleCopy(c)}
                      >
                        {copiedSlug === c.slug ? '✓ Copied' : 'Copy HTML'}
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            </>
          )}

          {suggestions === null && !loading && (
            <button className="btn btn--ghost" style={{ width: '100%', fontSize: 'var(--fs-caption)' }} onClick={fetch}>
              Analyze now
            </button>
          )}
        </div>
      )}
    </div>
  );
}

window.InternalLinkingPanel = InternalLinkingPanel;
