// StrictlyVC Deals — Markets Dashboard module.
//
// A searchable ledger of venture deals parsed from every StrictlyVC newsletter
// (fundings by tier, exits, IPOs, new funds), classified by sector and enriched
// with web research on the larger companies. The pipeline and database live in
// a SEPARATE Supabase project and are fully server-side; this panel only reads
// the public, read-only `svc_*` views and RPCs there — no writes exist on that
// API, so nothing here can mutate anything.
//
// Exposes window.StrictlyVCPanel (the inner content) and
// window.StrictlyVCSection (the collapsible section header ForMe mounts).
// Loads AFTER page-forme.jsx and reuses its IntelShell / useCollapsed / Chevron.

// Read-only publishable key for the StrictlyVC ledger project — safe in the
// browser by design (the underlying tables are not reachable; only SELECT on
// the svc_* views). If the ledger moves projects, only these two lines change.
const SVC_URL = 'https://zfqdwpwjwstaeftpuniq.supabase.co';
const SVC_KEY = 'sb_publishable_gcpjCm8OUZVG3_r5vu51ag_xwPVQzsT';

const _svcHeaders = () => ({ apikey: SVC_KEY, Authorization: `Bearer ${SVC_KEY}`, 'Content-Type': 'application/json' });
const _svcFail = async (r, what) => { throw new Error(`StrictlyVC ${what} ${r.status}: ${(await r.text()).slice(0, 160)}`); };
const svcGet = async (path) => {
  const r = await fetch(`${SVC_URL}/rest/v1/${path}`, { headers: _svcHeaders() });
  if (!r.ok) await _svcFail(r, 'API');
  return r.json();
};
const svcRpc = async (name, body) => {
  const r = await fetch(`${SVC_URL}/rest/v1/rpc/${name}`, { method: 'POST', headers: _svcHeaders(), body: JSON.stringify(body || {}) });
  if (!r.ok) await _svcFail(r, name);
  return r.json();
};

// Facets / stats / enriched-set are fetched once per page load and shared.
let _svcFacetsP = null, _svcStatsP = null, _svcEnrichedP = null;
const svcFacets = () => (_svcFacetsP = _svcFacetsP || svcRpc('svc_facets', {}).catch(() => null));
const svcStats = () => (_svcStatsP = _svcStatsP || svcGet('svc_stats').then((a) => (Array.isArray(a) ? a[0] : a)).catch(() => null));
const svcEnriched = () => (_svcEnrichedP = _svcEnrichedP || svcGet('svc_companies?select=company_key&enriched=is.true&limit=5000')
  .then((rows) => new Set((rows || []).map((r) => r.company_key))).catch(() => new Set()));

// ── Formatting ───────────────────────────────────────────────────────────────
const _svcNum = (v) => (v == null || v === '' ? null : Number(v));
const _svcSym = (ccy) => ({ USD: '$', EUR: '€', GBP: '£', CHF: 'CHF ', JPY: '¥', CAD: 'C$', AUD: 'A$', INR: '₹' })[ccy || 'USD'] ?? `${ccy} `;
// Amounts are in $M as reported: 41.6 → $41.6M · 1200 → $1.2B.
const _svcMoney = (musd, ccy) => {
  const v = _svcNum(musd);
  if (v == null) return null;
  const s = _svcSym(ccy);
  if (v >= 1000) return `${s}${(v / 1000).toFixed(v >= 10000 ? 0 : 1).replace(/\.0$/, '')}B`;
  if (v >= 100) return `${s}${Math.round(v)}M`;
  return `${s}${v.toFixed(1).replace(/\.0$/, '')}M`;
};
const _svcDate = (d) => {
  if (!d) return '—';
  const dt = new Date(`${d}T00:00:00Z`);
  if (isNaN(dt)) return d;
  return `${dt.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' })} ’${String(dt.getUTCFullYear()).slice(2)}`;
};
const SVC_TIERS = [
  { id: 'massive', label: 'MASSIVE', color: '#7A2D8E' },
  { id: 'big', label: 'BIG', color: '#1A4FB5' },
  { id: 'smaller', label: 'SMALLER', color: 'rgba(14,14,12,0.55)' },
  { id: 'exits', label: 'EXIT', color: '#0E7C3A' },
  { id: 'going_public', label: 'IPO', color: '#C9622E' },
  { id: 'new_funds', label: 'NEW FUND', color: '#9A6A1A' },
  { id: 'other_funding', label: 'OTHER', color: 'rgba(14,14,12,0.4)' },
];
const _svcTier = (id) => SVC_TIERS.find((t) => t.id === id) || { id, label: String(id || '—').toUpperCase(), color: tokens.inkMute };
const _svcInt = (v) => (v == null ? '—' : Number(v).toLocaleString('en-US'));

