// ════════════════════════════════════════════════════════════════
// CorpusPage — реестр 3068 стартапов
// Hero + warm stat cards + filter bar + virtualized rows
// Layer B integration: hero micro-bars, row CategoryPills + SimDot + DateDot
// ════════════════════════════════════════════════════════════════
const { useState: useStateCorpus, useMemo: useMemoCorpus, useRef: useRefCorpus, useEffect: useEffectCorpus } = React;

function CorpusPage() {
  const D = window.SDH_DATA;
  const [niche, setNiche] = useStateCorpus('all');
  const [source, setSource] = useStateCorpus('all');
  const [q, setQ] = useStateCorpus('');
  const [sort, setSort] = useStateCorpus('date'); // date | sim | name
  const [openStartup, setOpenStartup] = useStateCorpus(null);

  // close on Esc
  useEffectCorpus(() => {
    function onKey(e) { if (e.key === 'Escape') setOpenStartup(null); }
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const filtered = useMemoCorpus(() => {
    let arr = D.corpus;
    if (niche !== 'all') arr = arr.filter(s => s.niche === niche);
    if (source !== 'all') arr = arr.filter(s => s.source === source);
    if (q.trim()) {
      const qq = q.trim().toLowerCase();
      arr = arr.filter(s => s.name.toLowerCase().includes(qq) || s.desc.toLowerCase().includes(qq));
    }
    arr = arr.slice();
    if (sort === 'date') arr.sort((a, b) => a.daysAgo - b.daysAgo);
    else if (sort === 'sim') arr.sort((a, b) => b.similarity - a.similarity);
    else arr.sort((a, b) => a.name.localeCompare(b.name));
    return arr;
  }, [niche, source, q, sort, D.corpus]);

  // Stat cards (hero)
  const heroStats = [
    { key: 'total',  metric: 'startups',   label: 'всего стартапов',     value: D.corpus.length, hue: 'info',    series: D.series.startups, delta: 12.4 },
    { key: 'week',   metric: 'weekNew',    label: 'за последние 7 дней', value: countNew(D.corpus, 7),  hue: 'emerald', series: D.series.startups.slice(-7), delta: 8.1 },
    { key: 'class',  metric: 'classified', label: 'классифицировано',    value: D.series.classified[D.series.classified.length-1].value, hue: 'amber', series: D.series.classified, delta: 4.6 },
    { key: 'srcs',   metric: 'sources',    label: 'источников активно',  value: D.series.sources[D.series.sources.length-1].value, hue: 'purple', series: D.series.sources, delta: 2.0 },
  ];

  return (
    <div className="sdh-fade">
      {/* HERO */}
      <section className="sdh-container" style={{ paddingTop: 'var(--space-12)', paddingBottom: 'var(--space-8)' }}>
        <span className="sdh-section-label">реестр · корпус данных</span>
        <h1 className="sdh-hero-h" style={{ marginBottom: 'var(--space-3)' }}>
          Полный <em>реестр</em> стартапов
        </h1>
        <p className="sdh-quote" style={{ maxWidth: 640, margin: 0 }}>
          Один источник данных для исследований Стартапзавода. Сегодня в базе{' '}
          <span className="sdh-num" style={{ fontFamily: 'var(--font-mono)', color: 'var(--text-primary)' }}>
            {D.corpus.length.toLocaleString('ru-RU')}
          </span>{' '}
          компаний из {D.SOURCES.length} источников. Обновление ежедневно в 10:00 по МСК.
        </p>

        {/* 4 mini stat cards */}
        <div style={{
          marginTop: 'var(--space-8)',
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))',
          gap: 'var(--space-4)',
        }}>
          {heroStats.map(s => {
            const m = window.METRIC_DICT[s.metric];
            return (
            <div key={s.key} className="sdh-warm-card" style={{
              padding: 'var(--space-4)',
              '--bg-tint': `var(--hue-${s.hue}-subtle)`,
            }}>
              <div className="sdh-mono-label" style={{ marginBottom: 6 }}>
                <InfoLabel title={m.title} what={m.what} why={m.why}>
                  {s.label}
                </InfoLabel>
              </div>
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 8 }}>
                <span className="sdh-metric-big">{s.value.toLocaleString('ru-RU')}</span>
                <span style={{
                  fontFamily: 'var(--font-mono)',
                  fontSize: 11,
                  color: s.delta >= 0 ? 'var(--success)' : 'var(--danger)',
                }}>{s.delta >= 0 ? '+' : ''}{s.delta}%</span>
              </div>
              <div style={{ marginTop: 8 }}>
                <MicroSparkline data={s.series} width={188} height={20} color={`var(--hue-${s.hue})`} fill accentLast />
              </div>
            </div>
            );
          })}
        </div>

        <span className="sdh-sep" />
      </section>

      {/* FILTER BAR */}
      <CommandBar
        left={
          <>
            <span className="sdh-mono-label" style={{ marginRight: 6 }}>фильтр</span>
            <button className={`sdh-chip ${niche === 'all' ? 'is-active' : ''}`} onClick={() => setNiche('all')}>
              все ниши <span className="chip-count">{D.corpus.length.toLocaleString('ru-RU')}</span>
            </button>
            {D.NICHES.map(n => {
              const count = D.corpus.filter(s => s.niche === n.id).length;
              return (
                <button key={n.id} className={`sdh-chip ${niche === n.id ? 'is-active' : ''}`} onClick={() => setNiche(n.id)}>
                  {n.label} <span className="chip-count">{count}</span>
                </button>
              );
            })}
          </>
        }
        right={
          <>
            <div style={{ position: 'relative' }}>
              <input
                value={q}
                onChange={e => setQ(e.target.value)}
                placeholder="поиск по названию или описанию"
                style={{
                  background: 'var(--surface-elevated)',
                  border: '1px solid var(--border-default)',
                  borderRadius: 'var(--radius-md)',
                  padding: '7px 12px 7px 30px',
                  fontSize: 13,
                  color: 'var(--text-primary)',
                  width: 240,
                  outline: 'none',
                }}
              />
              <svg width="14" height="14" viewBox="0 0 14 14" style={{ position: 'absolute', left: 10, top: 9, color: 'var(--text-tertiary)' }} fill="none" stroke="currentColor" strokeWidth="1.3">
                <circle cx="6" cy="6" r="4.2" />
                <line x1="9.5" y1="9.5" x2="12.5" y2="12.5" strokeLinecap="round" />
              </svg>
            </div>
            <select value={source} onChange={e => setSource(e.target.value)} style={{
              background: 'var(--surface-elevated)',
              border: '1px solid var(--border-default)',
              borderRadius: 'var(--radius-md)',
              padding: '7px 28px 7px 12px',
              fontSize: 13,
              color: 'var(--text-primary)',
              appearance: 'none',
              backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><path fill='%238A7F70' d='M1 3l4 4 4-4'/></svg>")`,
              backgroundRepeat: 'no-repeat',
              backgroundPosition: 'right 10px center',
            }}>
              <option value="all">все источники</option>
              {D.SOURCES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
            </select>
            <select value={sort} onChange={e => setSort(e.target.value)} style={{
              background: 'var(--surface-elevated)',
              border: '1px solid var(--border-default)',
              borderRadius: 'var(--radius-md)',
              padding: '7px 28px 7px 12px',
              fontSize: 13,
              color: 'var(--text-primary)',
              appearance: 'none',
              backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><path fill='%238A7F70' d='M1 3l4 4 4-4'/></svg>")`,
              backgroundRepeat: 'no-repeat',
              backgroundPosition: 'right 10px center',
            }}>
              <option value="date">сортировать: дата</option>
              <option value="sim">сортировать: близость</option>
              <option value="name">сортировать: название</option>
            </select>
          </>
        }
      />

      {/* RESULTS HEAD */}
      <div className="sdh-container" style={{ paddingTop: 'var(--space-6)', paddingBottom: 'var(--space-3)', display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
        <div className="sdh-mono-label">
          <span className="sdh-num" style={{ color: 'var(--text-primary)', fontSize: 13 }}>
            {filtered.length.toLocaleString('ru-RU')}
          </span>
          {' '}результатов
        </div>
        <div className="sdh-mono-label">
          горячие клавиши: <span className="sdh-kbd">/</span> поиск · <span className="sdh-kbd">j</span>/<span className="sdh-kbd">k</span> навигация
        </div>
      </div>

      {/* VIRTUALIZED LIST */}
      <div className="sdh-container" style={{ paddingBottom: 'var(--space-16)' }}>
        <VirtualRows items={filtered} rowH={56} height={640} onOpen={setOpenStartup} />
      </div>

      {openStartup && <StartupCard startup={openStartup} onClose={() => setOpenStartup(null)} />}
    </div>
  );
}

function countNew(corpus, days) {
  return corpus.filter(s => s.daysAgo <= days).length;
}

// ── VirtualRows ──────────────────────────────────────────────
function VirtualRows({ items, rowH = 56, height = 640, onOpen }) {
  const [scroll, setScroll] = useStateCorpus(0);
  const ref = useRefCorpus(null);
  const totalH = items.length * rowH;
  const visibleCount = Math.ceil(height / rowH) + 6;
  const startIdx = Math.max(0, Math.floor(scroll / rowH) - 3);
  const endIdx = Math.min(items.length, startIdx + visibleCount);

  return (
    <div style={{
      border: '1px solid var(--border-subtle)',
      borderRadius: 'var(--radius-xl)',
      background: 'var(--surface-elevated)',
      overflow: 'hidden',
    }}>
      {/* table header */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '1fr 130px 130px 110px 80px 70px',
        padding: '10px 16px',
        background: 'var(--surface-sunken)',
        borderBottom: '1px solid var(--border-subtle)',
        gap: 12,
        position: 'relative',
        zIndex: 1,
      }}>
        <div className="sdh-mono-label">стартап</div>
        <div className="sdh-mono-label">
          <InfoLabel {...window.METRIC_DICT.niche}>ниша</InfoLabel>
        </div>
        <div className="sdh-mono-label">
          <InfoLabel {...window.METRIC_DICT.source}>источник</InfoLabel>
        </div>
        <div className="sdh-mono-label">
          <InfoLabel {...window.METRIC_DICT.firstSeen}>появился</InfoLabel>
        </div>
        <div className="sdh-mono-label" style={{ textAlign: 'right' }}>
          <span style={{ display: 'inline-flex', justifyContent: 'flex-end', width: '100%' }}>
            <InfoLabel {...window.METRIC_DICT.similarity}>близость</InfoLabel>
          </span>
        </div>
        <div className="sdh-mono-label" style={{ textAlign: 'right' }}>
          <span style={{ display: 'inline-flex', justifyContent: 'flex-end', width: '100%' }}>
            <InfoLabel {...window.METRIC_DICT.geo}>гео</InfoLabel>
          </span>
        </div>
      </div>

      <div
        ref={ref}
        onScroll={(e) => setScroll(e.target.scrollTop)}
        style={{ height, overflowY: 'auto', position: 'relative' }}
      >
        <div style={{ height: totalH, position: 'relative' }}>
          {items.slice(startIdx, endIdx).map((s, i) => (
            <CorpusRow key={s.id} startup={s} y={(startIdx + i) * rowH} h={rowH} onOpen={onOpen} />
          ))}
        </div>
      </div>
    </div>
  );
}

