// SocialListening.jsx — Admin Portal "Social Listening" page.
//
// Surfaces social_mentions rows found + AI-scored by the `social-search`
// Edge Function (Reddit live; Facebook deferred to a future provider).
// The function runs every 4h via pg_cron and on demand from the
// "Search now" button here. Each mention carries an AI relevance score
// (0-100), a reason, and a suggested engagement angle so the owner can
// jump into the right local conversations for SEO / GEO.
//
// Realtime: useSupaList keeps the list live, so new hits stream in during
// a search and ai_* fields fill in as analysis completes. Review actions
// (Save / Engaged / Dismiss) write back through the same hook.
//
// All top-level identifiers carry an "sl"/"Sl" suffix: in the Babel-in-
// browser portal every top-level const leaks to the global scope, so
// names must be unique across all component files (HANDBOOK §9).

const { useState: useStateSl, useEffect: useEffectSl, useMemo: useMemoSl } = React;

// ---- row <-> object mappers for useSupaList -----------------------------

const slMentionFromRow = (r) => ({
  id: r.id,
  source: r.source,
  externalId: r.external_id,
  keywordId: r.keyword_id,
  matchedTerm: r.matched_term,
  url: r.url,
  title: r.title,
  body: r.body,
  author: r.author,
  subreddit: r.subreddit,
  score: r.score,
  numComments: r.num_comments,
  postedAt: r.posted_at,
  fetchedAt: r.fetched_at,
  aiStatus: r.ai_status,
  aiRelevant: r.ai_relevant,
  aiScore: r.ai_score,
  aiReason: r.ai_reason,
  aiAngle: r.ai_angle,
  aiTopics: r.ai_topics,
  reviewStatus: r.review_status,
  reviewedAt: r.reviewed_at,
});
// Only the columns the portal is allowed to change on a review action.
// Everything else is owned by the Edge Function; omitting it means an
// UPDATE never clobbers AI state.
const slMentionToRow = (o) => ({
  id: o.id,
  review_status: o.reviewStatus,
  reviewed_at: o.reviewedAt,
});

const slKeywordFromRow = (r) => ({
  id: r.id,
  term: r.term,
  sources: r.sources || ['reddit'],
  active: r.active,
  lastSearchedAt: r.last_searched_at,
  createdAt: r.created_at,
});
const slKeywordToRow = (o) => ({
  id: o.id,
  term: o.term,
  sources: o.sources,
  active: o.active,
});

// ---- small helpers ------------------------------------------------------

const SL_SOURCE_META = {
  reddit:   { label: 'Reddit',   bg: '#FFF0E8', fg: '#D93A00' },
  facebook: { label: 'Facebook', bg: '#E7F0FF', fg: '#1877F2' },
};

const slFmtRel = (iso) => {
  if (!iso) return '';
  const then = new Date(iso).getTime();
  if (isNaN(then)) return '';
  const s = Math.max(0, Math.floor((Date.now() - then) / 1000));
  if (s < 60) return 'just now';
  const m = Math.floor(s / 60);
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const d = Math.floor(h / 24);
  if (d < 30) return `${d}d ago`;
  const mo = Math.floor(d / 30);
  return `${mo}mo ago`;
};

// Relevance-score → swatch. Tuned to the ink-first palette.
const slScoreSwatch = (score) => {
  if (score >= 80) return { bg: '#DCFCE7', fg: '#15803D' };
  if (score >= 60) return { bg: '#CCFBF1', fg: '#0F766E' };
  if (score >= 40) return { bg: '#FEF3C7', fg: '#B45309' };
  return { bg: '#F3F4F6', fg: '#6B7280' };
};

// ---- main page ----------------------------------------------------------

