// Single-page entry. Reads ?id=<uuid> from the URL:
//   - missing    → render the Projects landing page
//   - present    → render the Shot List editor for that project
//
// Runs after all other JSX modules have registered their globals
// (Rail/Header/ProjectSubheader/SceneGroup/ShotTable/DataInputModal/
//  ProjectsPage/ShotListApp/storage helpers).
//
// Boot strategy: render from the local cache *immediately* (localStorage is
// the snappy source of truth), then reconcile against Supabase in the
// BACKGROUND and nudge the UI to re-read storage when it finishes. Blocking
// the first paint on a network round-trip was what caused the post-sign-in
// "blank screen until it eventually loads". The only time we block is a
// fresh-device deep link straight to an editor URL whose project isn't in
// the local cache yet — there we show a small loading state, not a blank.

(async function mount() {
  // One-time migrations + cleanup before anything renders.
  window.migrateLegacyIfNeeded();
  window.purgeExpiredDeleted();

  const root   = ReactDOM.createRoot(document.getElementById('root'));
  const params = new URLSearchParams(location.search);
  const id     = params.get('id');
  const review = params.get('review');

  // Pick a view from whatever is in the local cache right now. Returns null
  // for an editor id that isn't present locally (caller decides what to do).
  const pickView = () => {
    // Client review route — a read-only reviewer experience. Takes priority
    // over the editor/projects logic and skips all owner-sync gating below.
    if (review) return <window.ReviewApp token={review} />;
    if (id) {
      const meta = (window.loadProjectsIndex() || []).find(p => p.id === id && !p.deletedAt);
      return meta ? <window.ShotListApp meta={meta} /> : null;
    }
    return <window.ProjectsPage />;
  };

  const renderResolved = () => {
    let view = pickView();
    if (id && !view) {
      // Editor id still not found (bad / stale / trashed / not synced) →
      // drop back to the projects list.
      history.replaceState(null, '', location.pathname);
      view = <window.ProjectsPage />;
    }
    root.render(view);
  };

  // A fresh-device deep link to an editor URL whose project isn't in the local
  // cache is the ONLY case with nothing to paint — there (and only there) we may
  // block on a reconcile, showing a loading state, never a blank. This check is
  // synchronous and cheap.
  const localHasId   = id && (window.loadProjectsIndex() || []).some(p => p.id === id && !p.deletedAt);
  const mayNeedBlock = id && !localHasId && !review;

  if (mayNeedBlock) {
    let uid = null;
    try { if (typeof window.ppGetUserIdAsync === 'function') uid = await window.ppGetUserIdAsync(); } catch (e) {}
    if (uid && !window.ppAlreadyReconciled(uid)) {
      root.render(
        <div style={{ display: 'grid', placeItems: 'center', height: '100vh',
                      color: 'var(--text-3)', fontFamily: 'var(--font-sans)', fontSize: 14 }}>
          Loading your shot list…
        </div>
      );
      try { await window.ppReconcileOnSignIn(); } catch (e) { console.warn('reconcile failed', e); }
    }
    renderResolved();
    return;
  }

  // Common path (projects list, locally-cached editor, reviewer): paint
  // IMMEDIATELY from the local cache — NEVER blocked on the network. Awaiting
  // auth/getSession before this first paint was what showed a BLACK SCREEN on the
  // post-Stripe-redirect load (?checkout=success): the returning token was stale,
  // so getSession did a slow network refresh before anything rendered. A reload
  // only "fixed" it because the token was warm by then.
  renderResolved();

  // …auth check + first-reconcile run entirely in the background, then nudge the
  // UI to re-read storage.
  (async () => {
    try {
      let uid = null;
      if (typeof window.ppGetUserIdAsync === 'function') uid = await window.ppGetUserIdAsync();
      if (uid && !window.ppAlreadyReconciled(uid)) {
        await window.ppReconcileOnSignIn();
        window.dispatchEvent(new CustomEvent('pp-projects-updated'));
      }
    } catch (e) { console.warn('background reconcile failed', e); }
  })();
})();
