function NginxHealth({ nginx }) {
  if (nginx.error) {
    return <div className="profile-card" style={{ maxWidth: 'none', marginBottom: 20 }}><h3 style={{ marginTop: 0 }}>Nginx</h3><p style={{ color: 'var(--red)' }}>{nginx.error}</p></div>;
  }
  const errors = nginx.errors || {};
  const bad = !nginx.ok;
  return (
    <div className="profile-card" style={{ maxWidth: 'none', marginBottom: 20 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <h3 style={{ margin: 0 }}>Nginx</h3>
        <span style={{ fontSize: 12, fontWeight: 700, color: bad ? 'var(--red)' : 'var(--green)' }}>{bad ? 'DEGRADED' : 'OK'}</span>
      </div>
      <p style={{ fontSize: 12, color: 'var(--text-dim)', margin: '6px 0 12px' }}>
        Probes go through port 443. Errors are from the last {nginx.window}.
      </p>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 16, marginBottom: 12 }}>
        {(nginx.probes || []).map(p => (
          <div key={p.name}>
            <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>{p.name}</div>
            <div style={{ fontWeight: 650, color: p.status >= 500 || p.status === 0 ? 'var(--red)' : 'inherit' }}>
              {p.status || p.error} · {p.ms} ms
            </div>
          </div>
        ))}
        <div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Upstream resets</div>
          <div style={{ fontWeight: 650, color: errors.upstream_reset ? 'var(--red)' : 'inherit' }}>{errors.upstream_reset || 0}</div>
        </div>
        <div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Timeouts</div>
          <div style={{ fontWeight: 650, color: errors.timeout ? 'var(--red)' : 'inherit' }}>{errors.timeout || 0}</div>
        </div>
        <div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Connect failures</div>
          <div style={{ fontWeight: 650, color: errors.connect ? 'var(--red)' : 'inherit' }}>{errors.connect || 0}</div>
        </div>
      </div>
      {(nginx.recent || []).length > 0 && (
        <pre style={{ margin: 0, fontSize: 11, whiteSpace: 'pre-wrap', color: 'var(--text-dim)' }}>{nginx.recent.join('\n')}</pre>
      )}
    </div>
  );
}

function formatBytes(bytes) {
  if (bytes == null) return '—';
  if (bytes < 1048576) return (bytes / 1024).toFixed(0) + ' KB';
  if (bytes < 1073741824) return (bytes / 1048576).toFixed(0) + ' MB';
  return (bytes / 1073741824).toFixed(2) + ' GB';
}

