/* ============================================================
   Screen 3 — Competitor Activity ("who's doing what")
   Screen 4 — Advisors ("follow the smart money")
   ============================================================ */

const ROLE_LABEL = { total: 'Total', platform: 'Platform', exit: 'Exit', bnb: 'Buy-and-build' };
const ROLE_HINT = { platform: 'as buyer', exit: 'as seller', bnb: 'as financer' };
function roleTest(d, id, role) {
  if (role === 'platform') return d.buyerCompId === id;
  if (role === 'exit') return d.sellerCompId === id;
  if (role === 'bnb') return d.financerCompId === id;
  return d.involvedCompIds.includes(id);
}
const DEFAULT_COMPS = ['pride', 'vortex', 'main', 'holland'];

/* ---------------- Competitor Activity ---------------- */
function CompetitorActivity({ deals, filters, openDrawer }) {
  const [selected, setSelected] = useState(DEFAULT_COMPS);
  const [expanded, setExpanded] = useState(null);

  useEffect(() => {
    if (filters.tier !== 'all') {
      const ids = DATA.competitors.filter((c) => c.tier === filters.tier).slice(0, 6).map((c) => c.id);
      setSelected(ids);
    }
  }, [filters.tier]);

  const toggle = (id) => setSelected((s) => s.includes(id) ? s.filter((x) => x !== id) : [...s, id]);
  const selComps = DATA.competitors.filter((c) => selected.includes(c.id));

  const cell = (id, role) => deals.filter((d) => roleTest(d, id, role));
  const totalCell = (role) => deals.filter((d) => selected.some((id) => roleTest(d, id, role)));

  // stacked bar by deal type per quarter (selected comps)
  const chrono = chronoQuarters(filters);
  const typeData = chrono.map((q) => {
    const dq = deals.filter((d) => d.quarter === q);
    return {
      label: qLabel(q), q,
      platform: dq.filter((d) => selected.some((id) => d.buyerCompId === id)).length,
      exit: dq.filter((d) => selected.some((id) => d.sellerCompId === id)).length,
      bnb: dq.filter((d) => selected.some((id) => d.financerCompId === id)).length,
    };
  });

  return (
    <div className="screen-in">
      <PageHead icon="layers" title="Competitor Activity" />

      {/* competitor pills */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginBottom: 16, padding: '11px 13px', background: 'var(--surface-warm)', borderRadius: 10, border: '1px solid var(--line)' }}>
        <span className="micro" style={{ marginRight: 2 }}>Competitors</span>
        {DATA.competitors.map((c) => {
          const on = selected.includes(c.id);
          return (
            <button key={c.id} onClick={() => toggle(c.id)} title={DATA.tierLabel(c.tier)}
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 6, height: 27, padding: '0 10px', borderRadius: 20,
                fontSize: 11.5, fontWeight: 600, cursor: 'pointer', transition: 'all .12s',
                border: '1px solid ' + (on ? 'var(--accent)' : 'var(--line)'),
                background: on ? 'var(--accent)' : 'var(--surface-card)', color: on ? '#fff' : 'var(--ink-muted)',
              }}>
              <span style={{ width: 6, height: 6, borderRadius: 9, background: on ? 'rgba(255,255,255,.7)' : (c.tier === 'core' ? 'var(--accent)' : c.tier === 'buyout' ? '#86a0ad' : '#c4b58c') }}></span>
              {c.name}
            </button>
          );
        })}
      </div>

      <div className="card" style={{ overflow: 'hidden', marginBottom: 16 }}>
            <table className="tbl">
              <thead>
                <tr>
                  <th style={{ width: 220 }}>Competitor</th>
                  {['total', 'platform', 'exit', 'bnb'].map((r) => (
                    <th key={r} className="num" style={{ textAlign: 'right' }}>
                      {ROLE_LABEL[r]}{ROLE_HINT[r] && <span style={{ display: 'block', fontWeight: 500, textTransform: 'none', letterSpacing: 0, color: 'var(--ink-faint)', fontSize: 10 }}>{ROLE_HINT[r]}</span>}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {/* total row */}
                <tr style={{ background: 'var(--surface-deep)' }}>
                  <td style={{ fontWeight: 700 }}>All selected ({selComps.length})</td>
                  {['total', 'platform', 'exit', 'bnb'].map((r) => {
                    const set = totalCell(r);
                    return <td key={r} className="num"><MatrixCell n={set.length} bold onClick={() => set.length && openDrawer(`All selected · ${ROLE_LABEL[r]}`, 'Across selected competitors', set)} /></td>;
                  })}
                </tr>
                {selComps.map((c) => (
                  <React.Fragment key={c.id}>
                    <tr className="clickable" onClick={() => setExpanded((e) => e === c.id ? null : c.id)} style={expanded === c.id ? { background: 'var(--accent-soft)' } : null}>
                      <td>
                        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                          <Icon name={expanded === c.id ? 'chevronDown' : 'chevronRight'} size={13} style={{ color: 'var(--ink-faint)' }} />
                          <span style={{ fontWeight: 600 }}>{c.name}</span>
                          <TierTag tier={c.tier} />
                        </span>
                      </td>
                      {['total', 'platform', 'exit', 'bnb'].map((r) => {
                        const set = cell(c.id, r);
                        return <td key={r} className="num"><MatrixCell n={set.length} onClick={(e) => { e.stopPropagation(); set.length && openDrawer(`${c.name} · ${ROLE_LABEL[r]}`, ROLE_HINT[r] ? 'Deals where ' + c.name + ' acted ' + ROLE_HINT[r] : 'All involvement', set); }} /></td>;
                      })}
                    </tr>
                    {expanded === c.id && (
                      <tr><td colSpan={5} style={{ padding: 0, background: 'var(--surface)' }}><CompetitorPanel comp={c} deals={cell(c.id, 'total')} openDrawer={openDrawer} /></td></tr>
                    )}
                  </React.Fragment>
                ))}
                {selComps.length === 0 && <tr><td colSpan={5} style={{ textAlign: 'center', padding: 30, color: 'var(--ink-faint)' }}>Select competitors above to build the matrix.</td></tr>}
              </tbody>
            </table>
          </div>

          <ChartCard title="Activity by deal type, per quarter" sub="Selected competitors · role-based classification"
            legend={[{ label: 'Platform (buyer)', color: CH.platform }, { label: 'Exit (seller)', color: CH.exit }, { label: 'Buy-and-build (financer)', color: CH.buyAndBuild }]}
            footnote="Role is the IP: buyer = platform move · seller = exit · financer = buy-and-build backing. This turns “who did a deal” into “what kind of move”.">
            <StackedBar data={typeData} keys={['platform', 'exit', 'bnb']}
              colors={{ platform: CH.platform, exit: CH.exit, bnb: CH.buyAndBuild }}
              labels={{ platform: 'Platform', exit: 'Exit', bnb: 'Buy-and-build' }}
              onSegment={(d, k) => {
                const roleMap = { platform: 'buyerCompId', exit: 'sellerCompId', bnb: 'financerCompId' };
                const set = deals.filter((x) => x.quarter === d.q && selected.some((id) => x[roleMap[k]] === id));
                openDrawer(`${ROLE_LABEL[k]} deals · ${d.q}`, 'Selected competitors', set);
              }} />
          </ChartCard>
    </div>
  );
}

function MatrixCell({ n, onClick, bold }) {
  if (!n) return <span style={{ color: 'var(--ink-faint)' }}>·</span>;
  return (
    <button onClick={onClick} style={{
      border: 'none', background: 'transparent', cursor: 'pointer', fontFamily: 'var(--mono)',
      fontWeight: bold ? 700 : 600, fontSize: 13, color: 'var(--accent)', padding: '2px 7px', borderRadius: 5,
    }}
      onMouseEnter={(e) => e.currentTarget.style.background = 'var(--accent-soft)'}
      onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>{n}</button>
  );
}

function CompetitorPanel({ comp, deals, openDrawer }) {
  const asBuyer = deals.filter((d) => d.buyerCompId === comp.id);
  const asSeller = deals.filter((d) => d.sellerCompId === comp.id);
  const asFinancer = deals.filter((d) => d.financerCompId === comp.id);
  const relWins = asBuyer.filter((d) => d.relevant);
  const seen = relWins.filter((d) => d.seenBefore).length;
  const missed = relWins.length - seen;
  const recent = [...deals].sort((a, b) => b.date.localeCompare(a.date)).slice(0, 5);
  const top = (key, n) => {
    const m = {}; asBuyer.forEach((d) => { if (d[key]) m[d[key]] = (m[d[key]] || 0) + 1; });
    return Object.entries(m).sort((a, b) => b[1] - a[1]).slice(0, n);
  };
  const sectors = top('sector', 3), countries = top('country', 3);

  // one-line strategy read from the dominant role
  const role = asFinancer.length > asBuyer.length && asFinancer.length >= asSeller.length ? 'bnb'
    : asSeller.length > asBuyer.length ? 'exit' : 'platform';
  const strategy = !deals.length ? 'No activity in the current filter.'
    : role === 'platform'
      ? `Active platform buyer${sectors.length ? ', leaning into ' + sectors[0][0].toLowerCase() : ''}. ${relWins.length} relevant win${relWins.length === 1 ? '' : 's'} in this window, ${relWins.length ? Math.round(seen / relWins.length * 100) + '% on our radar first' : 'none yet'}.`
      : role === 'bnb' ? 'Buy-and-build backer; shows up mostly as the financer behind add-on deals.'
        : 'Returning capital; more exits than acquisitions this window.';

  const roleTile = (label, hint, set, color) => (
    <button onClick={() => set.length && openDrawer(`${comp.name} · ${label}`, 'Deals where ' + comp.name + ' acted ' + hint, set)}
      style={{ textAlign: 'left', border: '1px solid var(--line)', background: 'var(--surface-card)', borderRadius: 9, padding: '10px 12px', cursor: set.length ? 'pointer' : 'default', transition: 'border-color .12s' }}
      onMouseEnter={(e) => { if (set.length) e.currentTarget.style.borderColor = 'var(--accent)'; }} onMouseLeave={(e) => e.currentTarget.style.borderColor = 'var(--line)'}>
      <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <span style={{ width: 7, height: 7, borderRadius: 9, background: color }}></span>
        <span className="micro" style={{ marginBottom: 0 }}>{label}</span>
      </span>
      <div className="tabular" style={{ fontSize: 21, fontWeight: 700, marginTop: 5, lineHeight: 1, color: set.length ? 'var(--ink)' : 'var(--ink-faint)' }}>{set.length}</div>
      <div style={{ fontSize: 10.5, color: 'var(--ink-faint)', marginTop: 3 }}>{hint}</div>
    </button>
  );

  const chips = (list) => list.length
    ? list.map(([s, n]) => (
      <span key={s} className="badge" style={{ background: 'var(--surface-deep)' }}>{s}<span style={{ color: 'var(--ink-faint)', marginLeft: 5 }}>{n}</span></span>
    ))
    : <span style={{ fontSize: 12, color: 'var(--ink-faint)' }}>None</span>;

  return (
    <div style={{ padding: '16px 18px 18px', borderTop: '1px solid var(--line)', background: 'var(--surface)' }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16, marginBottom: 14 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <h4 style={{ fontSize: 14.5, fontWeight: 700 }}>{comp.name}</h4>
            <TierTag tier={comp.tier} />
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-soft)', marginTop: 4, maxWidth: 580, lineHeight: 1.5, fontWeight: 500 }}>{strategy}</div>
        </div>
        <button className="btn sm" onClick={() => deals.length && openDrawer(`${comp.name} · all activity`, 'Every deal where they appear, in this filter', deals)}>
          All {deals.length} deals <Icon name="chevronRight" size={13} />
        </button>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.15fr 1fr', gap: 22 }}>
        {/* left — roles, coverage, focus */}
        <div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 10 }}>
            {roleTile('Platform', 'as buyer', asBuyer, CH.platform)}
            {roleTile('Exit', 'as seller', asSeller, CH.exit)}
            {roleTile('Buy & build', 'as financer', asFinancer, CH.buyAndBuild)}
          </div>

          <div style={{ marginTop: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 7 }}>
              <span className="micro" style={{ marginBottom: 0 }}>Our coverage of their relevant wins</span>
              <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink-muted)' }}>{relWins.length ? Math.round(seen / relWins.length * 100) + '%' : 'n/a'}</span>
            </div>
            {relWins.length ? (
              <div style={{ display: 'flex', height: 26, borderRadius: 7, overflow: 'hidden', border: '1px solid var(--line)' }}>
                {seen > 0 && <button onClick={() => openDrawer(`Saw coming · ${comp.name}`, 'Relevant wins we tracked early', relWins.filter((d) => d.seenBefore))}
                  style={{ width: (seen / relWins.length * 100) + '%', background: 'var(--positive)', border: 'none', color: '#fff', fontSize: 11, fontWeight: 700, cursor: 'pointer', display: 'flex', alignItems: 'center', paddingLeft: 9, whiteSpace: 'nowrap' }}>Seen:<span style={{ marginLeft: 5 }}>{seen}</span></button>}
                {missed > 0 && <button onClick={() => openDrawer(`Missed · ${comp.name}`, 'Relevant wins we never saw', relWins.filter((d) => !d.seenBefore), true)}
                  style={{ flex: 1, background: 'var(--danger-soft)', border: 'none', color: 'var(--danger)', fontSize: 11, fontWeight: 700, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'flex-end', paddingRight: 9, whiteSpace: 'nowrap' }}>Missed:<span style={{ marginLeft: 5 }}>{missed}</span></button>}
              </div>
            ) : <div style={{ fontSize: 12, color: 'var(--ink-faint)', padding: '5px 0' }}>No relevant wins in this window.</div>}
          </div>

          <div style={{ marginTop: 16, display: 'flex', gap: 26, flexWrap: 'wrap' }}>
            <div>
              <div className="micro" style={{ marginBottom: 7 }}>Buys in</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>{chips(sectors)}</div>
            </div>
            <div>
              <div className="micro" style={{ marginBottom: 7 }}>Geography</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>{chips(countries)}</div>
            </div>
          </div>
        </div>

        {/* right — recent deals */}
        <div>
          <div className="micro" style={{ marginBottom: 8 }}>Recent deals</div>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {recent.map((d, i) => {
              const r = d.buyerCompId === comp.id ? 'Platform' : d.sellerCompId === comp.id ? 'Exit' : 'Buy & build';
              return (
                <button key={d.id} onClick={() => openDrawer(d.name, `${d.sector} · ${d.country}`, [d], !d.seenBefore && d.relevant)}
                  style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 4px', border: 'none', borderTop: i ? '1px solid var(--line-soft)' : 'none', background: 'transparent', cursor: 'pointer', textAlign: 'left', width: '100%' }}>
                  <span className="fit" style={fitBadgeStyle(d.fit)}>{d.fit}</span>
                  <span style={{ flex: 1, minWidth: 0 }}>
                    <span style={{ display: 'block', fontWeight: 600, fontSize: 12.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.name}</span>
                    <span style={{ display: 'block', fontSize: 11, color: 'var(--ink-soft)' }}>{r} · {d.date} · {DATA.fmtSize(d.dealSize)}</span>
                  </span>
                  {d.relevant && <span className="badge accent" style={{ flexShrink: 0 }}>Relevant</span>}
                </button>
              );
            })}
            {recent.length === 0 && <div style={{ color: 'var(--ink-faint)', fontSize: 12, padding: '10px 0' }}>No deals in the current filter.</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------------- Advisors ---------------- */
function buildAdvisors(deals, side) {
  const map = new Map();
  for (const d of deals) {
    const names = side === 'sell' ? d.advisorsSell : side === 'buy' ? d.advisorsBuy : [...new Set([...d.advisorsSell, ...d.advisorsBuy])];
    for (const name of names) {
      if (!map.has(name)) map.set(name, { name, deals: [] });
      map.get(name).deals.push(d);
    }
  }
  const out = [];
  for (const a of map.values()) {
    const dl = a.deals;
    const rel = dl.filter((d) => d.relevant);
    const seen = rel.filter((d) => d.seenBefore).length;
    const tierN = (t) => dl.filter((d) => d.primaryTier === t).length;
    const tier = { core: tierN('core'), buyout: tierN('buyout'), vc: tierN('vc') };
    tier.other = dl.length - tier.core - tier.buyout - tier.vc;
    const relToCore = rel.filter((d) => d.primaryTier === 'core').length;
    const top = (key, n) => { const m = {}; dl.forEach((d) => { if (d[key]) m[d[key]] = (m[d[key]] || 0) + 1; }); return Object.entries(m).sort((x, y) => y[1] - x[1]).slice(0, n); };
    out.push({
      name: a.name, deals: dl, count: dl.length,
      sell: dl.filter((d) => d.advisorsSell.includes(a.name)).length,
      buy: dl.filter((d) => d.advisorsBuy.includes(a.name)).length,
      relevant: rel.length, seen, missed: rel.length - seen, toCore: relToCore, tier,
      avg: dl.reduce((s, d) => s + d.fit, 0) / dl.length,
      sectors: top('sector', 3), countries: top('country', 3),
      recent: [...dl].sort((x, y) => y.date.localeCompare(x.date)).slice(0, 5),
      raw: (rel.length - seen) * 3 + relToCore * 2 + rel.length,
    });
  }
  const maxRaw = Math.max(1, ...out.map((a) => a.raw));
  out.forEach((a) => { a.priority = a.raw <= 0 ? 1 : Math.max(1, Math.min(5, Math.round((a.raw / maxRaw) * 5))); });
  return out;
}

function advisorWhy(a) {
  if (!a.count) return 'No activity in this filter.';
  if (a.toCore >= 2 && a.missed >= 2) return `No line in; ${a.toCore} relevant deals went to core rivals.`;
  if (a.relevant >= 3 && a.missed >= a.relevant * 0.6) return `Thesis-fit processes we keep missing; saw only ${a.seen} of ${a.relevant}.`;
  if (a.relevant >= 3 && a.seen >= a.relevant * 0.7) return 'Strong relationship already; keep it warm.';
  if (a.toCore >= 2) return `Feeds core rivals; ${a.toCore} relevant deals.`;
  if (a.relevant >= 4) return 'High relevant volume, partial coverage.';
  if (a.relevant === 0) return 'No relevant mandates yet; tracked for context.';
  return 'Occasional relevant flow; worth monitoring.';
}

const ADVISOR_SORTS = [
  { value: 'priority', label: 'Priority' },
  { value: 'relevant', label: 'Relevant' },
  { value: 'missed', label: 'Coverage gap' },
  { value: 'count', label: 'Volume' },
];

function PriorityDots({ n, danger }) {
  const c = danger ? 'var(--danger)' : 'var(--accent)';
  return (
    <span style={{ display: 'inline-flex', gap: 3 }}>
      {[0, 1, 2, 3, 4].map((i) => (
        <span key={i} style={{ width: 8, height: 8, borderRadius: 9, background: i < n ? c : 'transparent', border: `1.5px solid ${i < n ? c : 'var(--line)'}` }}></span>
      ))}
    </span>
  );
}

function CoverageMini({ seen, missed }) {
  const t = seen + missed;
  if (!t) return <span style={{ fontSize: 11, color: 'var(--ink-faint)' }}>no relevant</span>;
  return (
    <div style={{ display: 'flex', height: 18, width: 140, borderRadius: 6, overflow: 'hidden', border: '1px solid var(--line)' }}>
      {seen > 0 && <div style={{ width: (seen / t * 100) + '%', background: 'var(--positive)', color: '#fff', fontSize: 9.5, fontWeight: 700, display: 'flex', alignItems: 'center', paddingLeft: 6 }}>{seen}</div>}
      {missed > 0 && <div style={{ flex: 1, background: 'var(--danger-soft)', color: 'var(--danger)', fontSize: 9.5, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'flex-end', paddingRight: 6 }}>{missed}</div>}
    </div>
  );
}

function MiniSpark({ pts, w = 116, h = 30 }) {
  if (!pts.length) return null;
  const max = Math.max(1, ...pts), min = Math.min(...pts);
  const xs = (i) => pts.length === 1 ? w / 2 : (i / (pts.length - 1)) * (w - 6) + 3;
  const ys = (v) => h - ((v - min) / (max - min || 1)) * (h - 8) - 4;
  const d = pts.map((v, i) => `${i ? 'L' : 'M'}${xs(i).toFixed(1)},${ys(v).toFixed(1)}`).join(' ');
  return (
    <svg width={w} height={h} style={{ display: 'block' }}>
      <path d={d} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={xs(pts.length - 1)} cy={ys(pts[pts.length - 1])} r="3" fill="var(--accent)" />
    </svg>
  );
}

function AdvisorDossier({ a, side, chrono, openDrawer }) {
  const relWins = a.deals.filter((d) => d.relevant);
  const pq = chrono.map((qq) => a.deals.filter((d) => d.quarter === qq).length);
  const tierBar = [['core', CH.core, 'Core'], ['buyout', CH.buyout, 'Buyout'], ['vc', CH.vc, 'VC'], ['other', CH.other, 'Open']];
  const tierTotal = a.count || 1;
  return (
    <div style={{ borderTop: '1px solid var(--line)', background: 'var(--surface)', padding: '16px 18px 18px' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14, marginBottom: 14 }}>
        <span style={{ fontSize: 12, color: 'var(--ink-soft)', fontWeight: 500 }}>{advisorWhy(a)}</span>
        <button className="btn sm" onClick={() => openDrawer(`${a.name} · ${side === 'both' ? 'all' : side + '-side'} mandates`, 'Every deal they advised in this filter', a.deals)}>All {a.count} deals <Icon name="chevronRight" size={13} /></button>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1.15fr 1fr', gap: 22 }}>
        <div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 10 }}>
            {[['Sell-side', a.sell], ['Buy-side', a.buy], ['Avg fit', a.avg.toFixed(1)]].map(([l, v]) => (
              <div key={l} style={{ border: '1px solid var(--line)', borderRadius: 9, padding: '10px 12px', background: 'var(--surface-card)' }}>
                <div className="micro">{l}</div>
                <div className="tabular" style={{ fontSize: 19, fontWeight: 700, marginTop: 4 }}>{v}</div>
              </div>
            ))}
          </div>

          <div style={{ marginTop: 15 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 7 }}>
              <span className="micro">Our coverage of their relevant deals</span>
              <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink-muted)' }}>{relWins.length ? Math.round(a.seen / relWins.length * 100) + '%' : 'n/a'}</span>
            </div>
            {relWins.length
              ? <div style={{ display: 'flex', height: 24, borderRadius: 7, overflow: 'hidden', border: '1px solid var(--line)' }}>
                {a.seen > 0 && <button onClick={() => openDrawer(`Seen · ${a.name}`, 'Relevant deals we tracked early', relWins.filter((d) => d.seenBefore))} style={{ width: (a.seen / relWins.length * 100) + '%', background: 'var(--positive)', border: 'none', color: '#fff', fontSize: 11, fontWeight: 700, cursor: 'pointer', display: 'flex', alignItems: 'center', paddingLeft: 9, whiteSpace: 'nowrap' }}>Seen:<span style={{ marginLeft: 5 }}>{a.seen}</span></button>}
                {a.missed > 0 && <button onClick={() => openDrawer(`Missed · ${a.name}`, 'Relevant deals we never saw', relWins.filter((d) => !d.seenBefore), true)} style={{ flex: 1, background: 'var(--danger-soft)', border: 'none', color: 'var(--danger)', fontSize: 11, fontWeight: 700, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'flex-end', paddingRight: 9, whiteSpace: 'nowrap' }}>Missed:<span style={{ marginLeft: 5 }}>{a.missed}</span></button>}
              </div>
              : <div style={{ fontSize: 12, color: 'var(--ink-faint)', padding: '4px 0' }}>No relevant mandates in this window.</div>}
          </div>

          <div style={{ marginTop: 15 }}>
            <div className="micro" style={{ marginBottom: 7 }}>Who won their deals</div>
            <div style={{ display: 'flex', height: 22, borderRadius: 6, overflow: 'hidden', border: '1px solid var(--line)' }}>
              {tierBar.map(([k, c]) => a.tier[k] > 0 ? <div key={k} style={{ width: (a.tier[k] / tierTotal * 100) + '%', background: c }}></div> : null)}
            </div>
            <div style={{ display: 'flex', gap: 14, marginTop: 7, flexWrap: 'wrap' }}>
              {tierBar.map(([k, c, lbl]) => (
                <span key={k} style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11, fontWeight: 600, color: 'var(--ink-muted)' }}>
                  <span style={{ width: 8, height: 8, borderRadius: 9, background: c }}></span>{lbl} {a.tier[k]}
                </span>
              ))}
            </div>
          </div>

          <div style={{ marginTop: 15, display: 'flex', gap: 26, flexWrap: 'wrap', alignItems: 'flex-start' }}>
            <div>
              <div className="micro" style={{ marginBottom: 7 }}>Geography</div>
              <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                {a.countries.length ? a.countries.map(([s, n]) => <span key={s} className="badge" style={{ background: 'var(--surface-deep)' }}>{s}<span style={{ color: 'var(--ink-faint)', marginLeft: 5 }}>{n}</span></span>) : <span style={{ fontSize: 12, color: 'var(--ink-faint)' }}>None</span>}
              </div>
            </div>
            <div>
              <div className="micro" style={{ marginBottom: 7 }}>Activity / quarter</div>
              <MiniSpark pts={pq} />
            </div>
          </div>
        </div>

        <div>
          <div className="micro" style={{ marginBottom: 8 }}>Recent mandates</div>
          <div style={{ display: 'flex', flexDirection: 'column' }}>
            {a.recent.map((d, i) => {
              const wt = d.primaryTier;
              const dest = wt === 'core' ? '→ Core' : wt === 'buyout' ? '→ Buyout' : wt === 'vc' ? '→ VC' : '→ open market';
              const sideTag = d.advisorsSell.includes(a.name) ? 'sell' : 'buy';
              return (
                <button key={d.id} onClick={() => openDrawer(d.name, `${d.sector} · ${d.country}`, [d], !d.seenBefore && d.relevant)}
                  style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 2px', border: 'none', borderTop: i ? '1px solid var(--line-soft)' : 'none', background: 'transparent', cursor: 'pointer', textAlign: 'left', width: '100%' }}>
                  <span className="fit" style={fitBadgeStyle(d.fit)}>{d.fit}</span>
                  <span style={{ flex: 1, minWidth: 0 }}>
                    <span style={{ display: 'block', fontWeight: 600, fontSize: 12.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.name}</span>
                    <span style={{ display: 'block', fontSize: 11, color: 'var(--ink-soft)' }}>{d.sector} · {sideTag} · <span style={{ color: wt === 'core' ? 'var(--danger)' : 'var(--ink-soft)' }}>{dest}</span></span>
                  </span>
                  {d.relevant && <span className="badge accent" style={{ flexShrink: 0 }}>relevant</span>}
                </button>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

function Advisors({ deals, filters, openDrawer }) {
  const [side, setSide] = useState('sell');
  const [q, setQ] = useState('');
  const [sortKey, setSortKey] = useState('priority');
  const [expanded, setExpanded] = useState(null);
  useEffect(() => { setExpanded(null); }, [side, deals.length]);

  let stats = buildAdvisors(deals, side);
  const relMandates = stats.reduce((s, a) => s + a.relevant, 0);
  const gap = stats.reduce((s, a) => s + a.missed, 0);
  const feedCore = stats.filter((a) => a.toCore >= 1).length;
  const priorityCount = stats.filter((a) => a.priority >= 4).length;

  if (q.trim()) stats = stats.filter((a) => a.name.toLowerCase().includes(q.trim().toLowerCase()));
  stats = [...stats].sort((a, b) => (b[sortKey] - a[sortKey]) || (b.raw - a.raw) || a.name.localeCompare(b.name));

  const sideLabel = side === 'sell' ? 'Sell-side' : side === 'buy' ? 'Buy-side' : 'All';
  const chrono = [...DATA.quarters].reverse();

  return (
    <div className="screen-in">
      <PageHead icon="users" title="Advisors" />

      <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
        <KpiCell label="Priority advisors" value={priorityCount} accent sub="score 4+ of 5, build next" />
        <KpiCell label="Relevant mandates" value={relMandates} sub={`${sideLabel.toLowerCase()}, inside the thesis`} />
        <KpiCell label="Coverage gap" value={gap} sub="relevant mandates we missed" />
        <KpiCell label="Feeding core rivals" value={feedCore} sub="advisors losing relevant deals to core" />
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14, flexWrap: 'wrap' }}>
        <span className="micro">Mandate side</span>
        <Segmented value={side} onChange={setSide} options={[{ value: 'sell', label: 'Sell' }, { value: 'buy', label: 'Buy' }, { value: 'both', label: 'Both' }]} />
        <span style={{ width: 1, height: 22, background: 'var(--line)', margin: '0 2px' }}></span>
        <span className="micro">Sort</span>
        <Segmented value={sortKey} onChange={setSortKey} options={ADVISOR_SORTS} />
        <div style={{ flex: 1 }}></div>
        <div style={{ position: 'relative' }}>
          <Icon name="search" size={14} style={{ position: 'absolute', left: 10, top: 9, color: 'var(--ink-faint)' }} />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search advisors"
            style={{ height: 32, border: '1px solid var(--line)', borderRadius: 7, padding: '0 10px 0 30px', fontSize: 12.5, width: 190, background: 'var(--surface-card)', color: 'var(--ink)' }} />
        </div>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {stats.map((a, i) => {
          const open = expanded === a.name;
          const danger = a.priority >= 4;
          return (
            <div key={a.name} className="card" style={{ overflow: 'hidden', borderColor: open ? 'var(--accent)' : 'var(--line)', background: open ? 'var(--accent-soft)' : 'var(--surface-card)' }}>
              <button onClick={() => setExpanded(open ? null : a.name)}
                style={{ width: '100%', textAlign: 'left', border: 'none', background: 'transparent', cursor: 'pointer', padding: '13px 16px', display: 'flex', alignItems: 'center', gap: 16 }}>
                <span className="tabular" style={{ fontSize: 17, fontWeight: 700, color: 'var(--ink-faint)', width: 22, textAlign: 'center', flexShrink: 0 }}>{i + 1}</span>
                <span style={{ width: 168, flexShrink: 0 }}>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
                    <span style={{ fontWeight: 600, fontSize: 13.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{a.name}</span>
                    {a.toCore >= 2 && <span className="badge danger" style={{ fontSize: 9.5, flexShrink: 0 }}>feeds core</span>}
                  </span>
                  <span style={{ display: 'block', fontSize: 11, color: 'var(--ink-soft)', marginTop: 3 }}>{a.sell} sell · {a.buy} buy</span>
                </span>
                <span style={{ flexShrink: 0, width: 58, textAlign: 'center' }}>
                  <span className="micro" style={{ display: 'block', marginBottom: 4 }}>Relevant</span>
                  <span className="tabular" style={{ fontWeight: 700, fontSize: 14 }}>{a.relevant}</span>
                </span>
                <span style={{ flexShrink: 0 }}>
                  <span className="micro" style={{ display: 'block', marginBottom: 4 }}>Coverage</span>
                  <CoverageMini seen={a.seen} missed={a.missed} />
                </span>
                <span style={{ flexShrink: 0, width: 52, textAlign: 'center' }}>
                  <span className="micro" style={{ display: 'block', marginBottom: 4 }}>→ Core</span>
                  <span className="tabular" style={{ fontWeight: 700, fontSize: 14, color: a.toCore >= 2 ? 'var(--danger)' : 'var(--ink)' }}>{a.toCore}</span>
                </span>
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ fontSize: 12, color: 'var(--ink-soft)', fontWeight: 500 }}>{advisorWhy(a)}</span>
                </span>
                <span style={{ flexShrink: 0, textAlign: 'right' }}>
                  <span className="micro" style={{ display: 'block', marginBottom: 5 }}>Priority</span>
                  <PriorityDots n={a.priority} danger={danger} />
                </span>
                <Icon name={open ? 'chevronDown' : 'chevronRight'} size={15} style={{ color: 'var(--ink-faint)', flexShrink: 0 }} />
              </button>
              {open && <AdvisorDossier a={a} side={side} chrono={chrono} openDrawer={openDrawer} />}
            </div>
          );
        })}
        {stats.length === 0 && <div className="card" style={{ padding: 30, textAlign: 'center', color: 'var(--ink-faint)' }}>No advisors match.</div>}
      </div>
    </div>
  );
}

Object.assign(window, { CompetitorActivity, Advisors, buildAdvisors });