function CorpusRow({ startup, y, h, onOpen }) {
  const s = startup;
  return (
    <div onClick={() => onOpen && onOpen(s)} style={{
      position: 'absolute', top: y, left: 0, right: 0, height: h,
      display: 'grid',
      gridTemplateColumns: '1fr 130px 130px 110px 80px 70px',
      gap: 12,
      padding: '0 16px',
      alignItems: 'center',
      borderBottom: '1px solid var(--border-subtle)',
      cursor: 'pointer',
      transition: 'background .15s',
    }}
    onMouseEnter={e => e.currentTarget.style.background = 'var(--surface-sunken)'}
    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 500, color: 'var(--text-primary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {s.name}
        </div>
        <div style={{ fontSize: 12, color: 'var(--text-tertiary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', marginTop: 2 }}>
          {s.desc}
        </div>
      </div>
      <div><CategoryPill hue={s.nicheHue}>{s.nicheLabel}</CategoryPill></div>
      <div><CategoryPill hue={s.sourceHue}>{s.sourceLabel}</CategoryPill></div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <MicroDateDot daysAgo={s.daysAgo} width={48} height={10} />
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-tertiary)' }}>
          {s.daysAgo === 0 ? 'сегодня' : `${s.daysAgo}д`}
        </span>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
        <MicroSimDot value={s.similarity} width={70} height={10} />
      </div>
      <div style={{ textAlign: 'right', fontFamily: 'var(--font-mono)', fontSize: 11.5, color: 'var(--text-secondary)' }}>
        {s.geo}
      </div>
    </div>
  );
}

window.CorpusPage = CorpusPage;
