// ════════════════════════════════════════════════════════════════
// ClusterDetailPage — drill-down при клике "Открыть стартапы кластера"
// Контекст кластера + мини-аналитика + список стартапов
// ════════════════════════════════════════════════════════════════
const { useMemo: useMemoCD, useState: useStateCD } = React;

function ClusterDetailPage({ cluster, onBack, onOpenStartup }) {
  const D = window.SDH_DATA;
  const tintHue =
    cluster.momentum === 'rising' ? 'emerald' :
    cluster.momentum === 'cooling' ? 'rose' : 'info';

  // Deterministic subset of corpus belonging to this cluster
  const clusterStartups = useMemoCD(() => {
    // seed from cluster.id like "t1"
    const seedNum = cluster.id.charCodeAt(1) * 7 + (cluster.id.length > 2 ? cluster.id.charCodeAt(2) : 0);
    const rng = (n) => ((seedNum * 9301 + n * 49297) % 233280) / 233280;
    // pick `cluster.count` startups from corpus by stable hash
    const ranked = D.corpus
      .map((s, i) => ({ s, key: rng(i) }))
      .sort((a, b) => a.key - b.key)
      .slice(0, cluster.count)
      .map(({ s }, i) => {
        // bias similarity higher in cluster
        return { ...s, similarity: Math.min(1, s.similarity * 0.5 + 0.45 + rng(i + 999) * 0.15) };
      });
    return ranked;
  }, [cluster.id, cluster.count]);

  // Stats
  const newThisWeek = clusterStartups.filter(s => s.daysAgo <= 7).length;
  const avgSim = clusterStartups.reduce((sum, s) => sum + s.similarity, 0) / Math.max(1, clusterStartups.length);
  const fundedCount = clusterStartups.filter(s => s.funding_usd).length;

  // Source distribution
  const sourceDist = useMemoCD(() => {
    const map = {};
    clusterStartups.forEach(s => {
      map[s.source] = map[s.source] || { id: s.source, label: s.sourceLabel, hue: s.sourceHue, count: 0 };
      map[s.source].count += 1;
    });
    return Object.values(map).sort((a, b) => b.count - a.count);
  }, [clusterStartups]);

  // Geo distribution
  const geoDist = useMemoCD(() => {
    const map = {};
    clusterStartups.forEach(s => {
      map[s.geo] = (map[s.geo] || 0) + 1;
    });
    return Object.entries(map)
      .map(([geo, count]) => ({ geo, count }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 6);
  }, [clusterStartups]);

  // Sort & filter state for the list
  const [sort, setSort] = useStateCD('sim');
  const [verdict, setVerdict] = useStateCD('all'); // all | high | mid | low

  const filteredStartups = useMemoCD(() => {
    let arr = clusterStartups;
    if (verdict === 'high') arr = arr.filter(s => s.similarity >= 0.75);
    else if (verdict === 'mid') arr = arr.filter(s => s.similarity >= 0.5 && s.similarity < 0.75);
    else if (verdict === 'low') arr = arr.filter(s => s.similarity < 0.5);
    arr = arr.slice();
    if (sort === 'sim') arr.sort((a, b) => b.similarity - a.similarity);
    else if (sort === 'date') arr.sort((a, b) => a.daysAgo - b.daysAgo);
    else if (sort === 'name') arr.sort((a, b) => a.name.localeCompare(b.name));
    else if (sort === 'funded') arr.sort((a, b) => (b.funding_usd || 0) - (a.funding_usd || 0));
    return arr;
  }, [clusterStartups, sort, verdict]);

  const high = clusterStartups.filter(s => s.similarity >= 0.75).length;
  const mid  = clusterStartups.filter(s => s.similarity >= 0.5 && s.similarity < 0.75).length;
  const low  = clusterStartups.filter(s => s.similarity < 0.5).length;

  return (
    <div className="sdh-fade" data-screen-label={`Кластер · ${cluster.title}`}>
      {/* HERO with tint */}
      <section style={{
        background: `linear-gradient(180deg, var(--hue-${tintHue}-subtle), var(--surface-canvas))`,
        borderBottom: '1px solid var(--border-subtle)',
        paddingBottom: 'var(--space-8)',
      }}>
        <div className="sdh-container" style={{ paddingTop: 'var(--space-8)' }}>
          {/* Breadcrumb */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 'var(--space-4)' }}>
            <button className="sdh-btn sdh-btn--ghost" onClick={onBack} style={{ padding: '5px 10px', fontSize: 12 }}>
              <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5">
                <path d="M7.5 2 4 6l3.5 4" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
              Тренды
            </button>
            <span style={{ color: 'var(--text-tertiary)' }}>›</span>
            <span className="sdh-mono-label" style={{ marginBottom: 0 }}>кластер {cluster.id.toUpperCase()}</span>
          </div>

          {/* Title row */}
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--space-6)', flexWrap: 'wrap' }}>
            <div style={{ flex: 1, minWidth: 280 }}>
              <span className="sdh-section-label">семантический кластер</span>
              <h1 className="sdh-hero-h" style={{ marginBottom: 'var(--space-3)' }}>
                {renderTitleWithItalic(cluster.title)}
              </h1>
              <p className="sdh-quote" style={{ margin: 0, maxWidth: 620 }}>
                {cluster.recommendation || 'Сила сигнала растёт. Следующий шаг: прототип на трёх пользовательских сценариях.'}
              </p>
            </div>

            {/* Side stat tile */}
            <div className="sdh-warm-card" style={{
              minWidth: 280, padding: 'var(--space-6)',
              '--bg-tint': 'var(--surface-elevated)',
            }}>
              <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 'var(--space-3)' }}>
                <div>
                  <span className="sdh-metric-big">{cluster.count}</span>
                  <span style={{ marginLeft: 8, fontSize: 12, color: 'var(--text-tertiary)' }}>стартапов</span>
                </div>
                <MomentumPill momentum={cluster.momentum} growth={cluster.growth} />
              </div>
              <MicroSparkline data={cluster.timeseries} width={232} height={42} color={`var(--hue-${tintHue})`} fill accentLast />
              <div className="sdh-mono-label" style={{ marginTop: 6, marginBottom: 0 }}>динамика за 30 дней</div>
            </div>
          </div>

          {/* Stat strip */}
          <div style={{
            marginTop: 'var(--space-8)',
            display: 'grid',
            gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
            gap: 'var(--space-3)',
          }}>
            <MiniStat metric={{ title: 'За последние 7 дней', what: 'Стартапы из кластера, появившиеся за последнюю неделю.', why: 'Скорость пополнения кластера прямо сейчас. Скачок = разогрев.' }}
              label="за 7 дней" value={`+${newThisWeek}`} hue="emerald" />
            <MiniStat metric={{ title: 'Средняя близость', what: 'Среднее значение similarity по стартапам кластера к идеям Стартапзавода.', why: 'Чем выше — тем больше прямых пересечений с фокусом исследования.' }}
              label="средняя близость" value={avgSim.toFixed(2)} hue={avgSim >= 0.75 ? 'emerald' : avgSim >= 0.5 ? 'amber' : 'rose'} />
            <MiniStat metric={{ title: 'С поднятыми раундами', what: 'Стартапы кластера, у которых зафиксирован раунд финансирования.', why: 'Зрелость кластера. Много фондируемых = плотный рынок и сильные конкуренты.' }}
              label="с финансированием" value={`${fundedCount} / ${cluster.count}`} hue="purple" />
            <MiniStat metric={{ title: 'Импульс к прошлой неделе', what: 'Темп прироста числа стартапов в кластере.', why: 'Скорость, с которой направление набирает или теряет участников.' }}
              label="импульс" value={`${cluster.growth >= 0 ? '+' : ''}${Math.round(cluster.growth * 100)}%`}
              hue={cluster.growth > 0.05 ? 'emerald' : cluster.growth < -0.05 ? 'rose' : 'info'} />
          </div>
        </div>
      </section>

      {/* Breakdown row */}
      <section className="sdh-container" style={{ paddingTop: 'var(--space-8)', paddingBottom: 'var(--space-6)' }}>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1fr 1fr 1.4fr',
          gap: 'var(--space-4)',
        }}>
          {/* Sources */}
          <Panel title="источники сигнала" subtitle="откуда поступили стартапы кластера"
            help={window.METRIC_DICT.cluster_sourcesPanel}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {sourceDist.map(s => (
                <BreakdownRow key={s.id} label={s.label} count={s.count} total={cluster.count} hue={s.hue} />
              ))}
            </div>
          </Panel>

          {/* Geo */}
          <Panel title="география" subtitle="концентрация по странам"
            help={window.METRIC_DICT.cluster_geoPanel}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {geoDist.map(g => (
                <BreakdownRow key={g.geo} label={g.geo} count={g.count} total={cluster.count} hue={tintHue} mono />
              ))}
            </div>
          </Panel>

          {/* Verdict mix */}
          <Panel title="распределение близости" subtitle="насколько стартапы релевантны идеям Стартапзавода"
            help={window.METRIC_DICT.cluster_verdictPanel}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
              <div style={{
                display: 'flex', height: 18,
                borderRadius: 'var(--radius-md)', overflow: 'hidden',
                border: '1px solid var(--border-subtle)',
              }}>
                {high > 0 && <div style={{ flex: high, background: 'var(--hue-emerald)' }} title={`Высокая: ${high}`} />}
                {mid > 0  && <div style={{ flex: mid,  background: 'var(--hue-amber)' }}   title={`Средняя: ${mid}`} />}
                {low > 0  && <div style={{ flex: low,  background: 'var(--hue-rose)' }}    title={`Низкая: ${low}`} />}
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
                <VerdictCell hue="emerald" label="высокая ≥0.75" count={high} />
                <VerdictCell hue="amber"   label="средняя 0.50–0.74" count={mid} />
                <VerdictCell hue="rose"    label="низкая <0.50" count={low} />
              </div>
            </div>
          </Panel>
        </div>
      </section>

      {/* FILTER */}
      <CommandBar sticky={false}
        left={
          <>
            <span className="sdh-mono-label" style={{ marginRight: 6 }}>
              <InfoLabel {...window.METRIC_DICT.cluster_filterSim}>фильтр близости</InfoLabel>
            </span>
            <button className={`sdh-chip ${verdict === 'all' ? 'is-active' : ''}`} onClick={() => setVerdict('all')}
              title="Все стартапы кластера без фильтра по близости">
              все <span className="chip-count">{cluster.count}</span>
            </button>
            <button className={`sdh-chip ${verdict === 'high' ? 'is-active' : ''}`} onClick={() => setVerdict('high')}
              title="Близость ≥0.75 — прямые конкуренты, делают почти то же самое">
              ≥0.75 <span className="chip-count">{high}</span>
            </button>
            <button className={`sdh-chip ${verdict === 'mid' ? 'is-active' : ''}`} onClick={() => setVerdict('mid')}
              title="Близость 0.50–0.74 — смежники, у которых стоит подсмотреть бизнес-модель и каналы">
              0.50–0.74 <span className="chip-count">{mid}</span>
            </button>
            <button className={`sdh-chip ${verdict === 'low' ? 'is-active' : ''}`} onClick={() => setVerdict('low')}
              title="Близость <0.50 — контекст рынка, фон, полезен перед питчем инвесторам">
              &lt;0.50 <span className="chip-count">{low}</span>
            </button>
          </>
        }
        right={
          <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="sim">сортировать: близость</option>
            <option value="date">сортировать: дата</option>
            <option value="name">сортировать: название</option>
            <option value="funded">сортировать: финансирование</option>
          </select>
        }
      />

      {/* LIST */}
      <section className="sdh-container" style={{ paddingTop: 'var(--space-6)', paddingBottom: 'var(--space-16)' }}>
        <div style={{ marginBottom: 'var(--space-3)', display: 'flex', justifyContent: 'space-between' }}>
          <div className="sdh-mono-label">
            <span className="sdh-num" style={{ color: 'var(--text-primary)', fontSize: 13 }}>{filteredStartups.length}</span> стартапов в выборке
          </div>
          <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 12 }}>
            <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4">
              <path d="M5 1v6m0 0L2.5 4.5M5 7l2.5-2.5M2 9v1a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V9" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
            Выгрузить кластер CSV
          </button>
        </div>

        <div style={{
          border: '1px solid var(--border-subtle)',
          borderRadius: 'var(--radius-xl)',
          background: 'var(--surface-elevated)',
          overflow: 'hidden',
        }}>
          <div style={{
            display: 'grid',
            gridTemplateColumns: '1fr 130px 130px 110px 100px 70px',
            padding: '10px 16px',
            background: 'var(--surface-sunken)',
            borderBottom: '1px solid var(--border-subtle)',
            gap: 12,
          }}>
            <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>
          {filteredStartups.length === 0 && (
            <div style={{ padding: 'var(--space-12)', textAlign: 'center', color: 'var(--text-tertiary)' }}>
              <p className="sdh-quote" style={{ margin: 0 }}>В выборке нет стартапов с выбранными фильтрами.</p>
            </div>
          )}
          {filteredStartups.map(s => (
            <button key={s.id} onClick={() => onOpenStartup && onOpenStartup(s)}
              style={{
                display: 'grid', gridTemplateColumns: '1fr 130px 130px 110px 100px 70px', gap: 12,
                padding: '14px 16px',
                alignItems: 'center',
                borderBottom: '1px solid var(--border-subtle)',
                background: 'transparent',
                width: '100%',
                textAlign: 'left',
                cursor: 'pointer',
                transition: 'background .15s',
                border: 'none',
                borderBottomWidth: '1px',
                borderBottomStyle: 'solid',
                borderBottomColor: 'var(--border-subtle)',
              }}
              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} small>{s.nicheLabel}</CategoryPill></div>
              <div><CategoryPill hue={s.sourceHue} small>{s.sourceLabel}</CategoryPill></div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <MicroDateDot daysAgo={s.daysAgo} width={42} 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', gap: 8, justifyContent: 'flex-end' }}>
                <MicroSimDot value={s.similarity} width={56} height={10} />
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-secondary)' }}>
                  {s.similarity.toFixed(2)}
                </span>
              </div>
              <div style={{ textAlign: 'right', fontFamily: 'var(--font-mono)', fontSize: 11.5, color: 'var(--text-secondary)' }}>
                {s.geo}
              </div>
            </button>
          ))}
        </div>
      </section>
    </div>
  );
}

