// Loading.jsx — full-screen loading splash that doubles as a session/data prefetch.
// onDone is called as ({ user, threads, settings }) once the server confirms the
// session and ships initial payloads. onAuthFailed is called if the token is bad.
function Loading({ onDone, onAuthFailed }) {
  const initialSteps = [
    { pct: 12, msg: '커널 부팅 · canon_lm_server' },
    { pct: 28, msg: '세션 토큰 검증' },
    { pct: 52, msg: '대화 목록 불러오는 중' },
    { pct: 78, msg: '설정 불러오는 중' },
    { pct: 100, msg: '준비 완료.' },
  ];
  const [i, setI] = React.useState(0);
  const [steps, setSteps] = React.useState(initialSteps);
  const [err, setErr] = React.useState(null);

  React.useEffect(() => {
    let cancelled = false;
    const advance = (idx, msg) => { if (!cancelled) { setSteps(s => { const c = s.slice(); if (msg) c[idx] = { ...c[idx], msg }; return c; }); setI(idx); } };

    (async () => {
      try {
        // Step 0: health
        advance(0);
        try { await window.API.health(); } catch (e) {
          throw new Error("Can't reach server at " + window.API.serverUrl);
        }

        // Step 1: /auth/me
        advance(1);
        let user;
        try { user = await window.API.me(); }
        catch (e) {
          if (e.status === 401) { onAuthFailed && onAuthFailed(); return; }
          throw e;
        }

        // Step 2: threads
        advance(2);
        let threads = [];
        try { threads = await window.API.listThreads(); } catch (_) { /* empty list is fine */ }

        // Step 3: settings
        advance(3, threads.length ? 'Loading settings · ' + threads.length + ' thread' + (threads.length === 1 ? '' : 's') : 'Loading settings');
        let settings = null;
        try { settings = await window.API.getSettings(); } catch (_) {}

        // Step 4: done
        advance(4);
        await new Promise(r => setTimeout(r, 220));
        if (!cancelled && onDone) onDone({ user, threads, settings });
      } catch (e) {
        if (!cancelled) setErr(e.message || String(e));
      }
    })();
    return () => { cancelled = true; };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const cur = steps[i] || steps[0];
  return (
    <div className="ch-loading" data-screen-label="Loading">
      <div className="mark">
        <div className="ring"></div>
        <div className="arc"></div>
        <img src="../../assets/zigu-logo-gold.png" alt="ZIGU"/>
      </div>
      <div className="wm">GBR</div>
      <h1>{err ? '연결 실패' : '작업 공간 준비 중'}</h1>
      <div className="status" style={err ? { color: 'var(--zg-danger)' } : null}>{err || cur.msg}</div>
      <div className="progress"><div className="bar" style={{width: (err ? 0 : cur.pct) + '%', background: err ? 'var(--zg-danger)' : undefined}}></div></div>
      <div className="meta">단계 {String(i+1).padStart(2,'0')} / {String(steps.length).padStart(2,'0')} · <span className="pct">{err ? '—' : cur.pct + '%'}</span></div>
      {err && (
        <div style={{marginTop: 24, display: 'flex', gap: 10}}>
          <button className="ad-btn" onClick={() => onAuthFailed && onAuthFailed()}>로그인 화면으로</button>
        </div>
      )}
    </div>
  );
}
window.Loading = Loading;
