// SCREEN: Community Signals
// Nav ID: community
// Purpose: Show Reddit, Discord, YouTube comment signals — brand mentions, sentiment, trending topics.

// ---------------------------------------------------------------------------
// Map function for API mention objects → display shape
// ---------------------------------------------------------------------------
window.mapMention = function(m) {
  return {
    id: m.mention_id,
    source: m.source,
    content: m.content,
    url: m.url,
    sentiment: m.sentiment_label,
    score: m.sentiment_score,
    when: m.detected_at ? new Date(m.detected_at).toLocaleTimeString() : 'now',
    author: m.author,
    keyword: m.keyword,
  };
};

// ---------------------------------------------------------------------------
// MOCK data — used as fallback if API is unavailable
// ---------------------------------------------------------------------------
const COMMUNITY_MOCK = {
  kpis: {
    totalMentions: 284,
    positivePct: 61,
    negativePct: 12,
    trendingCount: 8,
  },
  sources: {
    reddit:  { count: 142, sentiment: 0.72, top: 'r/marketing',    spark: [18,22,28,19,25,30,142] },
    discord: { count:  89, sentiment: 0.68, top: '#general',       spark: [10,14,12,18,16,20,89]  },
    youtube: { count:  53, sentiment: 0.55, top: 'Top comments',   spark: [5, 8, 7, 11, 9, 13, 53] },
  },
  sentiment: { positive: 61, neutral: 27, negative: 12 },
  mentions: [
    { id: 'm1', source: 'reddit',  author: 'u/saas_geek',   content: 'AstraReach journey analytics is genuinely impressive — we cut our attribution guesswork by half in week one.', url: '#', sentiment: 'POSITIVE', score: 0.91, when: '2m ago',  keyword: 'astrareach' },
    { id: 'm2', source: 'discord', author: 'DevUser#4421',  content: 'Anyone using agentic marketing tools? The CDP replacement angle is interesting but does it work at scale?', url: '#', sentiment: 'NEUTRAL',  score: 0.52, when: '8m ago',  keyword: 'CDP replacement' },
    { id: 'm3', source: 'youtube', author: 'MarketingPro',  content: 'Great walkthrough! One question: how does the marketing attribution model handle offline events?', url: '#', sentiment: 'POSITIVE', score: 0.78, when: '15m ago', keyword: 'marketing attribution' },
    { id: 'm4', source: 'reddit',  author: 'u/growth_hkr',  content: 'Customer data platform space is too crowded. AstraReach needs a killer differentiator fast.', url: '#', sentiment: 'NEGATIVE', score: 0.22, when: '24m ago', keyword: 'customer data' },
    { id: 'm5', source: 'discord', author: 'Founder#7712',  content: 'Journey analytics with real-time memory — that is the kind of product I have been waiting for. Big fan.', url: '#', sentiment: 'POSITIVE', score: 0.88, when: '31m ago', keyword: 'journey analytics' },
    { id: 'm6', source: 'reddit',  author: 'u/ad_optimizer', content: 'Ad optimization via an AI agent is a bold claim. Has anyone validated ROAS improvement numbers independently?', url: '#', sentiment: 'NEUTRAL',  score: 0.49, when: '42m ago', keyword: 'ad optimization' },
    { id: 'm7', source: 'youtube', author: 'TechReviewer',  content: 'Honestly the best demo I have seen for agentic marketing. The decision layer is what sets it apart.', url: '#', sentiment: 'POSITIVE', score: 0.94, when: '1h ago',  keyword: 'agentic marketing' },
    { id: 'm8', source: 'discord', author: 'CMO#1133',      content: 'Does anyone know if AstraReach integrates with HubSpot natively yet?', url: '#', sentiment: 'NEUTRAL',  score: 0.50, when: '1h ago',  keyword: 'astrareach' },
    { id: 'm9', source: 'reddit',  author: 'u/martech_fan', content: 'The CDP replacement narrative is picking up steam. AstraReach might actually be onto something real here.', url: '#', sentiment: 'POSITIVE', score: 0.76, when: '2h ago',  keyword: 'CDP replacement' },
    { id: 'm10', source: 'youtube', author: 'DataDrivenCo', content: 'Marketing attribution still feels like dark magic. Curious if the Markov chain model actually helps.', url: '#', sentiment: 'NEUTRAL',  score: 0.55, when: '2h ago',  keyword: 'marketing attribution' },
  ],
  keywords: [
    { name: 'astrareach',           count: 142, trend: '↑',  sentiment: 0.82 },
    { name: 'journey analytics',    count:  38, trend: '↑',  sentiment: 0.79 },
    { name: 'marketing attribution',count:  71, trend: '→',  sentiment: 0.61 },
    { name: 'customer data',        count:  29, trend: '↓',  sentiment: 0.44 },
    { name: 'ad optimization',      count:  19, trend: '↑',  sentiment: 0.66 },
    { name: 'agentic marketing',    count:  44, trend: '↑↑', sentiment: 0.85 },
    { name: 'CDP replacement',      count:  31, trend: '↑',  sentiment: 0.57 },
    { name: 'Markov chains',        count:  12, trend: '→',  sentiment: 0.70 },
  ],
};