const SocialListening = () => {
  const [mentions, setMentions] = window.useSupaList('social_mentions', {
    fromRow: slMentionFromRow,
    toRow: slMentionToRow,
    initial: [],
  });
  const [keywords, setKeywords] = window.useSupaList('social_keywords', {
    fromRow: slKeywordFromRow,
    toRow: slKeywordToRow,
    initial: [],
  });

  const [tab, setTab] = useStateSl('relevant');     // relevant | all | saved | engaged | dismissed
  const [sourceFilter, setSourceFilter] = useStateSl('all');  // all | reddit | facebook
  const [searching, setSearching] = useStateSl(false);
  const [settingsOpen, setSettingsOpen] = useStateSl(false);
  const [toast, setToast] = useStateSl('');

  // Relevance context (business blurb + areas + threshold). Lives on the
  // restaurants row; drives the default "Relevant" filter and the AI prompt.
  const [cfg, setCfg] = useStateSl({ business_blurb: '', areas: [], min_score: 60 });
  useEffectSl(() => {
    if (!window.supa) return;
    let cancelled = false;
    window.supa.from('restaurants')
      .select('social_listening_config')
      .eq('id', window.RESTAURANT_ID)
      .maybeSingle()
      .then(({ data }) => {
        if (cancelled || !data?.social_listening_config) return;
        const c = data.social_listening_config;
        setCfg({
          business_blurb: c.business_blurb || '',
          areas: Array.isArray(c.areas) ? c.areas : [],
          min_score: typeof c.min_score === 'number' ? c.min_score : 60,
        });
      });
    return () => { cancelled = true; };
  }, []);

  const minScore = cfg.min_score || 0;

  const lastSearched = useMemoSl(() => {
    const stamps = keywords.map(k => k.lastSearchedAt).filter(Boolean).map(s => new Date(s).getTime());
    if (!stamps.length) return null;
    return new Date(Math.max(...stamps)).toISOString();
  }, [keywords]);

  // Counts per tab (for the segment labels).
  const counts = useMemoSl(() => {
    const c = { relevant: 0, all: mentions.length, saved: 0, engaged: 0, dismissed: 0 };
    mentions.forEach(m => {
      if (m.reviewStatus === 'saved') c.saved++;
      else if (m.reviewStatus === 'engaged') c.engaged++;
      else if (m.reviewStatus === 'dismissed') c.dismissed++;
      if (m.reviewStatus === 'new' && m.aiRelevant && (m.aiScore || 0) >= minScore) c.relevant++;
    });
    return c;
  }, [mentions, minScore]);

  const visible = useMemoSl(() => {
    let list = mentions.slice();
    if (sourceFilter !== 'all') list = list.filter(m => m.source === sourceFilter);
    if (tab === 'relevant') {
      list = list.filter(m => m.reviewStatus === 'new' && m.aiRelevant && (m.aiScore || 0) >= minScore);
    } else if (tab === 'saved') {
      list = list.filter(m => m.reviewStatus === 'saved');
    } else if (tab === 'engaged') {
      list = list.filter(m => m.reviewStatus === 'engaged');
    } else if (tab === 'dismissed') {
      list = list.filter(m => m.reviewStatus === 'dismissed');
    }
    // 'all' shows everything (including pending + dismissed).
    list.sort((a, b) => {
      const sa = a.aiScore == null ? -1 : a.aiScore;
      const sb = b.aiScore == null ? -1 : b.aiScore;
      if (sb !== sa) return sb - sa;
      return new Date(b.postedAt || b.fetchedAt || 0) - new Date(a.postedAt || a.fetchedAt || 0);
    });
    return list;
  }, [mentions, tab, sourceFilter, minScore]);

  const pendingCount = useMemoSl(() => mentions.filter(m => m.aiStatus === 'pending').length, [mentions]);

  const setReview = (id, status) => {
    setMentions(ms => ms.map(m => (
      m.id === id ? { ...m, reviewStatus: status, reviewedAt: new Date().toISOString() } : m
    )));
  };

  const runSearch = async () => {
    if (!window.supa || searching) return;
    setSearching(true);
    try {
      const { data, error } = await window.supa.functions.invoke('social-search', { body: { mode: 'both' } });
      if (error) throw error;
      if (data && data.ok === false && data.errors && data.errors.length) {
        setToast('Search issue: ' + data.errors[0]);
      } else {
        const n = data?.inserted || 0;
        setToast(n > 0 ? `Found ${n} new · ${data?.relevant || 0} relevant` : 'No new mentions this run');
      }
    } catch (e) {
      setToast('Search failed: ' + (e?.message || 'error'));
    } finally {
      setSearching(false);
    }
  };

  const activeKeywords = keywords.filter(k => k.active).length;

  return (
    <div className="portal-page-wide" style={{ maxWidth: 1100 }}>
      <div className="portal-page-header" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
        <div>
          <h1 className="portal-page-title">Social Listening</h1>
          <div className="portal-page-subtitle">
            Reddit threads mentioning Snap-a-Box or our areas, scored by AI for how worth engaging they are.
            {' '}
            {activeKeywords > 0
              ? <span>Watching <b>{activeKeywords}</b> keyword{activeKeywords === 1 ? '' : 's'}.</span>
              : <span style={{ color: 'var(--warning)' }}>No active keywords — add some in Settings.</span>}
            {lastSearched && <span> · Last searched {slFmtRel(lastSearched)}.</span>}
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
          <PBtn variant="secondary" size="md" icon="settings" onClick={() => setSettingsOpen(true)}>Settings</PBtn>
          <PBtn variant="primary" size="md" icon="refresh" disabled={searching} onClick={runSearch}>
            {searching ? 'Searching…' : 'Search now'}
          </PBtn>
        </div>
      </div>

      {/* Filters */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '16px 0', flexWrap: 'wrap' }}>
        <PSegment
          value={tab}
          onChange={setTab}
          options={[
            { value: 'relevant',  label: `Relevant${counts.relevant ? ` (${counts.relevant})` : ''}` },
            { value: 'all',       label: `All${counts.all ? ` (${counts.all})` : ''}` },
            { value: 'saved',     label: `Saved${counts.saved ? ` (${counts.saved})` : ''}` },
            { value: 'engaged',   label: `Engaged${counts.engaged ? ` (${counts.engaged})` : ''}` },
            { value: 'dismissed', label: `Dismissed${counts.dismissed ? ` (${counts.dismissed})` : ''}` },
          ]}
        />
        <div style={{ flex: 1 }} />
        <PSegment
          value={sourceFilter}
          onChange={setSourceFilter}
          options={[
            { value: 'all', label: 'All sources' },
            { value: 'reddit', label: 'Reddit' },
          ]}
        />
      </div>

      {pendingCount > 0 && (
        <div style={{ fontSize: 12, color: 'var(--fg-3)', marginBottom: 12, display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          <PIcon name="sparkle" size={13} color="var(--fg-3)" />
          Analyzing {pendingCount} new mention{pendingCount === 1 ? '' : 's'}…
        </div>
      )}

      {/* List */}
      {visible.length === 0 ? (
        <div className="portal-empty" style={{ padding: '48px 24px', textAlign: 'center' }}>
          <div style={{ fontSize: 14, color: 'var(--fg-2)', marginBottom: 6 }}>
            {mentions.length === 0
              ? 'No mentions yet.'
              : tab === 'relevant'
                ? 'Nothing relevant right now.'
                : 'Nothing here.'}
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--fg-3)' }}>
            {mentions.length === 0
              ? 'Click “Search now” to scan Reddit for your keywords.'
              : 'Try the “All” tab or run a fresh search.'}
          </div>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {visible.map(m => <SlMentionCard key={m.id} m={m} onReview={setReview} />)}
        </div>
      )}

      {settingsOpen && (
        <SlSettingsModal
          keywords={keywords}
          setKeywords={setKeywords}
          cfg={cfg}
          setCfg={setCfg}
          onClose={() => setSettingsOpen(false)}
          onToast={setToast}
        />
      )}

      <PToast message={toast} open={!!toast} onClose={() => setToast('')} />
    </div>
  );
};