// ── helpers ──────────────────────────────────────────────────────
function renderTitleWithItalic(title) {
  // Italicize first noun-ish word for editorial accent
  const words = title.split(' ');
  if (words.length < 2) return title;
  return (
    <React.Fragment>
      {words[0]}{' '}
      <em style={{ fontFamily: 'var(--font-display)', fontStyle: 'italic', color: 'var(--brand-bronze-deep)', fontWeight: 600 }}>
        {words[1]}
      </em>
      {words.length > 2 ? ' ' + words.slice(2).join(' ') : ''}
    </React.Fragment>
  );
}

function MiniStat({ label, value, hue, metric }) {
  const body = (
    <React.Fragment>
      <div className="sdh-mono-label" style={{ marginBottom: 4 }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 22, fontWeight: 500,
          color: `var(--hue-${hue})`, letterSpacing: '-0.01em',
        }}>{value}</span>
      </div>
    </React.Fragment>
  );
  return (
    <div className="sdh-warm-card" style={{
      padding: 'var(--space-4)',
      '--bg-tint': `var(--hue-${hue}-subtle)`,
    }}>
      {metric ? (
        <InfoLabel title={metric.title} what={metric.what} why={metric.why} asInline={false}>
          <div style={{ display: 'flex', flexDirection: 'column' }}>{body}</div>
        </InfoLabel>
      ) : body}
    </div>
  );
}