// ── Small presentational bits ────────────────────────────────────────────────
const SvcPill = ({ text, color, filled, title }) => (
  <span title={title} style={{ fontFamily: fontMono, fontSize: '8.5px', letterSpacing: '0.1em', padding: '2px 7px', borderRadius: '999px', whiteSpace: 'nowrap', border: `1px solid ${color}`, color: filled ? tokens.paper : color, background: filled ? color : 'none' }}>{text}</span>
);
const SvcStat = ({ label, value, sub }) => (
  <div style={{ border: `1px solid ${tokens.inkLine}`, padding: '8px 12px', minWidth: '96px', flex: '1 1 96px' }}>
    <div style={{ fontFamily: fontMono, fontSize: '8.5px', letterSpacing: '0.12em', color: tokens.inkMute, marginBottom: '3px' }}>{label}</div>
    <div style={{ fontFamily: fontDisplay, fontSize: '18px', letterSpacing: '-0.02em', color: tokens.ink, lineHeight: 1.1 }}>{value}</div>
    {sub && <div style={{ fontFamily: fontMono, fontSize: '8.5px', color: tokens.inkMute, marginTop: '3px' }}>{sub}</div>}
  </div>
);
// Investor chip — click filters the ledger by that investor.
const SvcInvestor = ({ name, lead, returning, onPick }) => (
  <span onClick={(e) => { e.stopPropagation(); onPick && onPick(name); }}
    title={`${lead ? 'Lead' : 'Investor'}${returning ? ' · returning' : ''} — click to filter by ${name}`}
    style={{ display: 'inline-flex', alignItems: 'center', gap: '4px', fontFamily: fontMono, fontSize: '9.5px', letterSpacing: '0.03em', padding: '3px 8px', borderRadius: '999px', cursor: onPick ? 'pointer' : 'default', whiteSpace: 'nowrap', border: `1px solid ${lead ? tokens.ink : tokens.inkLine}`, background: lead ? tokens.ink : 'none', color: lead ? tokens.paper : tokens.inkSoft }}>
    {returning && <span style={{ fontSize: '9px', opacity: 0.8 }}>↺</span>}{name}
  </span>
);
const svcInp = { width: '100%', boxSizing: 'border-box', fontFamily: fontMono, fontSize: '11px', padding: '8px 10px', border: `1px solid ${tokens.inkLine}`, background: tokens.bg, color: tokens.ink, borderRadius: '3px' };
const svcLbl = { display: 'block', fontFamily: fontMono, fontSize: '8.5px', letterSpacing: '0.12em', color: tokens.inkMute, marginBottom: '4px' };
const svcToggle = (on) => ({ fontFamily: fontMono, fontSize: '9.5px', letterSpacing: '0.08em', padding: '8px 12px', cursor: 'pointer', userSelect: 'none', whiteSpace: 'nowrap', borderRadius: '3px', border: `1px solid ${on ? tokens.ink : tokens.inkLine}`, background: on ? tokens.ink : 'none', color: on ? tokens.paper : tokens.inkMute });