function HostHealthPage() {
  const [data, setData] = useState(null);
  const [fleet, setFleet] = useState(null);
  const [error, setError] = useState('');
  const [fleetError, setFleetError] = useState('');
  const [busy, setBusy] = useState('');
  const loading = useRef(false);

  const load = useCallback(async () => {
    if (loading.current) return;
    loading.current = true;
    try {
      const [host, apps] = await Promise.all([
        api('/api/admin/host'),
        api('/api/render/admin/fleet').then(data => ({ data, error: '' })).catch(e => ({ data: null, error: e.message })),
      ]);
      setData(host);
      setFleet(apps.data);
      setFleetError(apps.error);
      setError('');
    } catch (e) {
      setError(e.message || 'Could not load host health');
    } finally {
      loading.current = false;
    }
  }, []);

  useEffect(() => {
    load();
    const timer = setInterval(load, 15000);
    return () => clearInterval(timer);
  }, [load]);

  const act = async (name, action) => {
    const verb = action === 'restart' ? 'Restart' : 'Stop';
    if (!confirm(`${verb} ${name}?`)) return;
    setBusy(name + action);
    try {
      await api(`/api/admin/host/containers/${name}/${action}`, { method: 'POST' });
      await load();
    } catch (e) {
      setError(e.message || `${verb} failed`);
    } finally {
      setBusy('');
    }
  };

  const host = data?.host;
  const usedPct = host?.mem_total_bytes && host.mem_used_bytes != null
    ? Math.round((host.mem_used_bytes / host.mem_total_bytes) * 100)
    : null;
  const load1 = host?.load?.[0];
  const loadHot = host?.cpu_count && load1 > host.cpu_count;

  return (
    <>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
        <h2 style={{ margin: 0 }}>Health</h2>
        <button type="button" className="btn-sm btn-ghost" onClick={load}>↻ Refresh</button>
      </div>
      <div className="page-sub" style={{ marginBottom: 24 }}>
        Memory, CPU, nginx, and every container on this VPS. Admin only.
      </div>
      {error && <p style={{ color: 'var(--red)', marginBottom: 16 }}>{error}</p>}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 12, marginBottom: 20 }}>
        <div className="profile-card" style={{ maxWidth: 'none' }}>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Memory</div>
          <div style={{ fontSize: 22, fontWeight: 650, marginTop: 4 }}>
            {host ? `${formatBytes(host.mem_used_bytes)} / ${formatBytes(host.mem_total_bytes)}` : '…'}
          </div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>{usedPct != null ? `${usedPct}% used` : ''}</div>
        </div>
        <div className="profile-card" style={{ maxWidth: 'none' }}>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Load</div>
          <div style={{ fontSize: 22, fontWeight: 650, marginTop: 4, color: loadHot ? 'var(--red)' : 'inherit' }}>
            {load1 != null ? load1.toFixed(2) : '…'}
          </div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>
            {host ? `${host.cpu_count} cores · ${host.load?.map(n => n.toFixed(2)).join('  ')}` : ''}
          </div>
        </div>
        <div className="profile-card" style={{ maxWidth: 'none' }}>
          <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>Containers</div>
          <div style={{ fontSize: 22, fontWeight: 650, marginTop: 4 }}>{data ? data.containers.length : '…'}</div>
          <div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>
            {data ? `${data.containers.filter(c => c.status === 'running').length} running` : ''}
          </div>
        </div>
      </div>

      {data?.nginx && <NginxHealth nginx={data.nginx} />}

      <div className="profile-card" style={{ maxWidth: 'none', marginBottom: 20 }}>
        <h3 style={{ marginTop: 0 }}>Services</h3>
        {(data?.containers || []).map((c, i) => (
          <div key={c.name} style={{
            display: 'grid',
            gridTemplateColumns: '1.4fr 90px 70px 120px auto',
            gap: 12,
            alignItems: 'center',
            padding: '10px 0',
            borderTop: i === 0 ? 'none' : '1px solid var(--border)',
          }}>
            <div>
              <div style={{ fontWeight: 600 }}>{c.name}</div>
              <div style={{ fontSize: 12, color: c.oom_killed ? 'var(--red)' : 'var(--text-dim)' }}>
                {c.status}{c.oom_killed ? ' · OOM killed' : ''}{c.restart_count ? ` · ${c.restart_count} restarts` : ''}
              </div>
            </div>
            <span>{c.status === 'running' ? `${c.cpu_percent}% CPU` : '—'}</span>
            <span style={{ color: c.mem_percent > 80 ? 'var(--red)' : 'inherit' }}>
              {c.status === 'running' && c.mem_percent != null ? `${c.mem_percent}%` : '—'}
            </span>
            <span>{c.status === 'running' ? `${formatBytes(c.mem_bytes)} / ${formatBytes(c.mem_limit_bytes)}` : '—'}</span>
            <span style={{ display: 'flex', gap: 6, justifyContent: 'flex-end' }}>
              <button type="button" className="btn-sm btn-ghost" disabled={!!busy} onClick={() => act(c.name, 'restart')}>
                {busy === c.name + 'restart' ? '…' : 'Restart'}
              </button>
              {c.name !== 'vibey-app' && c.status === 'running' && (
                <button type="button" className="btn-sm btn-ghost" disabled={!!busy} style={{ color: 'var(--red)' }} onClick={() => act(c.name, 'stop')}>
                  {busy === c.name + 'stop' ? '…' : 'Stop'}
                </button>
              )}
            </span>
          </div>
        ))}
      </div>

      <div className="profile-card" style={{ maxWidth: 'none' }}>
        <h3 style={{ marginTop: 0 }}>Render apps</h3>
        <p style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 0 }}>
          These run inside vibey-render. CPU is a share of the whole machine.
        </p>
        {fleetError && <p style={{ color: 'var(--red)' }}>{fleetError}</p>}
        {!fleet && !fleetError && <p style={{ color: 'var(--text-dim)' }}>Loading Render apps…</p>}
        {(fleet?.projects || []).map((p, i) => (
          <div key={p.id} style={{
            display: 'grid',
            gridTemplateColumns: '1.4fr 120px 80px 80px',
            gap: 12,
            alignItems: 'center',
            padding: '10px 0',
            borderTop: i === 0 ? 'none' : '1px solid var(--border)',
          }}>
            <div>
              <div style={{ fontWeight: 600 }}>{p.name}</div>
              <div style={{ fontSize: 12, color: 'var(--text-dim)' }}>{p.owner || 'unknown'} · {p.id}</div>
            </div>
            <span style={{ color: renderStatusColor(p.status, p.live), fontWeight: 600, fontSize: 12, textTransform: 'uppercase' }}>
              {p.live ? 'live' : p.status}
            </span>
            <span>{p.live ? `${p.cpu_percent ?? 0}%` : '—'}</span>
            <span>{p.live ? formatBytes(p.rss_bytes) : '—'}</span>
          </div>
        ))}
        {fleet && (fleet.projects || []).length === 0 && <p style={{ color: 'var(--text-dim)' }}>No Render apps.</p>}
      </div>
    </>
  );
}
