// onboard.jsx — wizard root + step router.
//
// R03 / T0007 — wizard now writes into `workspaces/{wid}` (not the
// pre-R03 `accounts/{aid}`). The `onUserCreate` trigger mints the
// first workspace + membership atomically on user-doc creation; the
// wizard's job is to fill in display_name, modules, products, ICP,
// and Google-Workspace-connection state on that workspace.
//
// Routing is hash-free path-based: window.location.pathname drives
// which step shows. Firebase Hosting's SPA rewrite (firebase.json)
// sends every /onboard/* path to index.html, so the route lives in
// React.
//
// Loaded via index.html as a Babel-standalone <script>. Exposes
// window.Onboard.

(function (window) {
  'use strict';

  const { useAuth, AuthGate, signOut, db } = window.exoteamAuth || {};
  if (!useAuth) {
    console.error('onboard.jsx: window.exoteamAuth not loaded — check script order in index.html');
    return;
  }

  // R10 v2 (2026-06-04) — six-slot wizard. Module-specific setup
  // (voice / ICP / funder / audience) moved to native-app inline
  // empty-state panels per R11. See:
  //   docs/plan/roadmaps/R10_adaptive-onboarding/README.md (status update)
  //   docs/plan/roadmaps/R11_native-inline-onboarding/README.md
  const STEPS = [
    // 'welcome' is preamble — hidden from the progress bar (chromeless)
    // so the bar reads cleanly. Returning users (display_name already
    // set) skip past it on mount.
    { id: 'welcome', path: '/onboard/welcome', label: 'Welcome', chromeless: true },
    { id: 'signup', path: '/onboard/signup', label: 'Sign up' },
    { id: 'modules', path: '/onboard/modules', label: 'Pick modules' },
    { id: 'work', path: '/onboard/work', label: 'Your work' },
    { id: 'pair', path: '/onboard/pair', label: 'Get the desktop' },
    { id: 'done', path: '/onboard/done', label: 'Done' },
  ];
  const VISIBLE_STEPS = STEPS.filter((s) => !s.chromeless);

  function currentStepId() {
    const path = window.location.pathname || '/onboard/welcome';
    const match = STEPS.find((s) => path === s.path);
    return match ? match.id : 'welcome';
  }

  function navigate(stepId) {
    const step = STEPS.find((s) => s.id === stepId);
    if (!step) return;
    if (window.location.pathname !== step.path) {
      window.history.pushState({ step: step.id }, '', step.path);
      window.dispatchEvent(new PopStateEvent('popstate'));
    }
  }

  // ---------- root ----------
  function Onboard() {
    const [stepId, setStepId] = React.useState(currentStepId);
    React.useEffect(() => {
      const onPop = () => setStepId(currentStepId());
      window.addEventListener('popstate', onPop);
      return () => window.removeEventListener('popstate', onPop);
    }, []);

    return (
      <AuthGate>
        <OnboardChrome stepId={stepId} navigate={navigate}>
          <StepBody stepId={stepId} navigate={navigate} />
        </OnboardChrome>
      </AuthGate>
    );
  }

  function OnboardChrome({ stepId, navigate, children }) {
    const { userDoc } = useAuth();
    const currentStep = STEPS.find((s) => s.id === stepId);
    const chromeless = !!(currentStep && currentStep.chromeless);
    // For visible steps the progress bar uses VISIBLE_STEPS indices so
    // chromeless preamble doesn't shift the numbering. Chromeless steps
    // render with no progress bar (they aren't progress — they're prep).
    const stepIndex = VISIBLE_STEPS.findIndex((s) => s.id === stepId);
    return (
      <div className="exo-onboard">
        <header className="exo-onboard-bar">
          <img src="/lockup.svg" alt="exoteam" className="exo-onboard-logo" />
          {!chromeless && (
            <div className="exo-onboard-progress" role="progressbar"
              aria-valuemin="0" aria-valuemax={VISIBLE_STEPS.length - 1}
              aria-valuenow={stepIndex}>
              {VISIBLE_STEPS.map((s, i) => (
                <span
                  key={s.id}
                  className={
                    'exo-onboard-step ' +
                    (i < stepIndex ? 'exo-onboard-step--done ' : '') +
                    (i === stepIndex ? 'exo-onboard-step--current ' : '')
                  }
                  aria-current={i === stepIndex ? 'step' : undefined}
                >
                  {s.label}
                </span>
              ))}
            </div>
          )}
          <div className="exo-onboard-bar-right">
            {userDoc && userDoc.display_name && (
              <span className="exo-onboard-bar-user">Hi, {userDoc.display_name}</span>
            )}
            <button type="button" className="exo-link" onClick={() => signOut()}>
              Sign out
            </button>
          </div>
        </header>
        <main className="exo-onboard-main">{children}</main>
      </div>
    );
  }

  // R10 v2 — the wizard is straight-line; each step navigates to the
  // next id in STEPS directly. The earlier `nextAfter()` helper (which
  // resolved icp / funder / audience based on module + org_kind) was
  // removed when those steps moved to native R11 inline panels.

  // Resolve the previous step for any given step id. Returns null when
  // there's nowhere to go back (signup — no prior step; done — terminal).
  // Each step renders its own "← Back" button using this in its action
  // row (see onBack prop wired through StepBody).
  function prevStepFor(stepId) {
    const idx = STEPS.findIndex((s) => s.id === stepId);
    if (idx <= 0) return null;
    if (stepId === 'done') return null;
    return STEPS[idx - 1];
  }

  function StepBody({ stepId, navigate }) {
    const prev = prevStepFor(stepId);
    const onBack = prev ? () => navigate(prev.id) : null;
    switch (stepId) {
      case 'welcome':
        return <StepWelcome navigate={navigate} />;
      case 'signup':
        return <StepSignup navigate={navigate} />;
      case 'modules':
        return window.StepModules
          ? <window.StepModules
              onAdvance={() => navigate('work')}
              onSkip={() => navigate('work')}
              onBack={onBack}
            />
          : <ComingSoonStep stepId="modules" navigate={navigate} />;
      case 'work':
        return window.StepWork
          ? <window.StepWork navigate={navigate} onBack={onBack} />
          : <ComingSoonStep stepId="work" navigate={navigate} />;
      case 'pair':
        return window.StepPair
          ? <window.StepPair navigate={navigate} onBack={onBack} />
          : <ComingSoonStep stepId="pair" navigate={navigate} />;
      case 'done':
        return window.StepDone
          ? <window.StepDone navigate={navigate} />
          : <ComingSoonStep stepId="done" navigate={navigate} terminal />;
      default:
        return <ComingSoonStep stepId={stepId} navigate={navigate} />;
    }
  }

  // ---------- Step 0: Welcome / preamble ----------
  //
  // Pre-onboarding "what you're getting into" card. AuthGate has run,
  // so the user is signed in. Sets expectations: ~10-15 min, here's
  // what we'll cover, here's what to have ready, you can pause anytime.
  // Returning users (display_name already set) auto-skip to modules.
  function StepWelcome({ navigate }) {
    const { user, userDoc } = useAuth();
    React.useEffect(() => {
      // Returning user — skip the preamble straight to modules.
      // (R10 v1 routed through a chromeless voice step here; R10 v2
      // moved voice capture to a native-app inline panel — see R11.)
      if (userDoc && userDoc.display_name && userDoc.display_name.trim()) {
        navigate('modules');
      }
    }, [userDoc]);

    if (!userDoc) {
      // Wait for the user-doc snapshot rather than flashing the welcome.
      return <p className="exo-auth-body">Setting up your account…</p>;
    }

    const firstName = (() => {
      const email = (user && user.email) || '';
      const local = email.split('@')[0] || '';
      // Capitalise — "max" → "Max"; leave addresses with non-letter
      // chars alone (e.g. "team42" → "Team42").
      return local ? local.charAt(0).toUpperCase() + local.slice(1) : 'there';
    })();

    return (
      <div className="exo-step exo-welcome">
        <style>{`
.exo-welcome { max-width: 880px; margin: 0 auto; padding-top: 8px; }
.exo-welcome-eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--exo-ink-tertiary, #86868b); margin: 0 0 14px; }
.exo-welcome-title { font-size: 38px; letter-spacing: -0.025em; font-weight: 600; line-height: 1.08; color: var(--exo-ink, #1d1d1f); margin: 0 0 14px; }
.exo-welcome-lede { font-size: 17px; color: var(--exo-ink-secondary, #424245); line-height: 1.55; margin: 0 0 30px; max-width: 660px; }
.exo-welcome-lede strong { color: var(--exo-ink, #1d1d1f); font-weight: 600; }
.exo-welcome-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 30px; }
.exo-welcome-card { background: rgba(0,0,0,0.025); border: 1px solid rgba(0,0,0,0.05); border-radius: 16px; padding: 18px 20px 18px; }
.exo-welcome-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.exo-welcome-card-pip { width: 26px; height: 26px; border-radius: 8px; background: var(--exo-ink, #1d1d1f); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 12px; }
.exo-welcome-card-h { font-size: 14px; font-weight: 600; color: var(--exo-ink, #1d1d1f); margin: 0; letter-spacing: -0.01em; }
.exo-welcome-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.exo-welcome-list li { font-size: 13.5px; color: var(--exo-ink-secondary, #424245); line-height: 1.5; padding-left: 16px; position: relative; }
.exo-welcome-list li::before { content: ''; position: absolute; left: 0; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: var(--exo-ink-tertiary, #86868b); }
.exo-welcome-note { font-size: 13px; color: var(--exo-ink-tertiary, #86868b); margin: 0 0 22px; line-height: 1.55; max-width: 660px; }
.exo-welcome-cta-row { display: flex; align-items: center; gap: 16px; }
.exo-welcome-cta { font-family: inherit; font-size: 15px; font-weight: 500; padding: 12px 22px; border: none; border-radius: 10px; background: var(--exo-ink, #1d1d1f); color: #fff; cursor: pointer; transition: background 120ms ease, transform 80ms ease; }
.exo-welcome-cta:hover { background: #2a2a32; }
.exo-welcome-cta:active { transform: translateY(1px); }
@media (max-width: 900px) {
  .exo-welcome-grid { grid-template-columns: 1fr 1fr; }
  .exo-welcome-grid > :nth-child(3) { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
  .exo-welcome-title { font-size: 30px; }
  .exo-welcome-grid { grid-template-columns: 1fr; }
  .exo-welcome-grid > :nth-child(3) { grid-column: auto; }
}
        `}</style>
        <p className="exo-welcome-eyebrow">About 10–15 minutes</p>
        <h1 className="exo-welcome-title">Welcome, {firstName}. Let's set up your exoteam.</h1>
        <p className="exo-welcome-lede">
          We'll learn your work and your ideal customer, then connect Gmail / Calendar / Drive and pair the desktop app — the place the daily work actually runs. Plan for <strong>about 10–15 minutes</strong> of focused time.
        </p>

        <div className="exo-welcome-grid">
          <div className="exo-welcome-card">
            <div className="exo-welcome-card-head">
              <div className="exo-welcome-card-pip">1</div>
              <h3 className="exo-welcome-card-h">What we'll cover</h3>
            </div>
            <ul className="exo-welcome-list">
              <li>Pick modules (Sales, Grants, Proposals…)</li>
              <li>Describe your work — we enrich from your site</li>
              <li>Sketch your ideal customer</li>
              <li>Connect Google Workspace</li>
              <li>Download + pair the desktop app</li>
            </ul>
          </div>

          <div className="exo-welcome-card">
            <div className="exo-welcome-card-head">
              <div className="exo-welcome-card-pip">2</div>
              <h3 className="exo-welcome-card-h">Have ready</h3>
            </div>
            <ul className="exo-welcome-list">
              <li>Your company or studio website URL</li>
              <li>The Google account you'll send from</li>
              <li>A Mac — Windows / Linux land later</li>
              <li>~15 minutes without interruptions</li>
            </ul>
          </div>

          <div className="exo-welcome-card">
            <div className="exo-welcome-card-head">
              <div className="exo-welcome-card-pip">3</div>
              <h3 className="exo-welcome-card-h">Good to know</h3>
            </div>
            <ul className="exo-welcome-list">
              <li>You can pause anywhere — progress saves per step</li>
              <li>Skip any step you're not ready for</li>
              <li>Tokens stay in your OS keychain, not our cloud</li>
              <li>Trial: 14 days, no card required</li>
            </ul>
          </div>
        </div>

        <p className="exo-welcome-note">
          Signed in as <strong style={{ color: 'var(--exo-ink, #1d1d1f)' }}>{user.email}</strong> ·{' '}
          <button type="button" className="exo-link" onClick={() => signOut()}>
            not you?
          </button>
        </p>

        <div className="exo-welcome-cta-row">
          <button
            type="button"
            className="exo-welcome-cta"
            onClick={() => navigate('signup')}
          >
            Let's start →
          </button>
        </div>
      </div>
    );
  }

  // ---------- Step 1: Sign up + display name ----------
  //
  // The AuthGate has already proven the user is signed in by the time
  // we render here — so Step 1's only job is to capture display_name
  // if it isn't set yet, then advance to /onboard/work.
  function StepSignup({ navigate }) {
    const { user, userDoc } = useAuth();
    const [displayName, setDisplayName] = React.useState('');
    const [saving, setSaving] = React.useState(false);
    const [error, setError] = React.useState(null);

    // If the user already has a display_name, advance immediately.
    React.useEffect(() => {
      if (userDoc && userDoc.display_name && userDoc.display_name.trim()) {
        navigate('modules');
      }
    }, [userDoc]);

    async function handleSubmit(e) {
      e.preventDefault();
      const name = displayName.trim();
      if (!name) return;
      setSaving(true);
      setError(null);
      try {
        // Atomic batch: users + accounts both get the same display_name
        // at v1. The Cloud Function onUserCreate (F018T02) has already
        // created the accounts + memberships rows; this PATCH-style
        // update fills in the display_name.
        await persistDisplayName({ uid: user.uid, displayName: name });
        await advanceOnboarding({ uid: user.uid, nextStep: 'modules' });
        navigate('modules');
      } catch (err) {
        console.error('StepSignup: persistDisplayName failed', err);
        setError(err.message || String(err));
      } finally {
        setSaving(false);
      }
    }

    if (!userDoc) {
      // First-render: userDoc snapshot is still loading. Show a soft
      // skeleton rather than a flash of the name form.
      return <p className="exo-auth-body">Setting up your account…</p>;
    }

    return (
      <form className="exo-step exo-step--narrow" onSubmit={handleSubmit}>
        <h1 className="exo-step-title">Welcome — what should we call you?</h1>
        <p className="exo-step-body">
          Your name appears in your dashboard and on outreach drafts. You can
          change it later in Settings.
        </p>
        <label className="exo-auth-label" htmlFor="exo-display-name">
          Your name
        </label>
        <input
          id="exo-display-name"
          type="text"
          required
          autoFocus
          autoComplete="given-name"
          value={displayName}
          onChange={(e) => setDisplayName(e.target.value)}
          className="exo-auth-input"
          placeholder="First name or initials"
          disabled={saving}
        />
        {error && <p className="exo-auth-error">{error}</p>}
        <button
          type="submit"
          className="exo-auth-submit"
          disabled={saving || !displayName.trim()}
        >
          {saving ? 'Saving…' : 'Continue →'}
        </button>
        <p className="exo-auth-tos">
          Signed in as <strong>{user.email}</strong> ·{' '}
          <button type="button" className="exo-link" onClick={() => signOut()}>
            not you?
          </button>
        </p>
      </form>
    );
  }

  async function persistDisplayName({ uid, displayName }) {
    const batch = db.batch();
    const userRef = db.collection('users').doc(uid);
    batch.set(userRef, { display_name: displayName }, { merge: true });
    // The workspace + membership are created by the onUserCreate trigger;
    // we look up the workspace via memberships. v1 is one membership
    // per user at signup.
    const memberships = await db
      .collection('memberships')
      .where('user_id', '==', uid)
      .limit(1)
      .get();
    if (memberships.empty) {
      // The trigger hasn't fired yet — write the user-side and let the
      // onUserCreate trigger pick up the display_name from users.
      await batch.commit();
      return;
    }
    const workspaceId = memberships.docs[0].data().workspace_id;
    if (workspaceId) {
      const workspaceRef = db.collection('workspaces').doc(workspaceId);
      batch.set(workspaceRef, { display_name: displayName }, { merge: true });
    }
    await batch.commit();
  }

  // R03: onboarding state lives in `workspaces/{wid}.onboarding` map
  // (the standalone `onboarding/{uid}` collection is gone). The trigger
  // seeds the map; each step merges its progress in.
  async function advanceOnboarding({ uid, nextStep }) {
    const memberships = await db
      .collection('memberships')
      .where('user_id', '==', uid)
      .limit(1)
      .get();
    if (memberships.empty) return;
    const workspaceId = memberships.docs[0].data().workspace_id;
    if (!workspaceId) return;
    const ref = db.collection('workspaces').doc(workspaceId);
    await ref.set(
      {
        onboarding: {
          current_step: nextStep,
          completed_steps: firebase.firestore.FieldValue.arrayUnion({
            step: 'signup',
            at: firebase.firestore.Timestamp.now(),
          }),
          last_advanced_at: firebase.firestore.FieldValue.serverTimestamp(),
        },
      },
      { merge: true }
    );
  }

  // ---------- "Coming soon" stub for steps that haven't shipped yet ----------
  function ComingSoonStep({ stepId, navigate, terminal }) {
    return (
      <div className="exo-step exo-step--narrow">
        <h1 className="exo-step-title">Coming soon</h1>
        <p className="exo-step-body">
          Step <code>{stepId}</code> isn't built yet. The desktop client
          flow lands in F018 Phases 2-4.
        </p>
        {!terminal && (
          <button
            type="button"
            className="exo-auth-submit"
            onClick={() => navigate('done')}
          >
            Skip to dashboard →
          </button>
        )}
      </div>
    );
  }

  // ---------- expose ----------
  window.Onboard = Onboard;
  window.exoteamOnboard = { Onboard, STEPS, navigate };
})(window);
