// ════════════════════════════════════════════════════════════════
// CouncilLatest — последний прогон LLM Council
// Источник: GET /api/council/latest (auth required)
// Показывает: judge synthesis + переключатель между экспертами
// ════════════════════════════════════════════════════════════════

function CouncilLatest() {
  const [data, setData]   = React.useState(null);
  const [runs, setRuns]   = React.useState([]);     // история прогонов
  const [selTs, setSelTs] = React.useState(null);   // выбранный прогон
  const [active, setActive] = React.useState('judge'); // judge | analyst | breadth | depth | breakthrough | adversarial | structured
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState(null);

  const apiGet = (p) => (window.SDH_API ? window.SDH_API.get(p) : fetch(p).then(x => {
    if (!x.ok) throw new Error('HTTP ' + x.status); return x.json();
  }));

  React.useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const [latest, list] = await Promise.all([
          apiGet('/api/council/latest'),
          apiGet('/api/council/list').catch(() => []),
        ]);
        if (cancelled) return;
        setData(latest);
        setRuns(Array.isArray(list) ? list : []);
        setSelTs(latest.timestamp || null);
        setErr(null);
      } catch (e) {
        if (!cancelled) setErr(String(e.message || e));
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    load();
    return () => { cancelled = true; };
  }, []);

  // Переключение прогона из истории
  async function selectRun(ts) {
    if (!ts || ts === selTs) return;
    setLoading(true);
    try {
      const d = await apiGet('/api/council/by-ts/' + ts);
      setData(d); setSelTs(ts); setActive('judge'); setErr(null);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    } catch (e) { setErr(String(e.message || e)); }
    finally { setLoading(false); }
  }

  // Маппинг ролей в русские названия (без AI-провайдеров)
  // Префикс FULL_ означает прогон по полному корпусу (3000+), без префикса = sample (152)
  const ROLE_LABELS = {
    judge:        { ru: 'Сводный разбор',     desc: 'Финальный синтез по 6 секциям' },
    analyst:      { ru: 'Базовая аналитика',  desc: 'Реестр трендов и кластеров' },
    breadth:      { ru: 'Широта',             desc: 'Видит фокус-продукты портфеля' },
    depth:        { ru: 'Глубина',            desc: 'Двусторонние тренды и сдвиги' },
    breakthrough: { ru: 'Прорыв',             desc: 'Неочевидные структурные паттерны' },
    adversarial:  { ru: 'Критика',            desc: 'Контрвзгляд и проверка инсайтов' },
    structured:   { ru: 'Структура',          desc: 'Кодифицированный обзор' },
    extended:     { ru: 'Заметки и беклог',   desc: 'Расширенный разбор и план действий' },
  };
  // Нормализация role: FULL_analyst → analyst (префикс — это маркер scope, не отдельная роль)
  function cleanRole(role) { return (role || '').replace(/^FULL_/, ''); }
  function labelFor(role)  { return ROLE_LABELS[cleanRole(role)] || { ru: cleanRole(role), desc: '' }; }

  // Простой markdown → HTML (без библиотек, для §1, ###, **bold**, списков)
  function mdToHtml(md) {
    if (!md) return '';
    let html = md
      .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
      // headings
      .replace(/^### (.+)$/gm, '<h3 class="cl-h3">$1</h3>')
      .replace(/^## (.+)$/gm, '<h2 class="cl-h2">$1</h2>')
      .replace(/^# (.+)$/gm,  '<h1 class="cl-h1">$1</h1>')
      // bold + italic
      .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
      .replace(/\*([^*]+)\*/g, '<em>$1</em>')
      // inline code
      .replace(/`([^`]+)`/g, '<code class="cl-code">$1</code>')
      // numbered list (1. ...)
      .replace(/^(\d+)\.\s+(.+)$/gm, '<li class="cl-li-ordered" data-n="$1.">$2</li>')
      // bullets (* / - / •)
      .replace(/^[\*\-•]\s+(.+)$/gm, '<li class="cl-li-bullet">$1</li>')
      // double newlines = paragraph
      .replace(/\n\n+/g, '</p><p class="cl-p">')
      // single newline inside paragraph = break
      .replace(/\n/g, '<br/>');
    return '<p class="cl-p">' + html + '</p>';
  }

  if (loading) return (
    <main><section className="sdh-section first"><div className="sdh-container">
      <div className="sdh-placeholder" style={{ padding: 40, textAlign: 'center' }}>загружаю последний разбор…</div>
    </div></section></main>
  );

  if (err) return (
    <main><section className="sdh-section first"><div className="sdh-container">
      <div className="sdh-placeholder" style={{ padding: 40 }}>
        <div style={{ fontFamily: 'var(--font-serif)', fontSize: 18, marginBottom: 8 }}>
          разбор не загрузился
        </div>
        <div style={{ color: 'var(--text-muted)', fontSize: 14 }}>{err}</div>
        <div style={{ color: 'var(--text-muted)', fontSize: 13, marginTop: 16 }}>
          возможно прогонов ещё не было. запустите scripts/corpus_council_full.py или scripts/corpus_council.py.
        </div>
      </div>
    </div></section></main>
  );

  const date = data.iso_date ? new Date(data.iso_date).toLocaleString('ru-RU', {
    day: '2-digit', month: 'long', year: 'numeric', hour: '2-digit', minute: '2-digit'
  }) : '';

  const activeText = active === 'judge'
    ? data.judge_synthesis
    : (data.experts.find(e => e.role === active)?.text || '(нет данных)');

  const expertRoles = data.experts.map(e => e.role);
  const isFullScope = expertRoles.some(r => r.startsWith('FULL_'));

  return (
    <main className="cl-page">
      <section className="sdh-section first">
        <div className="sdh-container">

          {/* Заголовок */}
          <div className="cl-header">
            <div className="cl-head-row">
              <div className="cl-eyebrow">экспертный разбор</div>
              {runs.length > 1 && (
                <select className="cl-history" value={selTs || ''}
                  onChange={(e) => selectRun(Number(e.target.value))}
                  title="История прогонов совета">
                  {runs.map((r, i) => {
                    const d = new Date((r.timestamp || 0) * 1000);
                    const lbl = d.toLocaleDateString('ru-RU', { day: '2-digit', month: 'short' })
                      + ' ' + d.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });
                    return <option key={r.timestamp} value={r.timestamp}>{i === 0 ? 'свежий · ' : ''}{lbl} · {r.expert_count} эксп.</option>;
                  })}
                </select>
              )}
            </div>
            <h1 className="cl-title">{selTs && runs[0] && selTs !== runs[0].timestamp ? 'Прогон совета' : 'Последний прогон совета'}</h1>
            <div className="cl-meta">
              <span className="cl-meta-item">
                <span className="cl-meta-label">дата</span>
                <span className="cl-meta-value">{date}</span>
              </span>
              <span className="cl-meta-item">
                <span className="cl-meta-label">экспертов</span>
                <span className="cl-meta-value cl-num">{data.experts.length}</span>
              </span>
              <span className="cl-meta-item">
                <span className="cl-meta-label">синтез</span>
                <span className="cl-meta-value cl-num">{Math.round(data.judge_synthesis.length / 1024)} KB</span>
              </span>
              <span className="cl-meta-item">
                <span className="cl-meta-label">охват</span>
                <span className="cl-meta-value">{isFullScope ? 'полный корпус (3000+)' : 'выборка 152'}</span>
              </span>
            </div>
          </div>

          {/* Tab nav */}
          <div className="cl-tabs">
            <button
              className={`cl-tab ${active === 'judge' ? 'cl-tab-active' : ''}`}
              onClick={() => setActive('judge')}>
              <div className="cl-tab-title">{ROLE_LABELS.judge.ru}</div>
              <div className="cl-tab-desc">{ROLE_LABELS.judge.desc}</div>
            </button>
            {expertRoles.map(role => {
              const lbl = labelFor(role);
              return (
                <button key={role}
                  className={`cl-tab ${active === role ? 'cl-tab-active' : ''}`}
                  onClick={() => setActive(role)}>
                  <div className="cl-tab-title">{lbl.ru}</div>
                  <div className="cl-tab-desc">{lbl.desc}</div>
                </button>
              );
            })}
          </div>

          {/* Body */}
          <article className="cl-body" dangerouslySetInnerHTML={{ __html: mdToHtml(activeText) }} />

          {/* Footer */}
          <div className="cl-footer">
            <span className="cl-footer-note">
              совет собирается раз в неделю на выборке 152 стартапов и раз в месяц на полном корпусе.
              стоимость одного прогона: 5 до 40 рублей по курсу ЦБ.
            </span>
          </div>

        </div>
      </section>

      <style>{`
        .cl-page { padding-bottom: 80px; }
        .cl-header { margin-bottom: 32px; }
        .cl-head-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 4px; }
        .cl-history {
          font-family: var(--font-mono); font-size: 12px; color: var(--text-secondary);
          background: var(--surface-elevated); border: 1px solid var(--border-subtle);
          border-radius: 8px; padding: 6px 10px; cursor: pointer; max-width: 60%;
        }
        .cl-history:hover { border-color: var(--accent-bronze, var(--brand-bronze)); }
        .cl-eyebrow {
          font-family: var(--font-mono);
          font-size: 12px;
          letter-spacing: 0.12em;
          text-transform: uppercase;
          color: var(--text-muted);
          margin-bottom: 12px;
        }
        .cl-title {
          font-family: var(--font-serif);
          font-size: 42px;
          font-weight: 400;
          line-height: 1.1;
          color: var(--text-primary);
          margin: 0 0 20px 0;
          font-style: italic;
        }
        .cl-meta { display: flex; gap: 28px; flex-wrap: wrap; }
        .cl-meta-item { display: flex; flex-direction: column; gap: 4px; }
        .cl-meta-label {
          font-family: var(--font-mono);
          font-size: 11px;
          text-transform: uppercase;
          color: var(--text-muted);
          letter-spacing: 0.08em;
        }
        .cl-meta-value {
          font-family: var(--font-sans);
          font-size: 15px;
          color: var(--text-primary);
        }
        .cl-num {
          font-family: var(--font-mono);
          font-variant-numeric: tabular-nums;
        }
        .cl-tabs {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
          gap: 8px;
          margin-bottom: 32px;
          padding: 8px;
          background: var(--surface-recessed);
          border-radius: 12px;
          border: 1px solid var(--border-subtle);
        }
        .cl-tab {
          padding: 12px 14px;
          background: transparent;
          border: 1px solid transparent;
          border-radius: 8px;
          cursor: pointer;
          text-align: left;
          transition: all 160ms ease;
        }
        .cl-tab:hover { background: var(--surface-elevated); }
        .cl-tab-active {
          background: var(--surface-elevated);
          border-color: var(--accent-bronze);
          box-shadow: 0 1px 0 var(--accent-bronze);
        }
        .cl-tab-title {
          font-family: var(--font-sans);
          font-size: 14px;
          font-weight: 500;
          color: var(--text-primary);
          margin-bottom: 2px;
        }
        .cl-tab-desc {
          font-family: var(--font-sans);
          font-size: 12px;
          color: var(--text-muted);
          line-height: 1.3;
        }
        .cl-body {
          background: var(--surface-elevated);
          border: 1px solid var(--border-subtle);
          border-radius: 12px;
          padding: 36px 44px;
          font-family: var(--font-serif);
          font-size: 16px;
          line-height: 1.65;
          color: var(--text-primary);
        }
        .cl-body .cl-h1 {
          font-family: var(--font-serif);
          font-size: 32px;
          font-weight: 400;
          font-style: italic;
          margin: 0 0 24px 0;
        }
        .cl-body .cl-h2 {
          font-family: var(--font-serif);
          font-size: 24px;
          font-weight: 400;
          font-style: italic;
          color: var(--accent-bronze);
          margin: 32px 0 16px 0;
          padding-bottom: 8px;
          border-bottom: 1px solid var(--border-subtle);
        }
        .cl-body .cl-h3 {
          font-family: var(--font-sans);
          font-size: 17px;
          font-weight: 600;
          color: var(--text-primary);
          margin: 24px 0 12px 0;
        }
        .cl-body .cl-p {
          margin: 0 0 16px 0;
          font-family: var(--font-serif);
        }
        .cl-body strong { font-weight: 600; color: var(--text-primary); }
        .cl-body em { font-style: italic; color: var(--text-secondary); }
        .cl-body .cl-code {
          font-family: var(--font-mono);
          font-size: 13px;
          background: var(--surface-recessed);
          padding: 2px 6px;
          border-radius: 4px;
        }
        .cl-body .cl-li-ordered,
        .cl-body .cl-li-bullet {
          display: list-item;
          margin: 6px 0 6px 28px;
          padding-left: 6px;
        }
        .cl-body .cl-li-ordered { list-style: decimal; }
        .cl-body .cl-li-bullet { list-style: disc; }
        .cl-footer {
          margin-top: 24px;
          padding: 16px 20px;
          background: var(--surface-recessed);
          border-radius: 8px;
          border-left: 3px solid var(--accent-bronze);
        }
        .cl-footer-note {
          font-family: var(--font-sans);
          font-size: 13px;
          color: var(--text-muted);
          line-height: 1.5;
        }
        @media (max-width: 720px) {
          .cl-title { font-size: 32px; }
          .cl-body { padding: 24px 20px; font-size: 15px; }
          .cl-body .cl-h2 { font-size: 20px; }
        }
      `}</style>
    </main>
  );
}

window.CouncilLatest = CouncilLatest;