// ---------------------------------------------------------------------------
// Source icon component (R / D / Y badge)
// ---------------------------------------------------------------------------
const SourceIcon = ({ source, size = 18 }) => {
  const cfg = {
    reddit:  { letter: 'R', bg: '#FF4500', title: 'Reddit'  },
    discord: { letter: 'D', bg: '#5865F2', title: 'Discord' },
    youtube: { letter: 'Y', bg: '#FF0000', title: 'YouTube' },
  };
  const c = cfg[source] || { letter: '?', bg: 'var(--bg-3)', title: source };
  return (
    <span title={c.title} style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: size, height: size, borderRadius: 4,
      background: c.bg, color: '#fff',
      fontSize: size * 0.55, fontWeight: 700, flexShrink: 0,
      fontFamily: 'var(--mono)',
    }}>{c.letter}</span>
  );
};

// ---------------------------------------------------------------------------
// Sentiment badge
// ---------------------------------------------------------------------------
const SentimentBadge = ({ sentiment }) => {
  const cfg = {
    POSITIVE: { label: 'POS', color: 'var(--emerald)', bg: 'rgba(16,185,129,0.12)' },
    NEUTRAL:  { label: 'NEU', color: 'var(--text-3)',  bg: 'var(--bg-3)'            },
    NEGATIVE: { label: 'NEG', color: 'var(--rose)',    bg: 'rgba(244,63,94,0.12)'   },
  };
  const c = cfg[sentiment] || cfg['NEUTRAL'];
  return (
    <span style={{
      fontSize: 9, fontWeight: 700, letterSpacing: '0.06em', padding: '2px 6px',
      borderRadius: 3, color: c.color, background: c.bg, fontFamily: 'var(--mono)',
    }}>{c.label}</span>
  );
};

// ---------------------------------------------------------------------------
// Sentiment dot (small circle for keyword sentiment)
// ---------------------------------------------------------------------------
const SentimentDot = ({ score }) => {
  const color = score >= 0.65 ? 'var(--emerald)' : score >= 0.45 ? 'var(--amber)' : 'var(--rose)';
  return (
    <span style={{
      display: 'inline-block', width: 8, height: 8,
      borderRadius: '50%', background: color, flexShrink: 0,
    }} title={`Avg sentiment: ${(score * 100).toFixed(0)}%`} />
  );
};

// ---------------------------------------------------------------------------
// Horizontal bar row for sentiment distribution chart
// ---------------------------------------------------------------------------
const SentimentBar = ({ label, pct, count, color }) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 14 }}>
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
      <span style={{ fontSize: 12, color: 'var(--text-2)', fontWeight: 500 }}>{label}</span>
      <span style={{ fontSize: 11, color: 'var(--text-3)', fontFamily: 'var(--mono)' }}>
        {pct}% <span style={{ marginLeft: 4, opacity: 0.7 }}>({count})</span>
      </span>
    </div>
    <div style={{ height: 10, background: 'var(--bg-3)', borderRadius: 5, overflow: 'hidden' }}>
      <div style={{
        height: '100%', width: `${pct}%`, borderRadius: 5,
        background: color, transition: 'width 0.6s ease',
      }} />
    </div>
  </div>
);

