// ════════════════════════════════════════════════════════════════
// /admin/pipeline — настройка cron + источники
// ════════════════════════════════════════════════════════════════

function PipelineConfig({ currentUser }) {
  const A = window.SDH_ADMIN;
  const [pipeline, setPipeline] = React.useState(A.pipeline);
  const [running, setRunning] = React.useState(false);

  function toggleCron() { setPipeline(p => ({ ...p, cron_enabled: !p.cron_enabled })); }
  function setFreq(h) { setPipeline(p => ({ ...p, cron_frequency_hours: h })); }
  function toggleSource(id) {
    setPipeline(p => ({ ...p, sources: p.sources.map(s => s.id === id ? { ...s, enabled: !s.enabled } : s) }));
  }
  function runAll() {
    setRunning(true);
    setTimeout(() => setRunning(false), 2400);
  }

  // Build hour-by-hour timeseries (7 days)
  const hourSeries = React.useMemo(() => {
    const m = {};
    pipeline.history.forEach(h => {
      const d = new Date(h.hour).toISOString().slice(0, 10);
      m[d] = (m[d] || 0) + h.count;
    });
    return Object.entries(m).slice(-7).map(([date, count]) => ({ date, count }));
  }, [pipeline.history]);

  const totalNew = hourSeries.reduce((s, d) => s + d.count, 0);

  return (
    <div className="sdh-fade">
      <PageHeader
        section="управление"
        title="Pipeline и источники"
        accent="pipeline"
        subtitle="Cron собирает новые стартапы из источников и обновляет корпус. Здесь видно состояние, последние ошибки и историю."
      />

      <section className="sdh-container" style={{ paddingBottom: 'var(--space-16)' }}>
        {/* Status row */}
        <div style={{
          display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 1fr', gap: 'var(--space-4)',
          marginBottom: 'var(--space-8)',
        }}>
          <div style={{
            background: 'var(--surface-elevated)',
            border: '1px solid var(--border-subtle)',
            borderRadius: 'var(--radius-xl)',
            padding: 'var(--space-6)',
            display: 'flex', alignItems: 'center', gap: 'var(--space-4)',
          }}>
            <div style={{
              width: 12, height: 12, borderRadius: '50%',
              background: running ? 'var(--success)' : pipeline.cron_enabled ? 'var(--success)' : 'var(--text-tertiary)',
              boxShadow: (running || pipeline.cron_enabled) ? '0 0 0 4px var(--hue-emerald-subtle)' : 'none',
              animation: running ? 'sdhPulse 1.2s ease-in-out infinite' : 'none',
              flexShrink: 0,
            }} />
            <div style={{ flex: 1 }}>
              <div className="sdh-mono-label" style={{ marginBottom: 2 }}>
                <InfoLabel
                  title="Статус cron"
                  what="Включён ли автоматический запуск pipeline. Cron делает прогон каждые N часов и добавляет новые стартапы из включённых источников."
                  why="Если выключен, корпус заморожен. Включите если ушли в отпуск надолго и хотите чтобы обновления продолжали идти. Выключите если активно меняете источники."
                >состояние cron</InfoLabel>
              </div>
              <div style={{ fontSize: 17, fontWeight: 600, color: 'var(--text-primary)' }}>
                {running ? 'идёт ручной прогон' : pipeline.cron_enabled ? `работает · каждые ${pipeline.cron_frequency_hours} часов` : 'остановлен'}
              </div>
              <div style={{ fontSize: 12.5, color: 'var(--text-tertiary)', marginTop: 4 }}>
                последний прогон: {fmtAgo2(pipeline.last_run_at)} · добавил {pipeline.last_run_count} стартапов
              </div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              <button className="sdh-btn sdh-btn--bronze" disabled={running} onClick={runAll}>
                {running ? 'идёт...' : 'Запустить вручную'}
              </button>
              <button className="sdh-btn sdh-btn--ghost" onClick={toggleCron} style={{ fontSize: 12 }}>
                {pipeline.cron_enabled ? 'остановить cron' : 'запустить cron'}
              </button>
            </div>
          </div>

          <MiniMetric label="всего за 7 дней" value={totalNew} suffix="стартапов" hue="emerald" />
          <MiniMetric label="источников" value={`${pipeline.sources.filter(s => s.enabled).length} / ${pipeline.sources.length}`} suffix="вкл" hue="info" />
          <MiniMetric label="ошибок за 24ч" value={pipeline.errors_24h.length} suffix={pipeline.errors_24h.length === 0 ? 'чисто' : 'требуют внимания'}
            hue={pipeline.errors_24h.length === 0 ? 'emerald' : 'rose'} />
        </div>

        {/* 7-day chart */}
        <div style={{
          background: 'var(--surface-elevated)',
          border: '1px solid var(--border-subtle)',
          borderRadius: 'var(--radius-xl)',
          padding: 'var(--space-6)',
          marginBottom: 'var(--space-6)',
        }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 'var(--space-4)' }}>
            <h3 className="sdh-section-label" style={{ marginBottom: 0 }}>
              <InfoLabel
                title="Новые стартапы по дням"
                what="Сколько новых записей добавил pipeline в каждый день за последнюю неделю."
                why="Плоская линия = источники молчат, надо проверить health. Резкий всплеск = либо был ивент в индустрии, либо в источник попал шум. Открывайте такой день и смотрите вручную."
              >новые стартапы за 7 дней</InfoLabel>
            </h3>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-tertiary)' }}>
              среднее: {Math.round(totalNew / 7)} / день
            </span>
          </div>
          <DayBars days={hourSeries} />
        </div>

        {/* Cron schedule (super_admin only) */}
        {currentUser.role === 'super_admin' && (
          <div style={{
            background: 'var(--surface-elevated)',
            border: '1px solid var(--border-subtle)',
            borderRadius: 'var(--radius-xl)',
            padding: 'var(--space-6)',
            marginBottom: 'var(--space-6)',
          }}>
            <h3 className="sdh-section-label">частота автозапуска</h3>
            <div style={{ display: 'flex', gap: 8, marginTop: 'var(--space-3)' }}>
              {[1, 3, 6, 12, 24].map(h => (
                <button key={h} className={`sdh-chip ${pipeline.cron_frequency_hours === h ? 'is-active' : ''}`}
                  onClick={() => setFreq(h)}>
                  каждые {h}ч
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Sources */}
        <div style={{
          background: 'var(--surface-elevated)',
          border: '1px solid var(--border-subtle)',
          borderRadius: 'var(--radius-xl)',
          padding: 'var(--space-6)',
          marginBottom: 'var(--space-6)',
        }}>
          <h3 className="sdh-section-label" style={{ display: 'block', marginBottom: 'var(--space-4)' }}>
            <InfoLabel
              title="Источники"
              what="Внешние каталоги, агрегаторы и инвестиционные базы, из которых pipeline тянет новые стартапы."
              why="Health-индикатор зелёный = источник отвечает. Жёлтый = медленные ответы или один сбой. Красный = упал, нужно проверить. Если несколько источников красные одновременно — проблема скорее в сети, чем в источниках."
            >источники сигнала</InfoLabel>
          </h3>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {pipeline.sources.map(s => <SourceRow key={s.id} source={s} onToggle={() => toggleSource(s.id)} />)}
          </div>
        </div>

        {/* Errors */}
        {pipeline.errors_24h.length > 0 && (
          <div style={{
            background: 'var(--hue-rose-subtle)',
            border: '1px solid var(--hue-rose)',
            borderRadius: 'var(--radius-xl)',
            padding: 'var(--space-6)',
          }}>
            <h3 className="sdh-section-label" style={{ display: 'block', marginBottom: 'var(--space-3)', color: 'var(--hue-rose)' }}>
              ошибки за 24 часа
            </h3>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {pipeline.errors_24h.map((e, i) => (
                <div key={i} style={{
                  display: 'grid', gridTemplateColumns: '100px 130px 1fr',
                  gap: 12, alignItems: 'center', padding: '8px 12px',
                  background: 'var(--surface-elevated)',
                  borderRadius: 'var(--radius-sm)',
                  fontSize: 12.5,
                }}>
                  <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text-tertiary)' }}>
                    {fmtAgo2(e.time)}
                  </span>
                  <span style={{ color: 'var(--text-primary)', fontWeight: 500 }}>{e.source}</span>
                  <span style={{ color: 'var(--text-secondary)' }}>{e.message}</span>
                </div>
              ))}
            </div>
          </div>
        )}
      </section>
    </div>
  );
}

function MiniMetric({ label, value, suffix, hue }) {
  return (
    <div className="sdh-warm-card" style={{
      '--bg-tint': `var(--hue-${hue}-subtle)`,
      padding: 'var(--space-4)',
    }}>
      <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})` }}>{value}</span>
        {suffix && <span style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{suffix}</span>}
      </div>
    </div>
  );
}

function DayBars({ days }) {
  const max = Math.max(...days.map(d => d.count), 1);
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 12, height: 120 }}>
      {days.map(d => {
        const h = (d.count / max) * 100;
        return (
          <div key={d.date} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6 }}>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-primary)' }}>{d.count}</span>
            <div style={{
              width: '100%', height: `${h}%`,
              background: 'var(--brand-bronze)',
              opacity: 0.7,
              borderRadius: 'var(--radius-sm)',
              minHeight: 2,
            }} />
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-tertiary)' }}>
              {d.date.slice(5)}
            </span>
          </div>
        );
      })}
    </div>
  );
}

function SourceRow({ source, onToggle }) {
  const healthCfg = {
    green: { hue: 'emerald', label: 'работает' },
    amber: { hue: 'amber',   label: 'медленно' },
    red:   { hue: 'rose',    label: 'ошибка' },
    grey:  { hue: 'info',    label: 'выключен' },
  }[source.health] || { hue: 'info', label: 'нет данных' };

  return (
    <div style={{
      display: 'grid', gridTemplateColumns: '20px 1fr 130px 130px 120px',
      gap: 12, alignItems: 'center',
      padding: '12px 14px',
      background: source.enabled ? 'var(--surface-elevated)' : 'var(--surface-sunken)',
      border: '1px solid var(--border-subtle)',
      borderRadius: 'var(--radius-md)',
    }}>
      <input type="checkbox" checked={source.enabled} onChange={onToggle}
        style={{ accentColor: 'var(--brand-bronze)' }} />
      <div>
        <div style={{ fontSize: 13.5, fontWeight: 500, color: source.enabled ? 'var(--text-primary)' : 'var(--text-tertiary)' }}>
          {source.name}
        </div>
        {source.note && (
          <div style={{ fontSize: 11.5, color: 'var(--text-tertiary)', fontStyle: 'italic', marginTop: 2 }}>{source.note}</div>
        )}
      </div>
      <StatusDot status="active" label={healthCfg.label} />
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-tertiary)' }}>
        {source.last_run ? fmtAgo2(source.last_run) : '—'}
      </span>
      <div style={{ display: 'flex', gap: 6, justifyContent: 'flex-end' }}>
        <button className="sdh-btn sdh-btn--ghost" style={{ fontSize: 11, padding: '4px 8px' }} disabled={!source.enabled}>
          тест
        </button>
      </div>
    </div>
  );
}

window.PipelineConfig = PipelineConfig;