// ---- mention card -------------------------------------------------------

const SlMentionCard = ({ m, onReview }) => {
  const src = SL_SOURCE_META[m.source] || { label: m.source, bg: '#F3F4F6', fg: '#6B7280' };
  const analyzing = m.aiStatus === 'pending';
  const failed = m.aiStatus === 'error';
  const sw = slScoreSwatch(m.aiScore || 0);

  return (
    <div style={{
      background: '#FFFFFF',
      border: '1px solid var(--border-2)',
      borderRadius: 12,
      padding: '14px 16px',
      opacity: m.reviewStatus === 'dismissed' ? 0.6 : 1,
    }}>
      {/* meta row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8, flexWrap: 'wrap' }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center',
          fontSize: 11, fontWeight: 600, padding: '2px 8px', borderRadius: 999,
          background: src.bg, color: src.fg,
        }}>{src.label}</span>
        {m.subreddit && <span style={{ fontSize: 12, color: 'var(--fg-2)', fontWeight: 500 }}>{m.subreddit}</span>}
        {m.postedAt && <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>· {slFmtRel(m.postedAt)}</span>}
        {typeof m.score === 'number' && (
          <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>· ▲ {m.score}</span>
        )}
        {typeof m.numComments === 'number' && m.numComments > 0 && (
          <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>· {m.numComments} comment{m.numComments === 1 ? '' : 's'}</span>
        )}
        <div style={{ flex: 1 }} />
        {analyzing ? (
          <span style={{ fontSize: 11.5, color: 'var(--fg-3)', display: 'inline-flex', alignItems: 'center', gap: 5 }}>
            <PIcon name="sparkle" size={12} color="var(--fg-3)" /> Analyzing…
          </span>
        ) : failed ? (
          <span style={{ fontSize: 11.5, color: 'var(--fg-3)' }}>Analysis failed</span>
        ) : (
          <span style={{
            fontSize: 12, fontWeight: 700, padding: '2px 9px', borderRadius: 999,
            background: sw.bg, color: sw.fg, fontFamily: 'var(--font-num)',
          }}>{m.aiScore}<span style={{ fontWeight: 500, opacity: 0.75 }}> / 100</span></span>
        )}
      </div>

      {/* title */}
      <a href={m.url} target="_blank" rel="noopener noreferrer" style={{
        display: 'inline-block',
        fontSize: 15, fontWeight: 600, color: 'var(--fg-1)',
        textDecoration: 'none', letterSpacing: '-0.01em', lineHeight: 1.35,
      }}>
        {m.title || '(untitled post)'}
        <PIcon name="arrowR" size={13} color="var(--fg-3)" style={{ marginLeft: 6, transform: 'rotate(-45deg)' }} />
      </a>

      {/* snippet */}
      {m.body && (
        <div style={{
          fontSize: 13, color: 'var(--fg-2)', marginTop: 6, lineHeight: 1.5,
          display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
        }}>{m.body}</div>
      )}

      {/* AI reason + angle */}
      {!analyzing && !failed && (m.aiReason || m.aiAngle) && (
        <div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 8 }}>
          {m.aiReason && (
            <div style={{ fontSize: 12.5, color: 'var(--fg-2)' }}>
              <span style={{ color: 'var(--fg-3)', fontWeight: 600 }}>Why: </span>{m.aiReason}
            </div>
          )}
          {m.aiAngle && (
            <div style={{
              fontSize: 12.5, color: 'var(--fg-1)',
              background: 'var(--bg-sunken)', borderRadius: 8, padding: '8px 10px',
              display: 'flex', alignItems: 'flex-start', gap: 7,
            }}>
              <PIcon name="sparkle" size={14} color="var(--fg-2)" style={{ marginTop: 1, flexShrink: 0 }} />
              <span><b>Angle:</b> {m.aiAngle}</span>
            </div>
          )}
        </div>
      )}

      {/* topics + matched term */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 10, flexWrap: 'wrap' }}>
        {(m.aiTopics || []).map((t, i) => (
          <span key={i} style={{
            fontSize: 10.5, fontWeight: 500, padding: '2px 7px', borderRadius: 999,
            background: '#F5F5F7', color: '#6E6E73',
          }}>{t}</span>
        ))}
        {m.matchedTerm && (
          <span style={{ fontSize: 11, color: 'var(--fg-3)' }}>
            <PIcon name="search" size={11} color="var(--fg-3)" style={{ marginRight: 3 }} />
            {m.matchedTerm}
          </span>
        )}
      </div>

      {/* actions */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--border-2)' }}>
        <PBtn variant="secondary" size="sm" icon="arrowR" onClick={() => window.open(m.url, '_blank', 'noopener')}>Open</PBtn>
        <div style={{ flex: 1 }} />
        <SlReviewBtn icon="star"  label="Save"    active={m.reviewStatus === 'saved'}     onClick={() => onReview(m.id, m.reviewStatus === 'saved' ? 'new' : 'saved')} />
        <SlReviewBtn icon="check" label="Engaged" active={m.reviewStatus === 'engaged'}   onClick={() => onReview(m.id, m.reviewStatus === 'engaged' ? 'new' : 'engaged')} />
        <SlReviewBtn icon="x"     label="Dismiss" active={m.reviewStatus === 'dismissed'} onClick={() => onReview(m.id, m.reviewStatus === 'dismissed' ? 'new' : 'dismissed')} />
      </div>
    </div>
  );
};