function Panel({ title, subtitle, children, help }) {
  return (
    <div style={{
      background: 'var(--surface-elevated)',
      border: '1px solid var(--border-subtle)',
      borderRadius: 'var(--radius-xl)',
      padding: 'var(--space-4) var(--space-6) var(--space-6)',
    }}>
      <div className="sdh-mono-label" style={{ marginBottom: 2 }}>
        {help ? <InfoLabel {...help}>{title}</InfoLabel> : title}
      </div>
      {subtitle && <div className="sdh-quote" style={{ fontSize: 12.5, marginBottom: 'var(--space-4)' }}>{subtitle}</div>}
      {children}
    </div>
  );
}

function BreakdownRow({ label, count, total, hue, mono }) {
  const pct = (count / total) * 100;
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '90px 1fr 60px', gap: 10, alignItems: 'center' }}>
      <span style={{
        fontSize: 12.5,
        color: 'var(--text-primary)',
        fontFamily: mono ? 'var(--font-mono)' : 'var(--font-sans)',
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
      }}>{label}</span>
      <div style={{ position: 'relative', height: 8, background: 'var(--surface-sunken)', borderRadius: 4, overflow: 'hidden' }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, bottom: 0,
          width: `${pct}%`,
          background: `var(--hue-${hue})`,
          opacity: 0.55,
          borderRadius: 4,
          transition: 'width .3s var(--ease-card)',
        }} />
      </div>
      <span style={{
        fontFamily: 'var(--font-mono)', fontSize: 11.5,
        color: 'var(--text-secondary)', textAlign: 'right',
      }}>{count} · {Math.round(pct)}%</span>
    </div>
  );
}

function VerdictCell({ hue, label, count }) {
  return (
    <div>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 6,
        fontSize: 11, color: 'var(--text-tertiary)', marginBottom: 2,
      }}>
        <span style={{ width: 7, height: 7, borderRadius: '50%', background: `var(--hue-${hue})` }} />
        {label}
      </div>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: 18, fontWeight: 500, color: 'var(--text-primary)' }}>
        {count}
      </div>
    </div>
  );
}

window.ClusterDetailPage = ClusterDetailPage;