// ── Company drawer ───────────────────────────────────────────────────────────
// svc_company(name) → { company, enrichment|null, deals[] }. Read-only.
const SvcCompanyDrawer = ({ name, onClose, onPickInvestor }) => {
  const isMobile = useIsMobile();
  const [data, setData] = React.useState(undefined);
  const [err, setErr] = React.useState('');
  React.useEffect(() => {
    let dead = false;
    setData(undefined); setErr('');
    svcRpc('svc_company', { p_name: name })
      .then((d) => { if (!dead) setData(d || null); })
      .catch((e) => { if (!dead) { setErr(e.message); setData(null); } });
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => { dead = true; window.removeEventListener('keydown', onKey); };
  }, [name]);

  const co = data && data.company;
  const en = data && data.enrichment;
  const deals = data && Array.isArray(data.deals) ? [...data.deals].sort((a, b) => String(b.issue_date).localeCompare(String(a.issue_date))) : [];
  const sec = (t) => <div style={{ fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.14em', color: tokens.inkMute, margin: '18px 0 6px' }}>{t}</div>;
  const line = (label, v) => (v == null || v === '' || (Array.isArray(v) && !v.length)) ? null : (
    <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '110px 1fr', gap: '2px 12px', padding: '5px 0', borderBottom: `1px solid ${tokens.inkLineSoft}` }}>
      <span style={{ fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.1em', color: tokens.inkMute, paddingTop: '2px' }}>{label}</span>
      <span style={{ fontSize: '12.5px', color: tokens.inkSoft, lineHeight: 1.55 }}>{React.isValidElement(v) ? v : Array.isArray(v) ? v.join(' · ') : String(v)}</span>
    </div>
  );

  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(14,14,12,0.4)', zIndex: 220, display: 'flex', justifyContent: 'flex-end' }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: isMobile ? '100%' : 'min(760px, 92vw)', height: '100%', overflowY: 'auto', background: tokens.bg, borderLeft: `1px solid ${tokens.ink}`, boxShadow: '-20px 0 60px rgba(14,14,12,0.25)', padding: isMobile ? '20px 18px 40px' : '28px 32px 48px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: '16px' }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.16em', color: tokens.inkMute, marginBottom: '8px' }}>STRICTLYVC · COMPANY</div>
            <div style={{ fontSize: isMobile ? '24px' : '30px', letterSpacing: '-0.03em', lineHeight: 1.05, fontFamily: fontDisplay }}>{(co && co.company) || name}{en && <span title="Web-researched by Claude" style={{ color: tokens.ochre, fontSize: '18px', marginLeft: '8px' }}>✦</span>}</div>
            {co && (
              <div style={{ fontFamily: fontMono, fontSize: '10px', color: tokens.inkMute, letterSpacing: '0.04em', marginTop: '8px', lineHeight: 1.7 }}>
                {[co.sector, co.location, co.founded_year_est ? `FOUNDED ~${co.founded_year_est}` : null, co.mentions ? `${co.mentions} MENTION${co.mentions === 1 ? '' : 'S'}` : null].filter(Boolean).join(' · ').toUpperCase()}
              </div>
            )}
          </div>
          <span onClick={onClose} style={{ cursor: 'pointer', fontFamily: fontMono, fontSize: '11px', color: tokens.inkMute, border: `1px solid ${tokens.inkLine}`, padding: '6px 10px', whiteSpace: 'nowrap' }}>CLOSE ✕</span>
        </div>

        {data === undefined && <div style={{ fontFamily: fontMono, fontSize: '11px', letterSpacing: '0.1em', color: tokens.inkMute, padding: '32px 0' }}>LOADING…</div>}
        {err && <div style={{ fontFamily: fontMono, fontSize: '11px', color: tokens.red, padding: '24px 0' }}>{err}</div>}

        {co && (
          <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', marginTop: '18px' }}>
            {_svcMoney(co.total_raised_musd) && <SvcStat label="TOTAL RAISED" value={_svcMoney(co.total_raised_musd)} />}
            {_svcMoney(co.latest_valuation_musd) && <SvcStat label="LATEST VALUATION" value={_svcMoney(co.latest_valuation_musd)} />}
            {_svcMoney(co.largest_round_musd) && <SvcStat label="LARGEST ROUND" value={_svcMoney(co.largest_round_musd)} />}
            {co.latest_lead && <SvcStat label="LATEST LEAD" value={<span style={{ fontSize: '14px' }}>{co.latest_lead}</span>} />}
          </div>
        )}

        {en && (
          <React.Fragment>
            {sec('RESEARCH')}
            {en.product_summary && <p style={{ fontSize: '14px', lineHeight: 1.6, color: tokens.ink, margin: '0 0 10px' }}>{en.product_summary}</p>}
            {line('WEBSITE', en.website ? <a href={/^https?:/.test(en.website) ? en.website : `https://${en.website}`} target="_blank" rel="noopener noreferrer" style={{ color: tokens.ink, textDecoration: 'underline' }}>{en.website}</a> : null)}
            {line('HQ', en.hq)}
            {line('FOUNDED', en.founded_year)}
            {line('CEO', en.ceo)}
            {line('FOUNDERS', en.founders)}
            {line('EMPLOYEES', en.employees_est ? `~${_svcInt(en.employees_est)}` : null)}
            {line('TRACTION', en.traction)}
            {line('CUSTOMERS', en.customers)}
            {line('COMPETITORS', en.competitors)}
            {line('INVESTOR NOTE', en.investor_note)}
            {line('RISKS', en.risks)}
            {Array.isArray(en.sources) && en.sources.length > 0 && (
              <div style={{ padding: '6px 0' }}>
                <span style={svcLbl}>SOURCES</span>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px' }}>
                  {en.sources.slice(0, 8).map((s, i) => {
                    const url = typeof s === 'string' ? s : (s && (s.url || s.href));
                    const label = typeof s === 'string' ? s.replace(/^https?:\/\/(www\.)?/, '').slice(0, 40) : ((s && (s.title || s.name)) || String(url || '').replace(/^https?:\/\/(www\.)?/, '').slice(0, 40));
                    return url ? <a key={i} href={url} target="_blank" rel="noopener noreferrer" style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute, border: `1px solid ${tokens.inkLine}`, padding: '2px 7px', textDecoration: 'none' }}>{label} ↗</a> : null;
                  })}
                </div>
              </div>
            )}
            <div style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute, marginTop: '10px', lineHeight: 1.6 }}>
              Web research by Claude — verify before relying on it.{en.confidence != null ? ` Confidence ${typeof en.confidence === 'number' ? Math.round(en.confidence * (en.confidence <= 1 ? 100 : 1)) + '%' : en.confidence}.` : ''}{en.enriched_at ? ` Researched ${new Date(en.enriched_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}.` : ''}
            </div>
          </React.Fragment>
        )}

        {data && (
          <React.Fragment>
            {sec(`DEALS IN THE LEDGER · ${deals.length}`)}
            {deals.length === 0 && <div style={{ fontSize: '12.5px', color: tokens.inkMute }}>No deal rows found for this company.</div>}
            {deals.map((d) => {
              const t = _svcTier(d.tier);
              const isExit = d.entry_type === 'exit';
              const prev = new Set(d.previous_investors || []);
              const amount = isExit ? _svcMoney(d.deal_value_musd, d.currency) : (d.amount_undisclosed ? 'undisclosed' : _svcMoney(d.amount_musd, d.currency));
              return (
                <div key={d.uid} style={{ border: `1px solid ${tokens.inkLine}`, background: tokens.paper, padding: '12px 14px', marginBottom: '8px' }}>
                  <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
                    <span style={{ fontFamily: fontMono, fontSize: '10px', color: tokens.inkMute }}>{_svcDate(d.issue_date)}</span>
                    <SvcPill text={t.label} color={t.color} />
                    {d.status === 'reported' && <SvcPill text="REPORTED" color={tokens.ochre} title="Rumoured, not confirmed" />}
                    {d.round && <span style={{ fontFamily: fontMono, fontSize: '10px', color: tokens.inkSoft }}>{d.round}</span>}
                    {isExit && d.acquirer && <span style={{ fontSize: '12.5px', color: tokens.ink }}>{d.acquirer} → {d.company}</span>}
                    <span style={{ marginLeft: 'auto', fontFamily: fontMono, fontSize: '12px', color: tokens.ink }}>{amount || '—'}</span>
                    {_svcMoney(d.valuation_musd, d.currency) && <span style={{ fontFamily: fontMono, fontSize: '10px', color: tokens.inkMute }}>at {_svcMoney(d.valuation_musd, d.currency)}{d.valuation_type ? ` ${d.valuation_type}` : ''}</span>}
                  </div>
                  {d.description && <div style={{ fontSize: '12.5px', color: tokens.inkSoft, lineHeight: 1.55, marginTop: '6px' }}>{d.description}</div>}
                  {((d.lead_investors || []).length > 0 || (d.other_investors || []).length > 0) && (
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '5px', marginTop: '8px' }}>
                      {(d.lead_investors || []).map((n) => <SvcInvestor key={`l-${n}`} name={n} lead returning={prev.has(n)} onPick={onPickInvestor} />)}
                      {(d.other_investors || []).map((n) => <SvcInvestor key={`o-${n}`} name={n} returning={prev.has(n)} onPick={onPickInvestor} />)}
                    </div>
                  )}
                  {d.raw_text && <div style={{ fontSize: '11.5px', color: tokens.inkMute, lineHeight: 1.55, marginTop: '8px', fontStyle: 'italic', borderLeft: `2px solid ${tokens.inkLine}`, paddingLeft: '10px' }}>{d.raw_text}</div>}
                  {d.source_url && <div style={{ marginTop: '6px' }}><a href={d.source_url} target="_blank" rel="noopener noreferrer" style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute, textDecoration: 'underline' }}>{d.source_name || 'source'} ↗</a></div>}
                </div>
              );
            })}
          </React.Fragment>
        )}
      </div>
    </div>
  );
};

