// SRI App — J1 Onboarding (7a–7h), matured from Onboarding Flow.html.
// Design rules honored: work-email seeds org identity (7a) · workspace = boundary (7b) ·
// ground rules taught with real components (7c) · role is personalization, never permission (7d) ·
// sources are role-ranked, private-by-default, read-only (7e) · the first build shows honest
// emerging progress and ends STAGED, never committed (7f) · invite is skippable, permissions
// are two verbs (7g) · onboarding ends when the agent has something to show (7h → the reveal).

const OB = () => window.SRIData.onboarding;

const OB_STEPS = ["signin", "workspace", "rules", "role", "connect", "build", "invite", "handoff"];

function ObSteps({ step }) {
  const idx = OB_STEPS.indexOf(step);
  // signin has no steps bar (pre-flow); handoff shows all done
  if (idx <= 0) return null;
  return (
    <div className="obSteps" aria-hidden="true">
      {OB_STEPS.slice(1, 7).map((s, i) => (
        <i key={s} className={i + 1 < idx ? "done" : i + 1 === idx ? "on" : ""}></i>
      ))}
    </div>
  );
}

function ObCheckIcon() {
  return (
    <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"
      strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"></path></svg>
  );
}

// ── 7f — the first build, honest emerging progress ───────────────────────
// Runs on a shared controller so the build keeps ticking if the user moves on.
function useFirstBuild(started) {
  const [phase, setPhase] = React.useState(0);       // index of running phase; 4 = done
  const [counts, setCounts] = React.useState({ invoices: 0, businesses: 0, dormant: 0, staged: 0 });
  const timers = React.useRef([]);
  React.useEffect(() => () => timers.current.forEach(clearTimeout), []);
  React.useEffect(() => {
    if (!started) return;
    const later = (ms, fn) => { const id = setTimeout(fn, ms); timers.current.push(id); };
    let inv = 0, biz = 0, dor = 0, stg = 0;
    const tick = () => {
      inv = Math.min(4200, inv + 380 + Math.floor(Math.random() * 260));
      biz = Math.min(312, Math.floor(inv / 13.5));
      dor = Math.min(9, Math.floor(biz / 36));
      stg = Math.min(2941, Math.floor(inv * 0.62));
      setCounts({ invoices: inv, businesses: biz, dormant: dor, staged: stg });
      if (inv < 4200) later(420, tick);
    };
    later(400, tick);
    later(2200, () => setPhase(1));
    later(4600, () => setPhase(2));
    later(6600, () => setPhase(3));
    later(8400, () => setPhase(4));
  }, [started]);
  return { phase, counts, done: phase >= 4 };
}