// ---------------------------------------------------------------------------
// Main screen component
// ---------------------------------------------------------------------------
const CommunityScreen = () => {
  // State initialised from MOCK — API replaces on success
  const [kpis, setKpis]               = React.useState(COMMUNITY_MOCK.kpis);
  const [sources, setSources]         = React.useState(COMMUNITY_MOCK.sources);
  const [sentiment, setSentiment]     = React.useState(COMMUNITY_MOCK.sentiment);
  const [mentions, setMentions]       = React.useState(COMMUNITY_MOCK.mentions);
  const [keywords, setKeywords]       = React.useState(COMMUNITY_MOCK.keywords);

  const [syncing, setSyncing]         = React.useState(false);
  const [syncMsg, setSyncMsg]         = React.useState(null);   // { text, ok }
  const syncTimerRef                  = React.useRef(null);
  const [feedFilter, setFeedFilter]   = React.useState('all');
  const [expanded, setExpanded]       = React.useState(null);   // mention id

  // -------------------------------------------------------------------------
  // Load mentions on mount
  // -------------------------------------------------------------------------
  React.useEffect(() => {
    arFetch('/v1/community/mentions?limit=50')
      .then(data => {
        if (data && data.mentions && data.mentions.length > 0) {
          const mapFn = window.mapMention || (m => ({
            id: m.mention_id || m.id,
            source: m.source,
            content: m.text || m.content || '',
            url: m.url,
            sentiment: m.sentiment_label || m.sentiment || 'neutral',
            score: m.sentiment_score || 0.5,
            when: m.detected_at || m.mention_at || m.created_at || '',
            keyword: m.keyword,
            author: m.author,
          }));
          const mapped = data.mentions.map(mapFn);
          setMentions(mapped);

          // Recompute KPIs from live data
          const total = mapped.length;
          const pos   = mapped.filter(m => m.sentiment === 'POSITIVE').length;
          const neg   = mapped.filter(m => m.sentiment === 'NEGATIVE').length;
          const trending = keywords.filter(k => String(k.trend || '').includes('↑')).length;
          const totalMentions = data.total || total;
          const positivePct = total > 0 ? Math.round((pos / total) * 100) : undefined;
          const negativePct = total > 0 ? Math.round((neg / total) * 100) : undefined;
          setKpis(prev => ({ ...prev, totalMentions, positivePct: positivePct !== undefined ? positivePct : prev.positivePct, negativePct: negativePct !== undefined ? negativePct : prev.negativePct, trendingCount: trending }));

          // Recompute sentiment distribution
          const neu = total - pos - neg;
          setSentiment({
            positive: total > 0 ? Math.round((pos / total) * 100) : 61,
            neutral:  total > 0 ? Math.round((neu / total) * 100) : 27,
            negative: total > 0 ? Math.round((neg / total) * 100) : 12,
          });

          // Recompute source breakdown
          const bySource = {};
          mapped.forEach(m => {
            if (!bySource[m.source]) bySource[m.source] = { count: 0, totalScore: 0, items: [] };
            bySource[m.source].count++;
            bySource[m.source].totalScore += (m.score || 0);
            bySource[m.source].items.push(m);
          });
          setSources(prev => {
            const next = { ...prev };
            Object.entries(bySource).forEach(([src, v]) => {
              if (next[src]) {
                next[src] = {
                  ...next[src],
                  count: v.count,
                  sentiment: v.count > 0 ? Math.round((v.totalScore / v.count) * 100) / 100 : next[src].sentiment,
                };
              }
            });
            return next;
          });
        }
      })
      .catch(() => {}); // silently keep MOCK on error
  }, []);

  // -------------------------------------------------------------------------
  // Sync Now
  // -------------------------------------------------------------------------
  const handleSync = () => {
    setSyncing(true);
    setSyncMsg(null);
    arFetch('/v1/community/sync', { method: 'POST' })
      .then(data => {
        const total = data.synced || 0;
        setSyncMsg({ ok: true, text: `Synced ${total} new mentions` });
        // Refresh mentions separately, silently
        return arFetch('/v1/community/mentions?limit=50').then(d => {
          if (d && d.mentions) {
            const mapFn = window.mapMention || (m => ({
              id: m.mention_id || m.id,
              source: m.source,
              content: m.text || m.content || '',
              url: m.url,
              sentiment: m.sentiment_label || m.sentiment || 'neutral',
              score: m.sentiment_score || 0.5,
              when: m.detected_at || m.mention_at || m.created_at || '',
              keyword: m.keyword,
              author: m.author,
            }));
            setMentions(d.mentions.map(mapFn));
          }
        }).catch(() => {}); // silent — sync already succeeded
      })
      .catch(() => {
        setSyncMsg({ ok: false, text: 'Sync failed — using cached data' });
      })
      .finally(() => {
        setSyncing(false);
        clearTimeout(syncTimerRef.current);
        syncTimerRef.current = setTimeout(() => setSyncMsg(null), 4000);
      });
  };

  // -------------------------------------------------------------------------
  // Derived values
  // -------------------------------------------------------------------------
  const filteredMentions = feedFilter === 'all'
    ? mentions
    : mentions.filter(m => m.source === feedFilter);

  const totalMentionsForBars = mentions.length || 1;

  return (
    <div>
      {/* ------------------------------------------------------------------ */}
      {/* Top bar: sync button + KPI strip                                   */}
      {/* ------------------------------------------------------------------ */}
      <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 14, flexWrap: 'wrap' }}>
        <button
          className="btn primary"
          onClick={handleSync}
          disabled={syncing}
          style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 110 }}
        >
          {/* Simple animated spinner using CSS rotation trick */}
          <span style={{
            display: 'inline-block',
            animation: syncing ? 'spin 1s linear infinite' : 'none',
            fontSize: 13,
          }}>⟳</span>
          {syncing ? 'Syncing…' : 'Sync Now'}
        </button>

        {syncMsg && (
          <span style={{
            fontSize: 12, padding: '4px 10px', borderRadius: 6,
            background: syncMsg.ok ? 'rgba(16,185,129,0.15)' : 'rgba(244,63,94,0.15)',
            color: syncMsg.ok ? 'var(--emerald)' : 'var(--rose)',
            border: `1px solid ${syncMsg.ok ? 'rgba(16,185,129,0.3)' : 'rgba(244,63,94,0.3)'}`,
          }}>{syncMsg.text}</span>
        )}

        <div style={{ display: 'flex', gap: 10, marginLeft: 'auto', flexWrap: 'wrap' }}>
          {/* KPI chips */}
          {[
            { label: 'Mentions 24h',    value: kpis.totalMentions.toLocaleString(), color: 'var(--cyan)'    },
            { label: 'Positive',         value: kpis.positivePct + '%',              color: 'var(--emerald)' },
            { label: 'Negative',         value: kpis.negativePct + '%',              color: 'var(--rose)'    },
            { label: 'Trending Keywords',value: kpis.trendingCount,                 color: 'var(--amber)'   },
          ].map(k => (
            <div key={k.label} style={{
              background: 'var(--bg-2)', border: '1px solid var(--border)',
              borderRadius: 8, padding: '6px 14px', display: 'flex',
              flexDirection: 'column', alignItems: 'center', minWidth: 90,
            }}>
              <span style={{ fontSize: 18, fontWeight: 700, color: k.color, fontFamily: 'var(--mono)' }}>
                {k.value}
              </span>
              <span style={{ fontSize: 10, color: 'var(--text-3)', marginTop: 1, whiteSpace: 'nowrap' }}>
                {k.label}
              </span>
            </div>
          ))}
        </div>
      </div>

      {/* ------------------------------------------------------------------ */}
      {/* Source breakdown row (3 cards)                                      */}
      {/* ------------------------------------------------------------------ */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginBottom: 14 }}>
        {[
          { key: 'reddit',  label: 'Reddit',  icon: 'R', bg: '#FF4500' },
          { key: 'discord', label: 'Discord', icon: 'D', bg: '#5865F2' },
          { key: 'youtube', label: 'YouTube', icon: 'Y', bg: '#FF0000' },
        ].map(({ key, label, icon, bg }) => {
          const src = sources[key];
          return (
            <div key={key} className="card" style={{ padding: '14px 16px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                <span style={{
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  width: 28, height: 28, borderRadius: 6, background: bg,
                  color: '#fff', fontSize: 13, fontWeight: 800, fontFamily: 'var(--mono)',
                }}>{icon}</span>
                <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-1)' }}>{label}</span>
              </div>

              <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
                <div>
                  <div style={{ fontSize: 22, fontWeight: 700, color: 'var(--text-1)', fontFamily: 'var(--mono)' }}>
                    {src.count}
                  </div>
                  <div style={{ fontSize: 10, color: 'var(--text-3)' }}>mentions</div>
                </div>
                <div style={{ textAlign: 'right' }}>
                  <div style={{ fontSize: 16, fontWeight: 600, color: 'var(--emerald)', fontFamily: 'var(--mono)' }}>
                    {src.sentiment.toFixed(2)}
                  </div>
                  <div style={{ fontSize: 10, color: 'var(--text-3)' }}>avg sentiment</div>
                </div>
              </div>

              {/* 7-day sparkline */}
              <div style={{ marginBottom: 8 }}>
                <Spark data={src.spark} color={bg} h={28} />
              </div>

              <div style={{
                fontSize: 10, color: 'var(--text-3)', padding: '3px 6px',
                background: 'var(--bg-3)', borderRadius: 4, display: 'inline-block',
                fontFamily: 'var(--mono)',
              }}>
                {src.top}
              </div>
            </div>
          );
        })}
      </div>

      {/* ------------------------------------------------------------------ */}
      {/* Sentiment distribution + Mention feed                               */}
      {/* ------------------------------------------------------------------ */}
      <div style={{ display: 'grid', gridTemplateColumns: '2fr 3fr', gap: 12, marginBottom: 14 }}>

        {/* Left: Sentiment distribution chart */}
        <div className="card" style={{ padding: '16px 18px' }}>
          <div className="card-header" style={{ marginBottom: 16 }}>
            <div className="card-title">Sentiment Distribution</div>
            <span className="badge">24h</span>
          </div>

          <SentimentBar
            label="Positive"
            pct={sentiment.positive}
            count={Math.round(mentions.length * sentiment.positive / 100)}
            color="var(--emerald)"
          />
          <SentimentBar
            label="Neutral"
            pct={sentiment.neutral}
            count={Math.round(mentions.length * sentiment.neutral / 100)}
            color="var(--text-3)"
          />
          <SentimentBar
            label="Negative"
            pct={sentiment.negative}
            count={Math.round(mentions.length * sentiment.negative / 100)}
            color="var(--rose)"
          />

          {/* Legend */}
          <div style={{
            marginTop: 16, paddingTop: 12, borderTop: '1px solid var(--border)',
            display: 'flex', gap: 14, flexWrap: 'wrap',
          }}>
            {[
              { label: 'Positive', color: 'var(--emerald)' },
              { label: 'Neutral',  color: 'var(--text-3)'  },
              { label: 'Negative', color: 'var(--rose)'    },
            ].map(l => (
              <div key={l.label} style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
                <span style={{ width: 10, height: 10, borderRadius: 2, background: l.color, display: 'inline-block' }} />
                <span style={{ fontSize: 11, color: 'var(--text-3)' }}>{l.label}</span>
              </div>
            ))}
          </div>

          {/* Overall score */}
          <div style={{
            marginTop: 16, background: 'var(--bg-3)', borderRadius: 8, padding: '10px 14px',
            display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          }}>
            <span style={{ fontSize: 11, color: 'var(--text-3)' }}>Overall brand sentiment</span>
            <span style={{
              fontSize: 16, fontWeight: 700, fontFamily: 'var(--mono)',
              color: 'var(--emerald)',
            }}>
              {((sentiment.positive * 1 - sentiment.negative * 1) / 100).toFixed(2) > 0 ? '+' : ''}
              {((sentiment.positive - sentiment.negative) / 100).toFixed(2)}
            </span>
          </div>
        </div>

        {/* Right: Mention feed */}
        <div className="card" style={{ padding: '14px 16px', display: 'flex', flexDirection: 'column' }}>
          <div className="card-header" style={{ marginBottom: 12 }}>
            <div className="card-title">Recent Mentions</div>
            <span style={{ fontSize: 11, color: 'var(--text-3)' }}>
              {filteredMentions.length} of {mentions.length}
            </span>
          </div>

          {/* Filter tabs */}
          <div style={{
            display: 'flex', gap: 2, marginBottom: 12,
            borderBottom: '1px solid var(--border)',
          }}>
            {['all', 'reddit', 'discord', 'youtube'].map(f => (
              <button
                key={f}
                style={{
                  padding: '7px 13px', fontSize: 11, fontWeight: 500,
                  color: feedFilter === f ? 'var(--text-1)' : 'var(--text-3)',
                  borderBottom: feedFilter === f ? '2px solid var(--accent)' : '2px solid transparent',
                  textTransform: f === 'all' ? 'capitalize' : 'capitalize',
                  marginBottom: -1,
                }}
                onClick={() => { setFeedFilter(f); setExpanded(null); }}
              >
                {f === 'all' ? 'All' : f.charAt(0).toUpperCase() + f.slice(1)}
              </button>
            ))}
          </div>

          {/* Scrollable mention list */}
          <div style={{ overflowY: 'auto', maxHeight: 320, display: 'flex', flexDirection: 'column', gap: 8 }}>
            {filteredMentions.map(m => (
              <div key={m.id} style={{
                padding: '10px 12px', borderRadius: 7,
                background: expanded === m.id ? 'var(--bg-3)' : 'var(--bg-2)',
                border: `1px solid ${expanded === m.id ? 'var(--accent)' : 'var(--border)'}`,
                cursor: 'pointer', transition: 'border-color 0.15s',
              }} onClick={() => setExpanded(expanded === m.id ? null : m.id)}>

                {/* Row 1: icon + author + sentiment + time + link */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 6 }}>
                  <SourceIcon source={m.source} size={16} />
                  <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-2)', fontFamily: 'var(--mono)' }}>
                    {m.author || 'anon'}
                  </span>
                  <SentimentBadge sentiment={m.sentiment} />
                  <span style={{ fontSize: 10, color: 'var(--text-3)', marginLeft: 'auto' }}>{m.when}</span>
                  {m.url && m.url !== '#' && (
                    <a href={m.url} target="_blank" rel="noopener noreferrer"
                       onClick={e => e.stopPropagation()}
                       style={{ color: 'var(--text-3)', fontSize: 11, lineHeight: 1 }}
                       title="Open source">↗</a>
                  )}
                </div>

                {/* Row 2: content */}
                <div style={{
                  fontSize: 12, color: 'var(--text-2)', lineHeight: 1.55,
                  overflow: 'hidden',
                  display: expanded === m.id ? 'block' : '-webkit-box',
                  WebkitLineClamp: expanded === m.id ? 'unset' : 2,
                  WebkitBoxOrient: 'vertical',
                }}>
                  {m.content}
                </div>

                {/* Row 3: keyword tag */}
                {m.keyword && (
                  <div style={{ marginTop: 6 }}>
                    <span style={{
                      fontSize: 10, color: 'var(--accent)', background: 'rgba(139,92,246,0.1)',
                      padding: '2px 6px', borderRadius: 3, fontFamily: 'var(--mono)',
                    }}>{m.keyword}</span>
                  </div>
                )}
              </div>
            ))}

            {filteredMentions.length === 0 && (
              <div style={{ textAlign: 'center', color: 'var(--text-3)', fontSize: 12, padding: '32px 0' }}>
                No mentions for this source yet
              </div>
            )}
          </div>
        </div>
      </div>

      {/* ------------------------------------------------------------------ */}
      {/* Trending keywords panel (full width)                                */}
      {/* ------------------------------------------------------------------ */}
      <div className="card" style={{ padding: '16px 18px' }}>
        <div className="card-header" style={{ marginBottom: 14 }}>
          <div className="card-title">Trending Keywords</div>
          <span style={{ fontSize: 11, color: 'var(--text-3)' }}>Last 24h · community_keywords config</span>
        </div>

        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
          {keywords.map(kw => {
            // Size based on mention count (min 12px, max 18px)
            const min = Math.min(...keywords.map(k => k.count));
            const max = Math.max(...keywords.map(k => k.count));
            const range = max - min || 1;
            const fontSize = 11 + Math.round(((kw.count - min) / range) * 7);
            const trendColor = kw.trend.includes('↑') ? 'var(--emerald)'
                             : kw.trend.includes('↓') ? 'var(--rose)'
                             : 'var(--text-3)';

            return (
              <div key={kw.name} style={{
                display: 'flex', alignItems: 'center', gap: 6,
                background: 'var(--bg-3)', border: '1px solid var(--border)',
                borderRadius: 20, padding: '6px 12px',
                cursor: 'default', transition: 'border-color 0.15s',
              }} title={`${kw.count} mentions · avg sentiment ${(kw.sentiment * 100).toFixed(0)}%`}>

                <SentimentDot score={kw.sentiment} />

                <span style={{
                  fontSize, fontWeight: kw.count > 50 ? 700 : 500,
                  color: 'var(--text-1)', fontFamily: 'var(--mono)',
                }}>
                  {kw.name}
                </span>

                <span style={{
                  fontSize: 11, fontFamily: 'var(--mono)', fontWeight: 600,
                  color: 'var(--text-3)',
                }}>
                  {kw.count}
                </span>

                <span style={{
                  fontSize: 12, color: trendColor, fontWeight: 700,
                }}>
                  {kw.trend}
                </span>
              </div>
            );
          })}
        </div>
      </div>

      {/* Keyframe for sync spinner — injected once */}
      <style>{`
        @keyframes spin { to { transform: rotate(360deg); } }
      `}</style>
    </div>
  );
};

window.CommunityScreen = CommunityScreen;