// ── The panel ────────────────────────────────────────────────────────────────
const SVC_BLANK = { q: '', sector: '', tier: '', round: '', investor: '', location: '', from: '', to: '', ai: false, min: '', order: 'date' };
const SVC_PAGE = 50;

const StrictlyVCPanel = () => {
  const isMobile = useIsMobile();
  const [stats, setStats] = React.useState(undefined);
  const [facets, setFacets] = React.useState(null);
  const [enriched, setEnriched] = React.useState(() => new Set());
  const [f, setF] = React.useState(SVC_BLANK);
  const [rows, setRows] = React.useState(undefined);   // undefined = loading
  const [more, setMore] = React.useState(false);
  const [loadingMore, setLoadingMore] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [openCo, setOpenCo] = React.useState(null);
  const [showFilters, setShowFilters] = React.useState(!isMobile);
  const reqRef = React.useRef(0);
  const set = (k, v) => setF((p) => ({ ...p, [k]: v }));

  React.useEffect(() => {
    svcStats().then(setStats);
    svcFacets().then(setFacets);
    svcEnriched().then(setEnriched);
  }, []);

  const params = React.useCallback((offset) => {
    const p = { p_limit: SVC_PAGE, p_offset: offset, p_order: f.order };
    if (f.q.trim()) p.q = f.q.trim();
    if (f.sector) p.p_sector = f.sector;
    if (f.tier) p.p_tier = f.tier;
    if (f.round) p.p_round = f.round;
    if (f.investor.trim()) p.p_investor = f.investor.trim();
    if (f.location.trim()) p.p_location = f.location.trim();
    if (f.from) p.p_from = f.from;
    if (f.to) p.p_to = f.to;
    if (f.ai) p.p_ai_native = true;
    if (f.min !== '' && isFinite(Number(f.min))) p.p_min_amount = Number(f.min);
    return p;
  }, [f]);

  // Debounced search — every filter change re-queries from offset 0; stale
  // responses are dropped via the request counter.
  React.useEffect(() => {
    const id = ++reqRef.current;
    setErr('');
    const t = setTimeout(async () => {
      try {
        const data = await svcRpc('svc_search_deals', params(0));
        if (reqRef.current !== id) return;
        const list = Array.isArray(data) ? data : [];
        setRows(list); setMore(list.length >= SVC_PAGE);
      } catch (e) { if (reqRef.current === id) { setErr(e.message); setRows([]); setMore(false); } }
    }, 300);
    return () => clearTimeout(t);
  }, [params]);

  const loadMore = async () => {
    setLoadingMore(true);
    try {
      const data = await svcRpc('svc_search_deals', params((rows || []).length));
      const list = Array.isArray(data) ? data : [];
      setRows((prev) => [...(prev || []), ...list]); setMore(list.length >= SVC_PAGE);
    } catch (e) { setErr(e.message); }
    setLoadingMore(false);
  };

  const active = Object.keys(SVC_BLANK).filter((k) => k !== 'order' && f[k] !== SVC_BLANK[k]);
  const pickInvestor = (name) => { setOpenCo(null); setF((p) => ({ ...p, investor: name })); setShowFilters(true); };
  const sectors = (facets && facets.sectors) || [];
  const rounds = (facets && facets.rounds) || [];
  const topLeads = (facets && facets.top_lead_investors) || [];
  const topLocs = (facets && facets.top_locations) || [];

  // Columns collapse on narrow screens; the table scrolls in its own box.
  const cols = isMobile
    ? [['DATE', 76], ['COMPANY', 220], ['AMOUNT', 90]]
    : [['DATE', 78], ['COMPANY', 300], ['TIER', 82], ['ROUND', 90], ['AMOUNT', 96], ['VALUATION', 110], ['LEAD', 170], ['SECTOR', 160], ['LOCATION', 130]];
  const th = (t, i) => <th key={t} style={{ textAlign: ['AMOUNT', 'VALUATION'].includes(t) ? 'right' : 'left', fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.1em', color: tokens.inkMute, fontWeight: 400, padding: '6px 8px', borderBottom: `1px solid ${tokens.inkLine}`, whiteSpace: 'nowrap', minWidth: `${cols[i][1]}px` }}>{t}</th>;
  const td = (v, right, style) => <td style={{ textAlign: right ? 'right' : 'left', fontFamily: fontMono, fontSize: '11px', color: tokens.inkSoft, padding: '9px 8px', borderBottom: `1px solid ${tokens.inkLineSoft}`, verticalAlign: 'top', whiteSpace: 'nowrap', ...style }}>{v}</td>;

  return (
    <IntelShell collapseKey="strictlyvc" title="STRICTLYVC DEALS · VENTURE LEDGER"
      right={stats && stats.last_issue ? `UPDATED ${String(stats.last_issue).toUpperCase()}` : ''}>
      <div style={{ padding: '16px 20px' }}>

        {/* headline numbers */}
        {stats && (
          <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', marginBottom: '16px' }}>
            <SvcStat label="FUNDING ROUNDS" value={_svcInt(stats.funding_rounds)} />
            <SvcStat label="COMPANIES" value={_svcInt(stats.companies)} />
            <SvcStat label="RESEARCHED ✦" value={_svcInt(stats.enriched_companies)} sub="web-enriched" />
            <SvcStat label="NEWSLETTERS" value={_svcInt(stats.issues)} sub={stats.first_issue ? `SINCE ${_svcDate(stats.first_issue).toUpperCase()}` : null} />
          </div>
        )}

        {/* search + primary toggles */}
        <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', alignItems: 'stretch' }}>
          <input value={f.q} onChange={(e) => set('q', e.target.value)} placeholder="Search companies, investors, sectors, tags, locations…"
            style={{ ...svcInp, flex: '1 1 260px', fontSize: '13px', fontFamily: 'inherit', padding: '10px 12px' }} />
          <span onClick={() => set('order', f.order === 'date' ? 'amount' : 'date')} style={svcToggle(false)} title="Sort order">{f.order === 'date' ? '↓ NEWEST' : '↓ LARGEST'}</span>
          <span onClick={() => set('ai', !f.ai)} style={svcToggle(f.ai)} title="Only AI-native companies">◆ AI-NATIVE</span>
          <span onClick={() => setShowFilters((s) => !s)} style={svcToggle(showFilters)}>FILTERS{active.length ? ` · ${active.length}` : ''}</span>
        </div>

        {/* filters */}
        {showFilters && (
          <div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr 1fr' : 'repeat(4, minmax(0, 1fr))', gap: '10px 12px', marginTop: '12px', padding: '12px 14px', border: `1px solid ${tokens.inkLine}`, background: tokens.bg }}>
            <div><label style={svcLbl}>SECTOR</label>
              <select style={svcInp} value={f.sector} onChange={(e) => set('sector', e.target.value)}>
                <option value="">All sectors</option>
                {sectors.map((s) => <option key={s.name} value={s.name}>{s.name}{s.n ? ` (${s.n})` : ''}</option>)}
              </select></div>
            <div><label style={svcLbl}>TIER</label>
              <select style={svcInp} value={f.tier} onChange={(e) => set('tier', e.target.value)}>
                <option value="">All tiers</option>
                {SVC_TIERS.filter((t) => t.id !== 'other_funding').map((t) => <option key={t.id} value={t.id}>{t.label.charAt(0) + t.label.slice(1).toLowerCase()}{t.id === 'massive' ? ' ($100M+)' : t.id === 'big' ? ' ($20–100M)' : ''}</option>)}
              </select></div>
            <div><label style={svcLbl}>ROUND</label>
              <select style={svcInp} value={f.round} onChange={(e) => set('round', e.target.value)}>
                <option value="">All rounds</option>
                {rounds.map((r) => <option key={r.name} value={r.name}>{r.name}{r.n ? ` (${r.n})` : ''}</option>)}
              </select></div>
            <div><label style={svcLbl}>MIN SIZE ($M)</label><input type="number" min="0" style={svcInp} value={f.min} onChange={(e) => set('min', e.target.value)} placeholder="e.g. 50" /></div>
            <div><label style={svcLbl}>INVESTOR</label><input style={svcInp} list="svc-investors" value={f.investor} onChange={(e) => set('investor', e.target.value)} placeholder="Sequoia, a16z…" />
              <datalist id="svc-investors">{topLeads.map((l) => <option key={l.name} value={l.name} />)}</datalist></div>
            <div><label style={svcLbl}>LOCATION</label><input style={svcInp} list="svc-locations" value={f.location} onChange={(e) => set('location', e.target.value)} placeholder="London, SF…" />
              <datalist id="svc-locations">{topLocs.map((l) => <option key={l.name} value={l.name} />)}</datalist></div>
            <div><label style={svcLbl}>FROM</label><input type="date" style={svcInp} value={f.from} onChange={(e) => set('from', e.target.value)} /></div>
            <div><label style={svcLbl}>TO</label><input type="date" style={svcInp} value={f.to} onChange={(e) => set('to', e.target.value)} /></div>
            {active.length > 0 && (
              <div style={{ gridColumn: '1 / -1', display: 'flex', justifyContent: 'flex-end' }}>
                <span onClick={() => setF({ ...SVC_BLANK, order: f.order })} style={{ fontFamily: fontMono, fontSize: '9.5px', letterSpacing: '0.08em', color: tokens.red, cursor: 'pointer' }}>✕ CLEAR {active.length} FILTER{active.length === 1 ? '' : 'S'}</span>
              </div>
            )}
          </div>
        )}

        {/* results */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', margin: '16px 0 4px', gap: '12px', flexWrap: 'wrap' }}>
          <span style={{ fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.14em', color: tokens.inkMute }}>
            {rows === undefined ? 'SEARCHING…' : `${rows.length}${more ? '+' : ''} DEAL${rows.length === 1 ? '' : 'S'}`}{f.investor.trim() ? ` · INVESTOR: ${f.investor.trim().toUpperCase()}` : ''}
          </span>
          <span style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute }}>CLICK A ROW FOR THE COMPANY · CLICK A LEAD TO FILTER</span>
        </div>
        {err && <div style={{ fontFamily: fontMono, fontSize: '11px', color: tokens.red, padding: '10px 0' }}>{err}</div>}
        {rows && rows.length === 0 && !err && (
          <div style={{ fontFamily: fontMono, fontSize: '11px', color: tokens.inkMute, lineHeight: 1.8, padding: '24px 4px' }}>
            No deals match.{active.length ? ' Try clearing a filter or two.' : ''}
          </div>
        )}
        {rows && rows.length > 0 && (
          <div style={{ overflowX: 'auto', minWidth: 0, WebkitOverflowScrolling: 'touch', border: `1px solid ${tokens.inkLine}`, background: tokens.paper }}>
            <table style={{ width: '100%', borderCollapse: 'collapse' }}>
              <thead><tr>{cols.map(([t], i) => th(t, i))}</tr></thead>
              <tbody>
                {rows.map((d) => {
                  const t = _svcTier(d.tier);
                  const isExit = d.entry_type === 'exit';
                  const amount = isExit ? _svcMoney(d.deal_value_musd, d.currency) : (d.amount_undisclosed ? 'undisclosed' : _svcMoney(d.amount_musd, d.currency));
                  const val = _svcMoney(d.valuation_musd, d.currency);
                  const coLeads = (d.lead_investors || []).length - 1;
                  const isEnriched = enriched.has(d.company_key);
                  const companyCell = (
                    <div style={{ minWidth: 0, maxWidth: isMobile ? '220px' : '300px', whiteSpace: 'normal' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap' }}>
                        <span style={{ fontSize: '13px', fontWeight: 500, letterSpacing: '-0.01em', color: tokens.ink, fontFamily: 'inherit' }}>{isExit && d.acquirer ? <span><span style={{ color: tokens.inkSoft }}>{d.acquirer}</span> → {d.company}</span> : d.company}</span>
                        {isEnriched && <span title="Web-researched — open for details" style={{ color: tokens.ochre, fontSize: '11px' }}>✦</span>}
                        {d.status === 'reported' && <SvcPill text="REPORTED" color={tokens.ochre} title="Rumoured, not confirmed" />}
                        {d.ai_native && !isMobile && <SvcPill text="AI" color={tokens.inkMute} title="AI-native" />}
                      </div>
                      {d.description && <div style={{ fontSize: '11.5px', color: tokens.inkSoft, lineHeight: 1.45, marginTop: '3px', fontFamily: 'inherit', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{d.description}</div>}
                      {isMobile && <div style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute, marginTop: '3px' }}>{[t.label, d.round, d.lead_left, d.sector].filter(Boolean).join(' · ')}</div>}
                    </div>
                  );
                  return (
                    <tr key={d.uid} onClick={() => setOpenCo(d.company)} className="case-row" style={{ cursor: 'pointer' }}>
                      {td(_svcDate(d.issue_date), 0, { color: tokens.inkMute, fontSize: '10px' })}
                      {td(companyCell, 0, { whiteSpace: 'normal' })}
                      {!isMobile && td(<SvcPill text={t.label} color={t.color} />)}
                      {!isMobile && td(d.round || (isExit ? 'ACQ.' : d.entry_type === 'ipo' ? 'IPO' : d.entry_type === 'new_fund' ? 'FUND' : '—'), 0, { fontSize: '10px' })}
                      {td(amount || '—', 1, { color: tokens.ink, fontSize: '12px' })}
                      {!isMobile && td(val ? <span>{val}<span style={{ color: tokens.inkMute, fontSize: '9px' }}>{d.valuation_type ? ` ${d.valuation_type}` : ''}</span></span> : '—', 1)}
                      {!isMobile && td(d.lead_left ? (
                        <span style={{ display: 'inline-flex', alignItems: 'center', gap: '6px' }}>
                          <SvcInvestor name={d.lead_left} lead onPick={pickInvestor} />
                          {coLeads > 0 && <span style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute }}>+{coLeads} co-lead</span>}
                        </span>
                      ) : '—')}
                      {!isMobile && td(d.sector || '—', 0, { fontSize: '10px', whiteSpace: 'normal', maxWidth: '160px' })}
                      {!isMobile && td(d.location || '—', 0, { fontSize: '10px', color: tokens.inkMute })}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
        {more && rows && rows.length > 0 && (
          <div style={{ display: 'flex', justifyContent: 'center', marginTop: '12px' }}>
            <button onClick={loadMore} disabled={loadingMore} style={{ fontFamily: fontMono, fontSize: '10px', letterSpacing: '0.1em', padding: '8px 18px', background: 'none', color: loadingMore ? tokens.inkMute : tokens.ink, border: `1px solid ${tokens.inkLine}`, cursor: loadingMore ? 'default' : 'pointer' }}>{loadingMore ? 'LOADING…' : `LOAD ${SVC_PAGE} MORE`}</button>
          </div>
        )}

        <div style={{ fontFamily: fontMono, fontSize: '9px', color: tokens.inkMute, marginTop: '16px', lineHeight: 1.65 }}>
          Parsed from every StrictlyVC newsletter and classified by Claude; amounts as reported (REPORTED = rumour), founding year estimated from “N-year-old” wording, same-name companies merged. ✦ companies carry web research that can be stale. Coverage: Oct 2025 → today complete; Jan 2024 – Jul 2025 back-filling; mid-Jul → Oct 2025 not in the inbox.
        </div>
      </div>

      {openCo && <SvcCompanyDrawer name={openCo} onClose={() => setOpenCo(null)} onPickInvestor={pickInvestor} />}
    </IntelShell>
  );
};

// Collapsible section header, same shape as the VIC module's.
const StrictlyVCSection = () => {
  const [collapsed, toggle] = useCollapsed('section.strictlyvc');
  return (
    <div>
      <div onClick={toggle} style={{ display: 'flex', alignItems: 'center', gap: '6px', marginBottom: collapsed ? '0' : '8px', cursor: 'pointer', userSelect: 'none' }}>
        <Chevron collapsed={collapsed} onClick={(e) => { e.stopPropagation(); toggle(); }} size={13} />
        <span style={{ fontFamily: fontMono, fontSize: '11px', letterSpacing: '0.18em', color: tokens.inkMute }}>STRICTLYVC DEALS</span>
        <span style={{ fontFamily: fontMono, fontSize: '9px', letterSpacing: '0.1em', color: tokens.inkMute, border: `1px solid ${tokens.inkLine}`, padding: '1px 6px' }}>READ-ONLY</span>
      </div>
      {!collapsed && <StrictlyVCPanel />}
    </div>
  );
};

window.StrictlyVCPanel = StrictlyVCPanel;
window.StrictlyVCSection = StrictlyVCSection;