function Onboarding({ onDone }) {
  const ob = OB();
  const [step, setStep] = React.useState("signin");
  const [role, setRole] = React.useState("procurement");
  const [sources, setSources] = React.useState(() => ob.sources.filter((s) => s.on).map((s) => s.id));
  const [buildStarted, setBuildStarted] = React.useState(false);
  const build = useFirstBuild(buildStarted);
  const nowT = () => new Date().toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
  const [t0] = React.useState(nowT);

  const finish = (skipped) => onDone({ role, sources, skipped: !!skipped, buildDone: build.done });
  const next = (s) => setStep(s);
  const toggleSource = (id) => setSources((xs) => (xs.includes(id) ? xs.filter((x) => x !== id) : xs.concat([id])));

  const skipBtn = step !== "handoff" && (
    <button type="button" className="obSkip" onClick={() => finish(true)}
      title="Jump straight to the working desk on the demo workspace">Skip — use the demo workspace</button>
  );

  // ── 7a sign in ──
  if (step === "signin") return (
    <div className="obRoot" data-screen-label="7a Sign in">{skipBtn}
      <div className="obPanel">
        <div className="obBrand"><img src={(window.__resources && window.__resources.wordmark) || "../../assets/stimulus-wordmark.svg"} alt="Stimulus" /></div>
        <h1>The first B2B Relationship Intelligence layer that treats procurement data as a shared organizational asset. Every business relationship is a potential vendor, customer, partner, and more.</h1>
        <p className="obLede">Connect your work email and calendar to bring your relationships into Stimulus.</p>
        <button type="button" className="obProvider" onClick={() => next("workspace")}>
          <svg viewBox="0 0 48 48" aria-hidden="true"><path fill="#4285F4" d="M45.12 24.5c0-1.56-.14-3.06-.4-4.5H24v8.51h11.84c-.51 2.75-2.06 5.08-4.39 6.64v5.52h7.11c4.16-3.83 6.56-9.47 6.56-16.17z"></path><path fill="#34A853" d="M24 46c5.94 0 10.92-1.97 14.56-5.33l-7.11-5.52c-1.97 1.32-4.49 2.1-7.45 2.1-5.73 0-10.58-3.87-12.31-9.07H4.34v5.7C7.96 41.07 15.4 46 24 46z"></path><path fill="#FBBC05" d="M11.69 28.18c-.44-1.32-.69-2.73-.69-4.18s.25-2.86.69-4.18v-5.7H4.34A21.98 21.98 0 0 0 2 24c0 3.55.85 6.91 2.34 9.88l7.35-5.7z"></path><path fill="#EA4335" d="M24 10.75c3.23 0 6.13 1.11 8.41 3.29l6.31-6.31C34.91 4.18 29.93 2 24 2 15.4 2 7.96 6.93 4.34 14.12l7.35 5.7c1.73-5.2 6.58-9.07 12.31-9.07z"></path></svg>
          Continue with Google
        </button>
        <button type="button" className="obProvider" onClick={() => next("workspace")}>
          <svg viewBox="0 0 23 23" aria-hidden="true"><path fill="#F25022" d="M1 1h10v10H1z"></path><path fill="#7FBA00" d="M12 1h10v10H12z"></path><path fill="#00A4EF" d="M1 12h10v10H1z"></path><path fill="#FFB900" d="M12 12h10v10H12z"></path></svg>
          Continue with Microsoft
        </button>
        <span className="obHint" style={{ textAlign: "center" }}>Signing in as <b>{ob.user.email}</b> for this demo.</span>
        <span className="obHint" style={{ textAlign: "center", borderTop: "1px dashed var(--border-strong)", paddingTop: 14, marginTop: 6 }}>
          By using Stimulus you agree to the <a href="#terms" onClick={(e) => e.preventDefault()}>Terms of Service</a> and <a href="#privacy" onClick={(e) => e.preventDefault()}>Privacy Policy</a>.</span>
      </div>
    </div>
  );

  // ── 7b workspace = boundary ──
  if (step === "workspace") return (
    <div className="obRoot" data-screen-label="7b Workspace"><ObSteps step={step} />{skipBtn}
      <div className="obPanel">
        <h1>Create your workspace</h1>
        <p className="obLede">A workspace is an organization's boundary. Facts marked "org" are visible to everyone
          inside it — and to no one outside it unless you explicitly share.</p>
        <div className="obField">
          <label>Workspace name</label>
          <div className="obInput"><input defaultValue={ob.workspace.name} aria-label="Workspace name" /></div>
        </div>
        <div className="obField">
          <label>Organization domain</label>
          <div className="obInput">
            <span>{ob.workspace.domain}</span>
            <span className="obVerified"><ObCheckIcon /> Verified from your email</span>
          </div>
          <span className="obHint">Teammates who sign in with this domain can ask to join. You approve each one.</span>
        </div>
        <button type="button" className="obBtn" onClick={() => next("rules")}>Create {ob.workspace.name}</button>
      </div>
    </div>
  );

  // ── 7c ground rules ──
  if (step === "rules") return (
    <div className="obRoot" data-screen-label="7c Ground rules"><ObSteps step={step} />{skipBtn}
      <div className="obPanel isWide">
        <h1>Three rules that never bend</h1>
        <p className="obLede">Everything else about Stimulus follows from these.</p>
        <div className="obCard">
          <div className="obRule">
            <span className="ic"><Icon name="check" size={13} /></span>
            <div>
              <div className="t">Nothing is written without you</div>
              <div className="d">Agents and imports only propose. You approve, deny, or suggest a change — nothing moves until you decide.</div>
            </div>
          </div>
          <div className="obRule">
            <span className="ic"><Icon name="list" size={13} /></span>
            <div>
              <div className="t">Everything leaves a receipt</div>
              <div className="d">Every change — including your denials — is written to an append-only record you can audit, always.</div>
            </div>
          </div>
          <div className="obRule">
            <span className="ic"><Icon name="eye" size={13} /></span>
            <div>
              <div className="t">Every fact knows who may see it</div>
              <div className="d">Visibility travels with the data, field by field:</div>
              <div className="obChips">
                <window.StimulusDesignSystem_bb8fa3.ConsentChip level="private" />
                <window.StimulusDesignSystem_bb8fa3.ConsentChip level="org" />
                <window.StimulusDesignSystem_bb8fa3.ConsentChip level="shared" />
              </div>
            </div>
          </div>
        </div>
        <button type="button" className="obBtn" onClick={() => next("role")}>I'll hold you to it</button>
      </div>
    </div>
  );

  // ── 7d role — personalization, not permission ──
  if (step === "role") return (
    <div className="obRoot" data-screen-label="7d Role"><ObSteps step={step} />{skipBtn}
      <div className="obPanel isWide">
        <h1>What do you work on?</h1>
        <p className="obLede">This tunes your desk — what your brief leads with and which sources we suggest.
          It's not a permission; you can change it any time.</p>
        <div className="obCard">
          {ob.roles.map((r) => (
            <button key={r.id} type="button" className={"obRole" + (role === r.id ? " sel" : "")} onClick={() => setRole(r.id)}>
              <span className={"obRadio" + (role === r.id ? " on" : "")}></span>
              <span style={{ minWidth: 0 }}>
                <span className="t">{r.t}</span>
                <span className="d" style={{ display: "block" }}>{r.d}</span>
                {role === r.id && <span className="lead">Brief leads with → {r.lead}</span>}
              </span>
            </button>
          ))}
        </div>
        <span className="obHint">This demo workspace follows the LA28 procurement fixture — Priya Nair's desk.</span>
        <button type="button" className="obBtn" onClick={() => next("connect")}>
          Continue as {ob.roles.find((r) => r.id === role).t}</button>
      </div>
    </div>
  );

  // ── 7e connect — files they already collect; no OAuth required for the aha ──
  if (step === "connect") return (
    <div className="obRoot" data-screen-label="7e Connect"><ObSteps step={step} />{skipBtn}
      <div className="obPanel isWide">
        <h1>Connect what you already have</h1>
        <p className="obLede">Everything lands private to you. Nothing becomes org-visible or shared without your say-so, ever.</p>
        <div className="obCard">
          {ob.sources.map((s) => (
            <button key={s.id} type="button" className="obSrc" onClick={() => toggleSource(s.id)}>
              <span className="logo">{s.logo}</span>
              <span style={{ flex: 1, minWidth: 0 }}>
                <span className="t">{s.t}{s.rec && <span className="obRec">{s.rec}</span>}</span>
                <span className="d" style={{ display: "block" }}>{s.d}</span>
              </span>
              <span className={"obCheck" + (sources.includes(s.id) ? " on" : "")}></span>
            </button>
          ))}
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button type="button" className="obBtn" style={{ flex: 1 }} disabled={sources.length === 0}
            onClick={() => { setBuildStarted(true); next("build"); }}>
            Connect {sources.length} source{sources.length === 1 ? "" : "s"}</button>
          <button type="button" className="obGBtn" onClick={() => finish(true)}>Skip — start empty</button>
        </div>
        <span className="obHint" style={{ textAlign: "center" }}>Read-only access. Stimulus never sends, edits, or deletes anything in your systems.</span>
      </div>
    </div>
  );

  // ── 7f the first build — honest progress, value teasers, skippable wait ──
  if (step === "build") {
    const phases = ob.phases;
    return (
      <div className="obRoot" data-screen-label="7f First build"><ObSteps step={step} />{skipBtn}
        <div className="obPanel isWide">
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <h1 style={{ flex: 1 }}>Building {ob.workspace.name}'s graph</h1>
            <span className="obRunChip">
              {build.done
                ? <React.Fragment><span style={{ color: "var(--green-11)", display: "inline-flex" }}><ObCheckIcon /></span>Done</React.Fragment>
                : <React.Fragment><span className="obDotRun"></span>Running · {Math.min(build.phase + 1, 4)} of 4</React.Fragment>}
            </span>
          </div>
          <p className="obLede">Reading your {sources.length} sources into a first version of {ob.workspace.name}'s relationship graph.
            Everything below stays private to you until you approve it.</p>
          <div className="obCard">
            {phases.map((p, i) => (
              <div key={p.id} className="obPhase">
                {i < build.phase
                  ? <span style={{ color: "var(--green-9)", alignSelf: "center", display: "inline-flex" }}><ObCheckIcon /></span>
                  : i === build.phase ? <span className="obDotRun"></span> : <span className="obDotWait"></span>}
                <span className={"t" + (i < build.phase ? " isDone" : i > build.phase ? " isNext" : "")}>{p.t}</span>
                <span className="n tabular">{i < build.phase ? p.detail : i === build.phase ? liveDetail(p.id, build.counts) : "next"}</span>
              </div>
            ))}
          </div>
          <div className="obCard obTease">
            <span className="line tabular">
              <b>{build.counts.businesses} businesses</b> found so far · <b>{build.counts.dormant} look dormant</b> — your reveal is
              {build.done ? " ready" : " ~" + Math.max(1, 4 - build.phase) + " minutes away"}.
            </span>
            <span className="obHint">Value, not theater: these are live counts from your files, and nothing is committed.</span>
          </div>
          <button type="button" className="obGBtn" onClick={() => next("invite")}>
            Continue setup — the build keeps running</button>
          <span className="obHint" style={{ textAlign: "center" }}>Your reveal opens on partial data if you get there first — the rest streams in.</span>
        </div>
      </div>
    );
  }

  // ── 7g invite — skippable; permissions are two verbs, kept apart from role ──
  if (step === "invite") return (
    <div className="obRoot" data-screen-label="7g Invite"><ObSteps step={step} />{skipBtn}
      <div className="obPanel">
        <h1>Bring {ob.workspace.name} in — now or later</h1>
        <p className="obLede">Stimulus works solo from day one. Most people invite the team after their first week,
          once there's a record worth showing.</p>
        <div className="obField">
          <label>Invite by email</label>
          <div className="obInput"><input placeholder="marco@la28.org, dana@la28.org…" aria-label="Invite by email" /></div>
        </div>
        <div className="obCard">
          <div className="obPermRow">
            <span style={{ flex: 1 }}>
              <span className="t" style={{ display: "block" }}>Can approve and deny changes</span>
              <span className="obHint">Decides proposals in their areas</span>
            </span>
            <span style={{ width: 14, height: 14, borderRadius: "50%", border: "4.5px solid var(--green-9)", flex: "none" }}></span>
          </div>
          <div className="obPermRow">
            <span style={{ flex: 1 }}>
              <span className="t" style={{ display: "block" }}>Can read the record</span>
              <span className="obHint">Sees org-visible facts and receipts; proposes, never commits</span>
            </span>
            <span style={{ width: 14, height: 14, borderRadius: "50%", border: "1.5px solid var(--border-strong)", flex: "none" }}></span>
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button type="button" className="obBtn" style={{ flex: 1 }} onClick={() => next("handoff")}>Send invites</button>
          <button type="button" className="obGBtn" style={{ flex: 1 }} onClick={() => next("handoff")}>Skip for now</button>
        </div>
      </div>
    </div>
  );

  // ── 7h handoff — onboarding ends at your first decision ──
  const h = ob.handoff;
  return (
    <div className="obRoot" data-screen-label="7h Handoff">{skipBtn}
      <div className="obPanel isWide" style={{ alignItems: "center", textAlign: "center" }}>
        <img src={(window.__resources && window.__resources.mark) || "../../assets/stimulus-mark.svg"} alt="" style={{ height: 34, marginBottom: 4 }} />
        <h1 style={{ textAlign: "center" }}>{ob.workspace.name}'s graph, version one</h1>
        <p className="obLede" style={{ textAlign: "center" }}>
          {build.done ? "The first build is done." : "The first build is still finishing — enough has landed to show you something real."}{" "}
          Nothing is committed yet — it's all waiting on you.</p>
        <div className="obCard obStats">
          <span className="obStat"><span className="n tabular">{build.done ? h.entities : build.counts.businesses}</span><span className="obHint">entities</span></span>
          <span className="obStat"><span className="n tabular">{build.done ? h.relationships.toLocaleString() : "…"}</span><span className="obHint">relationships</span></span>
          <span className="obStat"><span className="n tabular">{build.done ? h.facts.toLocaleString() : build.counts.staged.toLocaleString()}</span><span className="obHint">facts staged</span></span>
          <span className="obStat"><span className="n tabular" style={{ color: "var(--destructive-fg, oklch(0.5 0.19 12))" }}>{build.done ? h.setAside : "…"}</span><span className="obHint">set aside</span></span>
        </div>
        <div className="obCard" style={{ width: "100%", textAlign: "left" }}>
          <div className="obEvent"><span className="dot"></span>Workspace created — {ob.workspace.domain} verified · you<span className="time tabular">{t0}</span></div>
          <div className="obEvent"><span className="dot"></span>First build — {sources.length} sources read · nothing committed<span className="time tabular">{nowT()}</span></div>
        </div>
        <button type="button" className="obBtn" style={{ width: "100%" }} onClick={() => finish(false)}>
          Open your desk — the reveal is waiting on you</button>
        <span className="obHint">Set-aside items aren't discarded — they wait for you with their reasons.</span>
      </div>
    </div>
  );
}

function liveDetail(phaseId, c) {
  if (phaseId === "read") return c.invoices.toLocaleString() + " invoices read…";
  if (phaseId === "resolve") return c.businesses + " businesses · merging duplicates…";
  if (phaseId === "detect") return c.dormant + " dormant found so far…";
  return c.staged.toLocaleString() + " facts staged…";
}

Object.assign(window, { Onboarding });