const SlReviewBtn = ({ icon, label, active, onClick }) => (
  <button onClick={onClick} title={label} style={{
    display: 'inline-flex', alignItems: 'center', gap: 5,
    height: 30, padding: '0 11px', borderRadius: 7,
    fontSize: 12.5, fontWeight: 500,
    cursor: 'pointer',
    background: active ? 'var(--fg-1)' : 'var(--bg-surface)',
    color: active ? '#FFFFFF' : 'var(--fg-2)',
    border: '1px solid ' + (active ? 'var(--fg-1)' : 'var(--border-1)'),
  }}>
    <PIcon name={icon} size={14} />
    {label}
  </button>
);

// ---- settings modal -----------------------------------------------------

const SlSettingsModal = ({ keywords, setKeywords, cfg, setCfg, onClose, onToast }) => {
  const [newTerm, setNewTerm] = useStateSl('');
  const [blurb, setBlurb] = useStateSl(cfg.business_blurb || '');
  const [areasText, setAreasText] = useStateSl((cfg.areas || []).join(', '));
  const [minScore, setMinScore] = useStateSl(cfg.min_score || 60);
  const [savingCfg, setSavingCfg] = useStateSl(false);

  const addKeyword = () => {
    const term = newTerm.trim();
    if (!term) return;
    if (keywords.some(k => k.term.toLowerCase() === term.toLowerCase())) {
      onToast('Keyword already exists');
      setNewTerm('');
      return;
    }
    const id = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : ('kw-' + Date.now());
    setKeywords(ks => [...ks, { id, term, sources: ['reddit'], active: true, lastSearchedAt: null, createdAt: new Date().toISOString() }]);
    setNewTerm('');
  };
  const toggleKeyword = (id) => setKeywords(ks => ks.map(k => k.id === id ? { ...k, active: !k.active } : k));
  const removeKeyword = (id) => setKeywords(ks => ks.filter(k => k.id !== id));

  const saveCfg = async () => {
    setSavingCfg(true);
    const areas = areasText.split(',').map(s => s.trim()).filter(Boolean);
    const next = {
      business_blurb: blurb.trim(),
      areas,
      min_score: Math.max(0, Math.min(100, parseInt(minScore, 10) || 0)),
    };
    try {
      if (window.supa) {
        const { error } = await window.supa.from('restaurants')
          .update({ social_listening_config: next })
          .eq('id', window.RESTAURANT_ID);
        if (error) throw error;
      }
      setCfg(next);
      onToast('Settings saved');
    } catch (e) {
      onToast('Save failed: ' + (e?.message || 'error'));
    } finally {
      setSavingCfg(false);
    }
  };

  return (
    <PModal open onClose={onClose} title="Social Listening settings" width={560} footer={
      <>
        <PBtn variant="ghost" onClick={onClose}>Close</PBtn>
        <PBtn variant="primary" disabled={savingCfg} onClick={saveCfg}>{savingCfg ? 'Saving…' : 'Save context'}</PBtn>
      </>
    }>
      <div style={{ padding: 18, display: 'flex', flexDirection: 'column', gap: 22 }}>
        {/* Keyword manager */}
        <div>
          <PField label="Keywords to watch" hint="Each term is searched on Reddit. Inactive terms are skipped.">
            <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
              <input
                className="portal-input"
                value={newTerm}
                onChange={e => setNewTerm(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addKeyword(); } }}
                placeholder="e.g. bento Katy, meal prep Houston…"
                style={{ flex: 1, height: 34 }}
              />
              <PBtn variant="secondary" icon="plus" onClick={addKeyword}>Add</PBtn>
            </div>
          </PField>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {keywords.length === 0 && (
              <div style={{ fontSize: 12.5, color: 'var(--fg-3)', padding: '6px 0' }}>No keywords yet — add one above.</div>
            )}
            {keywords.map(k => (
              <div key={k.id} style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '8px 10px', borderRadius: 8,
                background: 'var(--bg-sunken)',
                opacity: k.active ? 1 : 0.55,
              }}>
                <span style={{ flex: 1, fontSize: 13, fontWeight: 500, color: 'var(--fg-1)' }}>{k.term}</span>
                <span style={{ fontSize: 10.5, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.04em' }}>reddit</span>
                <button onClick={() => toggleKeyword(k.id)} title={k.active ? 'Active — click to pause' : 'Paused — click to activate'} style={{
                  fontSize: 11.5, fontWeight: 600, padding: '3px 9px', borderRadius: 999, cursor: 'pointer',
                  background: k.active ? 'var(--success-bg)' : 'transparent',
                  color: k.active ? 'var(--success)' : 'var(--fg-3)',
                  border: '1px solid ' + (k.active ? 'transparent' : 'var(--border-1)'),
                }}>{k.active ? 'Active' : 'Paused'}</button>
                <button onClick={() => removeKeyword(k.id)} title="Remove keyword" style={{
                  width: 26, height: 26, borderRadius: 6, cursor: 'pointer',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  color: 'var(--fg-3)',
                }}><PIcon name="trash" size={14} /></button>
              </div>
            ))}
          </div>
          <div style={{ fontSize: 11.5, color: 'var(--fg-3)', marginTop: 8, display: 'inline-flex', alignItems: 'center', gap: 5 }}>
            <PIcon name="info" size={12} color="var(--fg-3)" />
            Facebook search is coming once a provider is connected.
          </div>
        </div>

        {/* Relevance context */}
        <div style={{ borderTop: '1px solid var(--border-2)', paddingTop: 18, display: 'flex', flexDirection: 'column', gap: 16 }}>
          <PField label="What we are" hint="Helps the AI judge whether a thread is worth engaging.">
            <textarea
              className="portal-input"
              value={blurb}
              onChange={e => setBlurb(e.target.value)}
              rows={2}
              style={{ width: '100%', resize: 'vertical', lineHeight: 1.5, padding: '8px 10px' }}
            />
          </PField>
          <PField label="Service areas" hint="Comma-separated cities / neighborhoods we care about.">
            <input
              className="portal-input"
              value={areasText}
              onChange={e => setAreasText(e.target.value)}
              style={{ width: '100%', height: 34 }}
            />
          </PField>
          <PField label={`Relevance threshold — ${minScore}`} hint="Mentions at or above this AI score show in the Relevant tab.">
            <input
              type="range" min="0" max="100" step="5"
              value={minScore}
              onChange={e => setMinScore(parseInt(e.target.value, 10))}
              style={{ width: '100%' }}
            />
          </PField>
        </div>
      </div>
    </PModal>
  );
};

window.SocialListening = SocialListening;
