// Sponsors list + Sponsor detail
const { useState: useS_S, useEffect: useE_S, useMemo: useM_S } = React;

function SponsorsListPage({ navigate }) {
  const [data, setData] = useS_S(null);
  const [sort, setSort] = useS_S('total_raised');
  const [search, setSearch] = useS_S('');
  const [searchResults, setSearchResults] = useS_S(null);
  const [page, setPage] = useS_S(0);
  const limit = 50;

  useE_S(() => {
    setData(null);
    window.api(`/api/sponsors?limit=${limit}&offset=${page * limit}&sort=${sort}`)
      .then(r => setData(r.results));
  }, [sort, page]);

  useE_S(() => {
    if (!search.trim()) { setSearchResults(null); return; }
    let cancel = false;
    const t = setTimeout(() => {
      window.api('/api/search?q=' + encodeURIComponent(search.trim()))
        .then(r => { if (!cancel) setSearchResults(r); });
    }, 250);
    return () => { cancel = true; clearTimeout(t); };
  }, [search]);

  const rows = searchResults ? searchResults.sponsors : data;
  const maxRaised = useM_S(() => rows && rows.length ? Math.max(...rows.map(r => r.total_raised || 0)) : 1, [rows]);

  return (
    <>
      <div className="page-head">
        <div>
          <h1>Sponsors</h1>
          <p>6,056 deduplicated GPs — clusters of SPVs joined by shared phone, address & filer signals.</p>
        </div>
        <div className="page-head-actions">
          <span style={{ fontSize: 12, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
            {rows ? `${rows.length.toLocaleString()} shown` : '—'}
          </span>
        </div>
      </div>

      <div className="filter-bar">
        <div className="search">
          <span className="search-icon"><I.search /></span>
          <input type="text" placeholder="Search sponsors by name or alias…" value={search}
                 onChange={(e) => setSearch(e.target.value)} />
        </div>
        <div style={{ flex: 1 }}></div>
        <div className="sort-bar">
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Sort</span>
          <button className={`sort-btn ${sort === 'total_raised' ? 'active' : ''}`} onClick={() => { setSort('total_raised'); setPage(0); }}>
            Capital raised {sort === 'total_raised' && <I.desc />}
          </button>
          <button className={`sort-btn ${sort === 'deals_count' ? 'active' : ''}`} onClick={() => { setSort('deals_count'); setPage(0); }}>
            Deal count {sort === 'deals_count' && <I.desc />}
          </button>
        </div>
      </div>

      <div className="deal-table">
        <div className="dt-head" style={{ gridTemplateColumns: '40px minmax(0, 2.4fr) 130px 90px 1fr 110px' }}>
          <div>#</div>
          <div>Sponsor</div>
          <div style={{ textAlign: 'right' }}>Lifetime raised</div>
          <div style={{ textAlign: 'right' }}>Deals</div>
          <div>Aliases</div>
          <div>Recent</div>
        </div>
        {!rows && Array.from({ length: 12 }).map((_, i) => (
          <div className="dt-row" key={i} style={{ gridTemplateColumns: '40px minmax(0, 2.4fr) 130px 90px 1fr 110px' }}>
            <div className="skel" style={{ height: 10, width: 18 }}></div>
            <div className="dt-name">
              <div className="skel" style={{ height: 14, width: '50%' }}></div>
              <div className="skel" style={{ height: 10, width: '30%', marginTop: 4 }}></div>
            </div>
            <div className="skel" style={{ height: 12, width: 60, marginLeft: 'auto' }}></div>
            <div className="skel" style={{ height: 12, width: 30, marginLeft: 'auto' }}></div>
            <div className="skel" style={{ height: 10, width: '60%' }}></div>
            <div className="skel" style={{ height: 12, width: 60 }}></div>
          </div>
        ))}
        {rows && rows.length === 0 && <div className="empty">No sponsors match.</div>}
        {rows && rows.map((s, i) => <SponsorRow key={s.sponsor_id} s={s} idx={(page * limit) + i + 1} navigate={navigate} maxRaised={maxRaised} />)}

        {!searchResults && rows && (
          <div className="pager">
            <span>Page {page + 1} · showing {page * limit + 1}–{page * limit + rows.length}</span>
            <div className="pager-controls">
              <button className="btn" disabled={page === 0} onClick={() => setPage(p => Math.max(0, p - 1))}><I.chevL /> Prev</button>
              <button className="btn" onClick={() => setPage(p => p + 1)}>Next <I.chevR /></button>
            </div>
          </div>
        )}
      </div>
    </>
  );
}

function SponsorRow({ s, idx, navigate, maxRaised }) {
  const aliases = window.parseAliases(s.aliases);
  const aliasPreview = aliases.slice(0, 2).join(' · ') + (aliases.length > 2 ? ` · +${aliases.length - 2} more` : '');
  const pct = maxRaised ? (s.total_raised || 0) / maxRaised : 0;
  return (
    <div className="dt-row" onClick={() => navigate({ name: 'sponsor', id: s.sponsor_id })}
         style={{ gridTemplateColumns: '40px minmax(0, 2.4fr) 130px 90px 1fr 110px' }}>
      <div className="mono" style={{ fontSize: 11, color: 'var(--ink-4)' }}>{String(idx).padStart(3, '0')}</div>
      <div className="dt-name">
        <div className="dt-name-main">{s.canonical_name}</div>
        <div className="dt-name-sub">
          <I.tag />
          {window.industryShort(s.industry_group_type)}{s.primary_city ? ` · ${s.primary_city}, ${s.primary_state_or_country || ''}`.replace(/, $/, '') : ''}
        </div>
      </div>
      <div style={{ textAlign: 'right', position: 'relative' }}>
        <div className="dt-amount">{window.fmtMoney(s.total_raised)}</div>
        <div style={{ height: 3, background: 'var(--bg-sunk)', borderRadius: 2, marginTop: 4, overflow: 'hidden' }}>
          <div style={{ height: '100%', width: `${pct * 100}%`, background: 'var(--accent)' }}></div>
        </div>
      </div>
      <div className="mono" style={{ textAlign: 'right', fontSize: 13, fontWeight: 500 }}>
        {s.deals_count}
      </div>
      <div style={{ fontSize: 11, color: 'var(--ink-4)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontFamily: 'var(--font-mono)' }}>
        {aliasPreview || '—'}
      </div>
      <div className="dt-date">
        {s.latest_filing_date ? window.relTime(s.latest_filing_date) : '—'}
      </div>
    </div>
  );
}

// ===== Sponsor detail =====

function SponsorDetailPage({ id, navigate }) {
  const [data, setData] = useS_S(null);
  useE_S(() => {
    setData(null);
    window.api('/api/sponsors/' + id).then(setData);
  }, [id]);

  const signals = data?.signals;
  const deals = data?.deals;

  // Hooks must run unconditionally — compute these BEFORE early return
  const groupedSignals = useM_S(() => {
    const map = new Map();
    (signals || []).forEach(s => {
      const key = `${s.signal_type}|${s.signal_value}`;
      if (!map.has(key)) map.set(key, { signal_type: s.signal_type, signal_value: s.signal_value, deals: new Set() });
      map.get(key).deals.add(s.deal_id);
    });
    return Array.from(map.values()).sort((a, b) => b.deals.size - a.deals.size);
  }, [signals]);

  const dealMap = useM_S(() => {
    const m = new Map();
    (deals || []).forEach(d => m.set(d.deal_id, d));
    return m;
  }, [deals]);

  if (!data) return <DealDetailSkeleton />;

  const { sponsor } = data;
  const aliases = window.parseAliases(sponsor.aliases);
  const sortedDeals = [...(deals || [])].sort((a, b) => (b.total_raised || 0) - (a.total_raised || 0));
  const totalInvestors = (deals || []).reduce((acc, d) => acc + (d.total_investors || 0), 0);
  const firstYear = sponsor.first_filing_date ? new Date(sponsor.first_filing_date).getFullYear() : '—';
  const latestYear = sponsor.latest_filing_date ? new Date(sponsor.latest_filing_date).getFullYear() : '—';

  // Bar chart of deals by raise
  const chartMax = Math.max(...sortedDeals.map(d => d.total_raised || 0), 1);

  return (
    <>
      <div className="crumb">
        <a href="#/sponsors" onClick={(e) => { e.preventDefault(); navigate({ name: 'sponsors' }); }}>Sponsors</a>
        <span className="crumb-sep">/</span>
        <span style={{ color: 'var(--ink-2)' }}>{sponsor.canonical_name}</span>
      </div>

      <div className="detail-head">
        <div>
          <h1 className="detail-title">{sponsor.canonical_name}</h1>
          <div className="detail-meta">
            <span className="detail-meta-item">
              <I.tag /> {window.industryShort(sponsor.industry_group_type)}
            </span>
            <span className="detail-meta-item">
              <I.phone /> {window.fmtPhoneSignal(sponsor.primary_phone_normalized) || '—'}
            </span>
            <span className="detail-meta-item">
              <I.layers /> {sponsor.deals_count} attributed SPVs · active {firstYear}–{latestYear}
            </span>
          </div>
        </div>
      </div>

      {/* Headline metrics */}
      <div className="metric-strip">
        <div className="metric-cell">
          <div className="metric-label">Lifetime raised</div>
          <div className="metric-value">{window.fmtMoneyFull(sponsor.total_raised)}</div>
          <div className="metric-sub">across {sponsor.deals_count} deals</div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Avg. deal size</div>
          <div className="metric-value">{window.fmtMoney((sponsor.total_raised || 0) / Math.max(sponsor.deals_count, 1))}</div>
          <div className="metric-sub">{sponsor.deals_count > 1 ? `Range ${window.fmtMoney(Math.min(...sortedDeals.map(d => d.total_raised || 0)))}–${window.fmtMoney(chartMax)}` : ''}</div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Investors seen</div>
          <div className="metric-value">{(sponsor.total_investors_seen || totalInvestors || 0).toLocaleString()}</div>
          <div className="metric-sub">across all SPVs</div>
        </div>
        <div className="metric-cell">
          <div className="metric-label">Most recent</div>
          <div className="metric-value" style={{ fontSize: 18 }}>{window.fmtDate(sponsor.latest_filing_date)}</div>
          <div className="metric-sub">{window.relTime(sponsor.latest_filing_date)}</div>
        </div>
      </div>

      {/* Deals list */}
      <div className="card" style={{ marginBottom: 24 }}>
        <div className="card-header">
          <h3>Attributed deals</h3>
          <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
            {sortedDeals.length} SPVS · BY RAISE
          </span>
        </div>
        <div>
          {sortedDeals.map((d, i) => (
            <div key={d.deal_id} onClick={() => navigate({ name: 'deal', id: d.deal_id })}
                 style={{ display: 'grid', gridTemplateColumns: '36px 1fr 200px 130px 110px', gap: 16,
                          padding: '14px 18px', borderBottom: '1px solid var(--line)', alignItems: 'center', cursor: 'pointer' }}
                 onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-sunk)'}
                 onMouseLeave={(e) => e.currentTarget.style.background = ''}>
              <span className="mono" style={{ fontSize: 11, color: 'var(--ink-4)' }}>{String(i + 1).padStart(2, '0')}</span>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 500 }}>{d.deal_name}</div>
                <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 2 }}>
                  {d.filings_count} filing{d.filings_count > 1 ? 's' : ''} · {window.fmtDate(d.first_filing_date)} → {window.fmtDate(d.latest_filing_date)}
                </div>
              </div>
              <div style={{ height: 6, background: 'var(--bg-sunk)', borderRadius: 3, overflow: 'hidden' }}>
                <div style={{ height: '100%', width: `${((d.total_raised || 0) / chartMax) * 100}%`, background: 'var(--accent)' }}></div>
              </div>
              <div className="mono" style={{ textAlign: 'right', fontSize: 14, fontWeight: 500 }}>
                {d.total_raised ? window.fmtMoneyFull(d.total_raised) : '—'}
                {d.target_is_indefinite ? (
                  <div style={{ fontSize: 10, color: 'var(--ink-4)', fontWeight: 400, marginTop: 2, fontStyle: 'italic' }}>of Indefinite</div>
                ) : d.target_offering_amount ? (
                  <div style={{ fontSize: 10, color: 'var(--ink-4)', fontWeight: 400, marginTop: 2 }}>
                    of {window.fmtMoney(d.target_offering_amount)}
                    {d.total_raised ? ` · ${Math.round((d.total_raised / d.target_offering_amount) * 100)}%` : ''}
                  </div>
                ) : null}
              </div>
              <div className="dt-status">
                <span className={`status-dot ${d.is_open ? 'open' : 'closed'}`}></span>
                {d.is_open ? 'Active' : 'Closed'}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Aliases */}
      {aliases.length > 0 && (
        <div className="card" style={{ marginBottom: 24 }}>
          <div className="card-header">
            <h3>Filed under {aliases.length} different name{aliases.length > 1 ? 's' : ''}</h3>
            <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>SPV legal names</span>
          </div>
          <div className="aliases-row">
            {aliases.map((a, i) => <span className="alias-chip" key={i}>{a}</span>)}
          </div>
        </div>
      )}

      {/* Evidence trail */}
      {groupedSignals.length > 0 && (
        <div className="card" style={{ marginBottom: 24 }}>
          <div className="card-header">
            <h3>Evidence trail</h3>
            <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--font-mono)' }}>
              WHY THESE SPVS = ONE SPONSOR
            </span>
          </div>
          <div style={{ padding: '14px 18px 0', fontSize: 13, color: 'var(--ink-3)', lineHeight: 1.6 }}>
            We rolled {sponsor.deals_count} separate SPVs into <strong style={{ color: 'var(--ink) '}}>{sponsor.canonical_name}</strong> because they share these signals. Each card lists the matching deals.
          </div>
          <div className="evidence-grid">
            {groupedSignals.map((sig, i) => {
              const dealList = Array.from(sig.deals).map(id => dealMap.get(id)).filter(Boolean);
              return (
                <div className="evidence-card" key={i}>
                  <div className="evidence-header">
                    <span className="evidence-type">
                      {sig.signal_type === 'phone' ? <><I.phone style={{ verticalAlign: -2 }}/> Shared phone</> :
                       sig.signal_type === 'address' ? <><I.pin style={{ verticalAlign: -2 }}/> Shared address</> :
                       sig.signal_type}
                    </span>
                    <span className="evidence-count">{sig.deals.size} deals</span>
                  </div>
                  <div className="evidence-value">
                    {sig.signal_type === 'phone' ? window.fmtPhoneSignal(sig.signal_value) :
                     sig.signal_type === 'address' ? window.fmtAddressSignal(sig.signal_value) :
                     sig.signal_value}
                  </div>
                  <div className="evidence-deals">
                    {dealList.slice(0, 5).map(d => (
                      <div className="evidence-deal" key={d.deal_id}
                           onClick={(e) => { e.stopPropagation(); navigate({ name: 'deal', id: d.deal_id }); }}
                           style={{ cursor: 'pointer' }}>
                        {d.deal_name}
                      </div>
                    ))}
                    {dealList.length > 5 && <div className="evidence-deal" style={{ opacity: 0.6 }}>+{dealList.length - 5} more</div>}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </>
  );
}

window.SponsorsListPage = SponsorsListPage;
window.SponsorDetailPage = SponsorDetailPage;
