// ─────────────────────────────────────────────────────────────────────────
// auth.jsx — multi-step auth UI shell. Dispatches to step components
// (SignupStep, LoginStep, MfaEnrollStep, MfaVerifyStep, BackupCodesStep)
// loaded via auth-steps/*.jsx.
//
// FEATURES.auth — when off, every kind shows an "Invite required" state.
// ─────────────────────────────────────────────────────────────────────────

function BSAuthShell({ kind }) {
  const featureOn = (window.FEATURES || {}).auth === true;
  const [step, setStep] = React.useState(() => initialStep(kind));
  const data = AUTH[step] || AUTH[kind];

  function initialStep(k) {
    if (k === "signup") {
      const hash = window.location.hash.slice(1);
      if (hash === "mfa-enroll") return "mfaEnroll";
      if (hash === "backup-codes") return "backupCodes";
      return "signup";
    }
    if (k === "verify") {
      // If the URL has a token, the user just clicked the email verify link
      // → run the OPAQUE register flow (set password). Otherwise show the
      // informational "check your email" state.
      const hasToken = new URLSearchParams(window.location.search).has("token");
      return hasToken ? "setPassword" : "verify";
    }
    return k;
  }

  return (
    <div className="bs-auth">
      <aside className="bs-auth-brand">
        <a href="/" className="bs-auth-mark">
          <span className="bs-auth-wordmark">{AUTH.brand.eyebrow}</span>
          <span className="bs-auth-tagline">{AUTH.brand.tagline}</span>
        </a>
        <div className="bs-auth-quote">
          <p>"Every commit, analyzed. By an engine that reasons about state, not signatures."</p>
        </div>
        <div className="bs-auth-meta">
          <span>{SITE.domain}</span>
          <span>© 2026</span>
        </div>
      </aside>
      <main className="bs-auth-form-panel">
        <header className="bs-auth-header">
          <a href="/" className="bs-auth-back">← Back to {SITE.name}</a>
          {kind !== "signup" && (
            <a href="/auth/signup.html" className="bs-auth-altcta">Create account</a>
          )}
          {kind === "signup" && (
            <a href="/auth/login.html" className="bs-auth-altcta">Sign in</a>
          )}
        </header>
        <div className="bs-auth-body">
          <p className="bs-eyebrow">{data?.eyebrow}</p>
          <h1 className="bs-auth-h">{data?.headline}</h1>
          {data?.lede && <p className="bs-auth-lede">{data.lede}</p>}
          {!featureOn ? <LockedState /> : renderStep(step, setStep, data)}
        </div>
        <footer className="bs-auth-footer">
          <a href="/privacy.html">Privacy</a>
          <a href="/terms.html">Terms</a>
          <a href="/disclose.html">Disclose a vulnerability</a>
        </footer>
      </main>
    </div>
  );
}

function LockedState() {
  return (
    <div className="bs-auth-locked">
      <div className="bs-auth-locked-bar" aria-hidden="true">
        <span></span><span></span><span></span>
      </div>
      <h2 className="bs-auth-locked-h">Invite required.</h2>
      <p>
        Accounts are currently issued only to verification partners and platform-beta participants.
        If you've been invited, the activation link in your email bypasses this screen.
      </p>
      <a className="bs-cta" href="/waitlist.html">
        <span>Request an invite</span>
        <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
          <path d="M3 8h10M9 4l4 4-4 4" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </a>
    </div>
  );
}

function renderStep(step, setStep, data) {
  if (step === "signup")      return <SignupStep onDone={() => setStep("verifyHold")} data={data} />;
  if (step === "verifyHold")  return <p>Check your email to verify your address. After clicking the link, you'll set a password.</p>;
  if (step === "setPassword") return <SetPasswordStep onDone={() => setStep("mfaEnroll")} data={data} />;
  if (step === "mfaEnroll")   return <MfaEnrollStep onDone={() => setStep("backupCodes")} data={data} />;
  if (step === "backupCodes") return <BackupCodesStep onDone={() => location.assign("/")} data={data} />;
  if (step === "login")       return <LoginStep data={data} />;
  if (step === "reset")       return <ResetStep data={data} />;
  if (step === "verify")      return <VerifyStep data={data} />;
  if (step === "mfaVerify")   return <MfaVerifyStep data={data} />;
  return null;
}

// Fallback steps for screens the multi-step shell doesn't replace yet.
// These mirror the previous single-form behaviour so existing pages keep working.
function ResetStep({ data }) {
  const [submitted, setSubmitted] = React.useState(false);
  return submitted ? (
    <div className="bs-auth-success">
      If we have an account at that address, you'll get a reset link within a minute.
    </div>
  ) : (
    <form className="bs-form bs-auth-form" onSubmit={async (e) => {
      e.preventDefault();
      const form = new FormData(e.currentTarget);
      await fetch(`${window.__bs_api}/api/auth/reset/request`, {
        method: "POST", credentials: "include",
        headers: { "content-type": "application/json", "x-csrf-token": window.__bs_csrf },
        body: JSON.stringify({ email: form.get("email") }),
      });
      setSubmitted(true);
    }}>
      {(data.fields || []).map((f) => (
        <label key={f.name} className="bs-formfield">
          <span>{f.label}</span>
          <input type={f.type} name={f.name} required={f.required} />
        </label>
      ))}
      <button type="submit" className="bs-formsubmit">{data.primaryCta}</button>
    </form>
  );
}

function VerifyStep({ data }) {
  return (
    <div className="bs-auth-success">{data.lede}</div>
  );
}

Object.assign(window, { BSAuthShell });
