/* =========================================================================
   Veto · Auth & onboarding   (Mercury-inspired pass)

   Principles for this flow:
   · One context per screen. Personal identity (name, email) is never on the
     same screen as "what do you do" questions (role, office).
   · Less is more. One question, one decision per screen.
   · Every question has a real payoff — the copy says what it does FOR you.

   Routes:
     /welcome    bold hub
     /login      email → code   (returning)
     /verify     6-digit code   (returning)
     /onboarding create an office: name → email → verify → role → office
   ========================================================================= */

const OFFICE_SUGGESTIONS = ["805 Escrow", "805 Title & Escrow", "Conejo Valley Escrow", "Central Coast Escrow", "Ventura County Escrow", "Westlake Escrow Services"];

/* Gently proper-case a typed name: capitalise the first letter of each word,
   leave the rest as typed (so "mcDonald" stays "McDonald"). */
const properCase = (s) => (s || "").replace(/(^|[\s'’-])([a-z])/g, (_, p, c) => p + c.toUpperCase());

/* ============================================================ primitives */

/* Centered shell for the bold marketing-y screens (welcome / login / verify). */
function AuthShell({ children, footer, align = "center" }) {
  return (
    <div className="min-h-screen bg-background text-ink">
      <div className="mx-auto flex min-h-screen w-full max-w-[440px] flex-col px-6">
        <header className="flex items-center justify-between pt-9">
          <Link to="/welcome" aria-label="Veto"><VetoLogo className="text-[18px]" /></Link>
        </header>
        <main className={cn("flex flex-1 flex-col py-10", align === "top" ? "justify-start pt-[7vh]" : "justify-center")}>{children}</main>
        {footer && <footer className="pb-9 text-[12.5px] text-ink-soft">{footer}</footer>}
      </div>
    </div>
  );
}

/* In-flow help: setup guides + "message us", opened from the Need help pill. */
const ONB_GUIDES = [
  { id: "office", icon: "building", title: "Setting up your office", blurb: "Name, branches, and reviewers.",
    body: "Your office name appears on every receipt the parties see, and it's bound to the record so it can't be faked. You can add branches and invite reviewers now, or later from Settings." },
  { id: "reviews", icon: "shield-check", title: "How a review works", blurb: "Lines, checkpoints, and receipts.",
    body: "Every file moves money through review lines — seller proceeds, buyer funding, payoff. Each line is a short list of checkpoints you record against a source. When the last is recorded, Veto issues a signed, source-bound receipt." },
  { id: "2fa", icon: "lock", title: "Why a second factor?", blurb: "Keeping the office locked to you.",
    body: "An emailed code only proves someone reached your inbox. A passkey or authenticator ties sign-in to a device you hold, so a leaked email can't open your office. You'll confirm it each time you sign in." },
];

function OnbHelpPanel() {
  const [guide, setGuide] = useState(null);
  const [sent, setSent] = useState(false);
  const g = ONB_GUIDES.find((x) => x.id === guide);
  return (
    <div className="w-[330px] overflow-hidden rounded-2xl border border-line bg-background shadow-[0_24px_64px_-24px_rgba(0,0,0,0.4)]">
      <div className="bg-ink px-5 py-5 text-background">
        <div className="text-[15px] font-semibold tracking-[-0.01em]">Need a hand?</div>
        <div className="mt-1 text-[12.5px] text-background/70">Setup guides, or a real person — we usually reply in a few minutes.</div>
      </div>
      {g ? (
        <div className="p-4">
          <button onClick={() => setGuide(null)} className="mb-3 inline-flex items-center gap-1.5 text-[12px] text-ink-soft transition hover:text-ink"><Icon name="arrow-left" size={13} /> All guides</button>
          <div className="flex items-center gap-2.5">
            <span className="grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-surface-2 text-ink-soft"><Icon name={g.icon} size={15} /></span>
            <div className="text-[13.5px] font-medium text-ink">{g.title}</div>
          </div>
          <p className="mt-3 text-[12.5px] leading-relaxed text-ink-soft">{g.body}</p>
        </div>
      ) : (
        <div className="p-2">
          {ONB_GUIDES.map((x) => (
            <button key={x.id} onClick={() => setGuide(x.id)} className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition hover:bg-surface">
              <span className="grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-surface-2 text-ink-soft"><Icon name={x.icon} size={15} /></span>
              <span className="min-w-0 flex-1"><span className="block text-[13px] font-medium text-ink">{x.title}</span><span className="block truncate text-[11.5px] text-ink-soft">{x.blurb}</span></span>
              <Icon name="chevron-right" size={14} className="shrink-0 text-ink-soft" />
            </button>
          ))}
          <div className="my-1 h-px bg-line" />
          <button onClick={() => setSent(true)} className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition hover:bg-surface">
            <span className="grid h-8 w-8 shrink-0 place-items-center rounded-lg bg-surface-2 text-ink-soft"><Icon name={sent ? "check-circle" : "message-circle"} size={15} /></span>
            <span className="min-w-0 flex-1"><span className="block text-[13px] font-medium text-ink">{sent ? "We're on it" : "Message us"}</span><span className="block truncate text-[11.5px] text-ink-soft">{sent ? "We'll reply to your work email shortly." : "Questions about setup or your office."}</span></span>
            {!sent && <Icon name="chevron-right" size={14} className="shrink-0 text-ink-soft" />}
          </button>
        </div>
      )}
      <div className="border-t border-line px-4 py-2.5 text-[11.5px] text-ink-soft">Veto records the review. The office decides.</div>
    </div>
  );
}

/* Onboarding chrome: slim header + full-width progress rail + roomy canvas.
   Modelled on Mercury's one-question screens. */
function OnbChrome({ step, total, right, children }) {
  const pct = Math.round(((step + 1) / total) * 100);
  const [help, setHelp] = useState(false);
  return (
    <div className="min-h-screen bg-background text-ink">
      {/* progress rail spans the very top edge */}
      <div className="fixed inset-x-0 top-0 z-20 h-[3px] bg-line">
        <div className="h-full bg-ink transition-[width] duration-500 ease-out" style={{ width: pct + "%" }} />
      </div>
      <header className="flex items-center justify-between px-6 pt-7 lg:px-10">
        <Link to="/welcome" aria-label="Veto"><VetoLogo className="text-[18px]" /></Link>
        <div className="text-[12.5px] text-ink-soft">{right}</div>
      </header>
      <main className="mx-auto flex w-full max-w-[600px] flex-col px-6 pb-16 pt-[9vh]">{children}</main>
      <div className="fixed bottom-5 right-5 z-30 flex flex-col items-end gap-3">
        {help && <OnbHelpPanel />}
        <button type="button" onClick={() => setHelp((h) => !h)}
          className="inline-flex items-center gap-1.5 rounded-full border border-line bg-background px-3.5 py-2 text-[12.5px] text-ink-soft shadow-sm transition hover:border-ink/20 hover:text-ink">
          <Icon name={help ? "x" : "life-buoy"} size={14} /> {help ? "Close" : "Need help?"}
        </button>
      </div>
    </div>
  );
}

/* The bold question + payoff. The heading IS the question. */
function QHead({ title, payoff }) {
  return (
    <div>
      <h1 className="text-[clamp(27px,4.6vw,37px)] font-semibold leading-[1.06] tracking-[-0.03em] text-ink text-balance">{title}</h1>
      {payoff && <p className="mt-3.5 max-w-[460px] text-[15px] leading-relaxed text-ink-soft text-pretty">{payoff}</p>}
    </div>
  );
}

/* Large, calm input. Bigger and airier than the in-app field. */
function BigField({ label, type = "text", value, onChange, placeholder, autoFocus, helper, prefix, onEnter }) {
  return (
    <label className="block">
      {label && <span className="mb-2 block text-[13px] font-medium text-ink">{label}</span>}
      <span className={cn("flex h-14 w-full items-center rounded-xl border border-line bg-background px-4 text-[16px] text-ink transition focus-within:border-ink/45 focus-within:ring-2 focus-within:ring-ink/10")}>
        {prefix && <span className="shrink-0 pr-0.5 text-ink-soft">{prefix}</span>}
        <input type={type} value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} autoFocus={autoFocus}
          autoComplete="off" onKeyDown={(e) => { if (e.key === "Enter" && onEnter) onEnter(); }}
          className="h-full w-full bg-transparent text-[16px] text-ink outline-none placeholder:text-muted-foreground" />
      </span>
      {helper && <span className="mt-2 block text-[12.5px] text-ink-soft">{helper}</span>}
    </label>
  );
}

/* Pill action button — bolder than the in-app rounded-md button. */
function PillButton({ children, onClick, disabled, type = "button", trailing = true }) {
  return (
    <button type={type} onClick={onClick} disabled={disabled}
      className={cn("inline-flex h-12 items-center justify-center gap-2 rounded-full px-7 text-[14px] font-medium transition",
        disabled ? "cursor-not-allowed bg-surface-2 text-muted-foreground" : "bg-ink text-background hover:bg-ink/90")}>
      {children}{trailing && <Icon name="arrow-right" size={16} />}
    </button>
  );
}

function GhostBack({ onClick }) {
  return (
    <button onClick={onClick} className="mb-8 inline-flex items-center gap-1.5 rounded-md -ml-2 px-2 py-1.5 text-[13px] text-ink-soft transition hover:bg-surface hover:text-ink">
      <Icon name="arrow-left" size={15} /> Back
    </button>
  );
}

/* Selectable card — for role and other single-choice "what do you do" screens. */
function ChoiceCard({ selected, onSelect, icon, title, sub }) {
  return (
    <button type="button" onClick={onSelect}
      className={cn("flex w-full items-center gap-3.5 rounded-xl border p-4 text-left transition",
        selected ? "border-ink bg-surface/50 ring-1 ring-ink" : "border-line bg-background hover:border-ink/30 hover:bg-surface/30")}>
      {icon && (
        <span className={cn("grid h-10 w-10 shrink-0 place-items-center rounded-lg border transition",
          selected ? "border-ink/20 bg-background text-ink" : "border-line bg-surface text-ink-soft")}>
          <Icon name={icon} size={18} />
        </span>
      )}
      <span className="min-w-0 flex-1">
        <span className="block text-[14.5px] font-medium text-ink">{title}</span>
        {sub && <span className="mt-0.5 block text-[12.5px] leading-snug text-ink-soft">{sub}</span>}
      </span>
      <span className={cn("grid h-5 w-5 shrink-0 place-items-center rounded-full border transition", selected ? "border-ink bg-ink" : "border-line")}>
        {selected && <Icon name="check" size={12} strokeWidth={3} className="text-background" />}
      </span>
    </button>
  );
}

function CodeInput({ value, onChange, onComplete }) {
  const refs = useRef([]);
  if (!refs.current.length) refs.current = Array.from({ length: 6 }, () => null);
  const digits = value.padEnd(6, " ").slice(0, 6).split("");
  function set(i, d) {
    const arr = value.padEnd(6, " ").slice(0, 6).split("");
    arr[i] = d || " ";
    const joined = arr.join("").replace(/\s+$/g, "");
    onChange(joined);
    if (d && i < 5 && refs.current[i + 1]) refs.current[i + 1].focus();
    if (joined.length === 6 && onComplete) onComplete();
  }
  return (
    <div className="flex gap-2.5">
      {digits.map((d, i) => (
        <input key={i} ref={(el) => (refs.current[i] = el)} inputMode="numeric" maxLength={1} autoComplete="off" autoFocus={i === 0}
          value={d.trim()} onChange={(e) => set(i, e.target.value.replace(/[^0-9]/g, ""))}
          onKeyDown={(e) => { if (e.key === "Backspace" && !d.trim() && i > 0 && refs.current[i - 1]) refs.current[i - 1].focus(); }}
          className="h-[58px] w-full rounded-xl border border-line bg-background text-center font-mono text-[20px] text-ink outline-none transition focus:border-ink/45 focus:ring-2 focus:ring-ink/10" />
      ))}
    </div>
  );
}

/* Email chips — narrower + taller compose box with a Mercury-style
   autocomplete: type a name, we complete it against the office domain;
   Enter or click the suggestion to drop a pill. */
function EmailChips({ emails, onChange, autoFocus, domain }) {
  const [draft, setDraft] = useState("");
  const suggestion = (() => {
    const d = draft.trim();
    if (!d) return null;
    if (d.includes("@")) return /\S+@\S+\.\S+/.test(d) ? d : null;
    return domain ? `${d}@${domain}` : null;
  })();
  const commit = (val) => {
    const e = (val || "").trim();
    if (/\S+@\S+\.\S+/.test(e) && !emails.includes(e)) onChange([...emails, e]);
    setDraft("");
  };
  const commitMany = (text) => {
    const parts = (text || "").split(/[\s,;]+/).map((s) => s.trim()).filter((p) => /\S+@\S+\.\S+/.test(p));
    const add = parts.filter((p) => !emails.includes(p));
    if (add.length) onChange([...emails, ...Array.from(new Set(add))]);
    setDraft("");
  };
  const initial = (e) => (e[0] || "?").toUpperCase();
  return (
    <div className="max-w-[440px]">
      <div className="flex min-h-[88px] w-full flex-wrap content-start gap-2 rounded-xl border border-line bg-background p-3 transition focus-within:border-ink/45 focus-within:ring-2 focus-within:ring-ink/10">
        {emails.map((e) => (
          <span key={e} className="inline-flex h-8 items-center gap-2 rounded-full bg-surface-2 pl-1 pr-2 text-[13px] text-ink">
            <span className="grid h-6 w-6 shrink-0 place-items-center rounded-full bg-background text-[10px] font-medium text-ink-soft">{initial(e)}</span>
            <span className="max-w-[210px] truncate">{e}</span>
            <button type="button" onClick={() => onChange(emails.filter((x) => x !== e))} aria-label={"Remove " + e}
              className="grid h-4 w-4 shrink-0 place-items-center rounded text-ink-soft transition hover:bg-line hover:text-ink"><Icon name="x" size={12} /></button>
          </span>
        ))}
        <input value={draft} onChange={(e) => setDraft(e.target.value)} onBlur={() => commit(suggestion || draft)}
          onPaste={(e) => { const t = e.clipboardData.getData("text"); if (/[\s,;]/.test(t)) { e.preventDefault(); commitMany(t); } }}
          onKeyDown={(ev) => {
            if (ev.key === "Enter" || ev.key === "," || (ev.key === " " && draft.includes("@"))) { ev.preventDefault(); commit(suggestion || draft); }
            else if (ev.key === "Backspace" && !draft && emails.length) onChange(emails.slice(0, -1));
          }}
          autoFocus={autoFocus} autoComplete="off" placeholder={emails.length ? "Add another…" : (domain ? `name@${domain}` : "name@youroffice.com")}
          className="h-8 min-w-[160px] flex-1 bg-transparent text-[15px] text-ink outline-none placeholder:text-muted-foreground" />
      </div>
      {suggestion && !emails.includes(suggestion) && (
        <button type="button" onMouseDown={(e) => { e.preventDefault(); commit(suggestion); }}
          className="group/sg mt-1.5 flex w-full items-center gap-3 rounded-xl border border-line bg-background px-3.5 py-3 text-left shadow-[0_8px_24px_-18px_rgba(0,0,0,0.3)] transition hover:bg-surface">
          <span className="grid h-[18px] w-[18px] shrink-0 place-items-center rounded-[5px] border border-line transition group-hover/sg:border-ink group-hover/sg:bg-ink">
            <Icon name="check" size={11} strokeWidth={3} className="text-background opacity-0 transition group-hover/sg:opacity-100" />
          </span>
          <span className="min-w-0 flex-1 truncate text-[13.5px] text-ink">Invite <span className="font-medium">{suggestion}</span></span>
          <kbd className="shrink-0 rounded bg-surface-2 px-1.5 py-0.5 font-mono text-[10px] text-ink-soft">↵</kbd>
        </button>
      )}
    </div>
  );
}

/* A QR-ish placeholder for authenticator setup (3 finder squares + grid). */
function QrPlaceholder() {
  return (
    <div className="relative h-full w-full">
      <div className="absolute inset-0 rounded-sm" style={{ backgroundImage: "repeating-conic-gradient(var(--ink) 0% 25%, transparent 0% 50%)", backgroundSize: "9px 9px" }} />
      {["top-1 left-1", "top-1 right-1", "bottom-1 left-1"].map((pos, i) => (
        <div key={i} className={cn("absolute h-9 w-9 rounded-[4px] border-[3px] border-ink bg-background", pos)}>
          <div className="absolute inset-[5px] rounded-[1px] bg-ink" />
        </div>
      ))}
    </div>
  );
}

/* Full-page passkey step (not a modal — reads as forward progress). */
function PasskeyPanel({ domain, onApprove, onCancel, mode = "create" }) {
  const benefits = [
    { icon: "shield-check", text: "Phishing-proof — a leaked email can't open your office." },
    { icon: "check-circle", text: "Nothing to remember — your device is the key." },
    { icon: "lock", text: "Stays on this device. Veto never sees it." },
  ];
  return (
    <div className="flex flex-col items-center pt-[2vh] text-center">
      <span className="relative grid h-20 w-20 place-items-center rounded-3xl bg-surface text-ink">
        <span aria-hidden className="absolute inset-[-6px] rounded-[30px] border border-line motion-safe:animate-pulse" />
        <Icon name="lock" size={32} />
      </span>
      <h1 className="mt-7 text-[clamp(24px,3.6vw,32px)] font-semibold tracking-[-0.03em] text-ink">{mode === "create" ? "Create your passkey." : "Confirm it's you."}</h1>
      <p className="mt-3 max-w-[400px] text-[14.5px] leading-relaxed text-ink-soft">
        {mode === "create"
          ? <>One touch — Touch ID, Face ID, or a hardware key — saves a passkey for <span className="text-ink">{domain}</span>.</>
          : <>Use Touch ID to sign in to <span className="text-ink">{domain}</span>.</>}
      </p>
      {mode === "create" && (
        <ul className="mt-6 w-full max-w-[360px] space-y-2">
          {benefits.map((b) => (
            <li key={b.text} className="flex items-center gap-3 rounded-xl border border-line bg-background px-3.5 py-2.5 text-left">
              <Icon name={b.icon} size={16} className="shrink-0 text-ink" />
              <span className="text-[12.5px] leading-snug text-ink-soft">{b.text}</span>
            </li>
          ))}
        </ul>
      )}
      <button onClick={onApprove} className="mt-7 inline-flex h-12 items-center justify-center gap-2 rounded-full bg-ink px-7 text-[14px] font-medium text-background transition hover:bg-ink/90"><Icon name="lock" size={16} /> {mode === "create" ? "Create passkey" : "Use Touch ID"}</button>
      {onCancel && <button onClick={onCancel} className="mt-3 text-[12.5px] text-ink-soft transition hover:text-ink">Use a different method</button>}
    </div>
  );
}

/* --------------------------------------------------------------- Welcome */
function Welcome() {
  return (
    <AuthShell footer={<span>Veto records the review. The office decides.</span>}>
      <div>
        <div className="mb-5 inline-flex items-center gap-2 rounded-full border border-line bg-surface/60 px-3 py-1 text-[11.5px] font-medium text-ink-soft">
          <span className="h-1.5 w-1.5 rounded-full bg-[var(--ok)]" /> For escrow & title offices
        </div>
        <h1 className="text-[33px] font-semibold leading-[1.04] tracking-[-0.035em] text-ink text-balance">
          The future of escrow money is on the record.
        </h1>
        <p className="mt-3.5 text-[14.5px] leading-relaxed text-ink-soft text-pretty">
          Veto turns every buyer funding, seller proceeds, and payoff demand into a signed, source-bound review record no one can fake.
        </p>
        <div className="mt-8 flex flex-col gap-3">
          <Link to="/onboarding" className="flex h-12 items-center justify-center gap-2 rounded-full bg-ink text-[14px] font-medium text-background transition hover:bg-ink/90">
            Create an office <Icon name="arrow-right" size={16} />
          </Link>
          <Link to="/login" className="flex h-12 items-center justify-center rounded-full border border-line bg-background text-[14px] font-medium text-ink transition hover:bg-surface">Sign in</Link>
        </div>
        <div className="mt-5 text-center text-[12.5px] text-ink-soft">
          Have an invite? <Link to="/join" className="text-ink underline decoration-line underline-offset-4 hover:decoration-ink">Join an existing office</Link>
        </div>
        <div className="mt-8 border-t border-line pt-5">
          <Link to="/" className="text-[12.5px] text-ink-soft underline decoration-line underline-offset-4 hover:text-ink">Skip to the demo →</Link>
        </div>
      </div>
    </AuthShell>
  );
}

/* --------------------------------------------------------------- Login */
function Login() {
  const [email, setEmail] = useState("");
  const valid = /\S+@\S+\.\S+/.test(email);
  return (
    <AuthShell footer={<span>New to Veto? <Link to="/onboarding" className="text-ink underline decoration-line underline-offset-4 hover:decoration-ink">Create an office</Link>.</span>}>
      <div>
        <h1 className="text-[26px] font-semibold tracking-[-0.025em] text-ink">Welcome back.</h1>
        <p className="mt-2 text-[14px] text-ink-soft">Enter your work email and we'll send a 6-digit code. No password to remember.</p>
        <div className="mt-7 space-y-4">
          <BigField label="Work email" type="email" value={email} onChange={setEmail} placeholder="you@youroffice.com" autoFocus onEnter={() => valid && navigate("/verify")} />
          <PillButton disabled={!valid} onClick={() => navigate("/verify")}>Continue with email</PillButton>
        </div>
        <Link to="/" className="mt-7 block text-[12.5px] text-ink-soft underline decoration-line underline-offset-4 hover:text-ink">Continue to the demo</Link>
      </div>
    </AuthShell>
  );
}

/* --------------------------------------------------------------- Verify (returning) */
function Verify() {
  const [phase, setPhase] = useState("code");
  const [code, setCode] = useState("");
  const [otp, setOtp] = useState("");
  if (phase === "code") {
    return (
      <AuthShell footer={<span>Didn't get it? <button className="text-ink underline decoration-line underline-offset-4 hover:decoration-ink">Resend</button> · <Link to="/login" className="text-ink underline decoration-line underline-offset-4 hover:decoration-ink">Use a different email</Link></span>}>
        <div>
          <h1 className="text-[26px] font-semibold tracking-[-0.025em] text-ink">Check your email.</h1>
          <p className="mt-2 text-[14px] leading-relaxed text-ink-soft">We sent a code to <span className="text-ink">madeline.lane@805escrow.example</span>.</p>
          <div className="mt-7">
            <CodeInput value={code} onChange={setCode} onComplete={() => setPhase("2fa")} />
            <div className="mt-5"><PillButton disabled={code.length < 6} onClick={() => setPhase("2fa")}>Continue</PillButton></div>
          </div>
        </div>
      </AuthShell>
    );
  }
  return (
    <AuthShell footer={<span>Lost your device? <button className="text-ink underline decoration-line underline-offset-4 hover:decoration-ink">Use a backup code</button></span>}>
      <div>
        <h1 className="text-[26px] font-semibold tracking-[-0.025em] text-ink">One more check.</h1>
        <p className="mt-2 text-[14px] leading-relaxed text-ink-soft">A code in your inbox isn't proof on its own. Confirm with your passkey, or enter the code from your authenticator app.</p>
        <div className="mt-7 space-y-4">
          <button onClick={() => navigate("/")} className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-ink text-[14px] font-medium text-background transition hover:bg-ink/90"><Icon name="lock" size={15} /> Confirm with passkey</button>
          <div className="flex items-center gap-3 text-[12px] text-muted-foreground"><span className="h-px flex-1 bg-line" /> or enter your code <span className="h-px flex-1 bg-line" /></div>
          <CodeInput value={otp} onChange={setOtp} onComplete={() => navigate("/")} />
        </div>
      </div>
    </AuthShell>
  );
}

/* ------------------------------------------------------------ Onboarding */
/* Create-an-office flow. Each step is a single context with a clear payoff. */
const ONB_STEPS = ["name", "email", "verify", "secure", "role", "office", "invite"];

const TWOFA_METHODS = [
  { id: "passkey", icon: "lock", title: "Passkey", sub: "Face ID, Touch ID, or a hardware key. Phishing-proof and recommended." },
  { id: "authenticator", icon: "shield-check", title: "Authenticator app", sub: "A rotating 6-digit code from Authy, 1Password, or Google Authenticator." },
];

const ONB_ROLES = [
  { id: "officer", icon: "shield-check", title: "Escrow officer", sub: "Reviews files and signs receipts." },
  { id: "manager", icon: "users", title: "Branch manager", sub: "Oversees second review and the office." },
  { id: "assistant", icon: "file-text", title: "Assistant", sub: "Preps files and gathers evidence. Can't sign." },
];

function Onboarding() {
  const [step, setStep] = useState(0);
  const [first, setFirst] = useState("");
  const [last, setLast] = useState("");
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const [role, setRole] = useState("officer");
  const [office, setOffice] = useState("");
  const [invites, setInvites] = useState([]);
  const [twofa, setTwofa] = useState("passkey");
  const [securePhase, setSecurePhase] = useState("choose");
  const [otp, setOtp] = useState("");
  const [keyCopied, setKeyCopied] = useState(false);
  const [linkCopied, setLinkCopied] = useState(false);

  const total = ONB_STEPS.length;
  const id = ONB_STEPS[step];
  const next = () => setStep((s) => Math.min(s + 1, total - 1));
  const back = () => setStep((s) => Math.max(s - 1, 0));

  const finish = () => {
    try {
      localStorage.setItem("veto.setup.office", office || "805 Escrow");
      localStorage.setItem("veto.setup.first", first || "Madeline");
      localStorage.setItem("veto.setup.role", role);
      localStorage.setItem("veto.setup.officeDone", "1");
      localStorage.setItem("veto.setup.2fa", twofa);
      localStorage.setItem("veto.setup.domain", (email.split("@")[1] || "").trim());
      if (invites.length) { localStorage.setItem("veto.setup.invitesDone", "1"); localStorage.setItem("veto.setup.inviteCount", String(invites.length)); }
    } catch {}
    navigate("/");
  };

  const rightCtx = first ? `${first}${last ? " " + last : ""}` : <Link to="/login" className="underline decoration-line underline-offset-4 hover:text-ink">Sign in</Link>;
  const nameOk = first.trim().length > 0;
  const emailOk = /\S+@\S+\.\S+/.test(email);

  return (
    <OnbChrome step={step} total={total} right={rightCtx}>
      {/* 1 · Your name — personal identity, on its own */}
      {id === "name" && (
        <div>
          <QHead title="First, what's your name?"
            payoff="It signs every receipt you record, so everyone on the file knows the review is yours." />
          <div className="mt-9 space-y-4">
            <div className="grid grid-cols-2 gap-3">
              <BigField label="First name" value={first} onChange={(v) => setFirst(properCase(v))} placeholder="Madeline" autoFocus onEnter={() => nameOk && next()} />
              <BigField label="Last name" value={last} onChange={(v) => setLast(properCase(v))} placeholder="Lane" onEnter={() => nameOk && next()} />
            </div>
            <div className="pt-1"><PillButton disabled={!nameOk} onClick={next}>Continue</PillButton></div>
          </div>
        </div>
      )}

      {/* 2 · Work email — still personal identity, one field */}
      {id === "email" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="What's your work email?"
            payoff="We'll send your sign-in code here, plus alerts when a file needs you. No passwords to remember." />
          <div className="mt-9 space-y-4">
            <BigField label="Work email" type="email" value={email} onChange={setEmail} placeholder="you@youroffice.com" autoFocus
              helper="We'll never share it or send marketing." onEnter={() => emailOk && next()} />
            <div className="pt-1"><PillButton disabled={!emailOk} onClick={next}>Send my code</PillButton></div>
          </div>
        </div>
      )}

      {/* 3 · Verify */}
      {id === "verify" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="Enter your code." payoff={<>We sent a 6-digit code to <span className="text-ink">{email || "your inbox"}</span>. It expires in 10 minutes.</>} />
          <div className="mt-9 max-w-[400px]">
            <CodeInput value={code} onChange={setCode} onComplete={next} />
            <div className="mt-5 flex items-center gap-5">
              <PillButton disabled={code.length < 6} onClick={next}>Continue</PillButton>
              <button className="text-[12.5px] text-ink-soft underline decoration-line underline-offset-4 transition hover:text-ink">Resend code</button>
            </div>
          </div>
        </div>
      )}

      {/* 4 · Secure — a real second factor, with the actual passkey / authenticator UI */}
      {id === "secure" && (
        <div>
          {securePhase === "choose" && (
            <>
              <GhostBack onClick={back} />
              <QHead title="Add a second factor."
                payoff="Veto holds the record for real money, so an emailed code isn't enough on its own. You'll confirm this every time you sign in." />
              <div className="mt-9 space-y-2.5">
                {TWOFA_METHODS.map((mth) => (
                  <ChoiceCard key={mth.id} icon={mth.icon} title={mth.title} sub={mth.sub} selected={twofa === mth.id} onSelect={() => setTwofa(mth.id)} />
                ))}
                <div className="pt-3"><PillButton onClick={() => setSecurePhase(twofa === "passkey" ? "passkey" : "auth")}>{twofa === "passkey" ? "Create a passkey" : "Set up authenticator"}</PillButton></div>
              </div>
            </>
          )}
          {securePhase === "passkey" && (
            <>
              <GhostBack onClick={() => setSecurePhase("choose")} />
              <PasskeyPanel mode="create" domain={email.split("@")[1] || "your office"} onApprove={next} onCancel={() => setSecurePhase("choose")} />
            </>
          )}
          {securePhase === "auth" && (
            <>
              <GhostBack onClick={() => setSecurePhase("choose")} />
              <QHead title="Set up your authenticator."
                payoff="A rotating code from an app you already trust — Authy, 1Password, or Google Authenticator." />
              <div className="mt-8 flex flex-col gap-8 sm:flex-row sm:items-start">
                <div className="shrink-0">
                  <div className="grid h-48 w-48 place-items-center rounded-2xl border border-line bg-background p-3 shadow-sm"><QrPlaceholder /></div>
                  <button type="button" onClick={() => { try { navigator.clipboard?.writeText("JBSWY3DPEHPK3PXP"); } catch {} setKeyCopied(true); setTimeout(() => setKeyCopied(false), 1500); }}
                    className="mt-2.5 flex w-48 items-center justify-between gap-2 rounded-lg border border-line bg-surface/50 px-3 py-2 text-left transition hover:bg-surface">
                    <span className="font-mono text-[11.5px] tracking-[0.04em] text-ink">JBSW Y3DP EHPK 3PXP</span>
                    <Icon name={keyCopied ? "check" : "link"} size={13} strokeWidth={keyCopied ? 3 : 1.6} className="shrink-0 text-ink-soft" />
                  </button>
                </div>
                <div className="min-w-0 flex-1">
                  <ol className="space-y-3">
                    {["Open your authenticator app.", "Scan the code, or paste the key.", "Enter the 6-digit code it shows."].map((t, i) => (
                      <li key={i} className="flex items-start gap-3">
                        <span className="grid h-6 w-6 shrink-0 place-items-center rounded-full bg-surface-2 font-mono text-[11px] font-medium text-ink">{i + 1}</span>
                        <span className="pt-0.5 text-[13px] text-ink">{t}</span>
                      </li>
                    ))}
                  </ol>
                  <div className="mt-5"><CodeInput value={otp} onChange={setOtp} onComplete={next} /></div>
                </div>
              </div>
            </>
          )}
        </div>
      )}

      {/* 5 · Role — "what do you do", on its own screen */}
      {id === "role" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="What do you do in the office?"
            payoff="Only officers and managers can sign a receipt. Assistants prep files and gather the evidence." />
          <div className="mt-9 space-y-2.5">
            {ONB_ROLES.map((r) => (
              <ChoiceCard key={r.id} icon={r.icon} title={r.title} sub={r.sub} selected={role === r.id} onSelect={() => setRole(r.id)} />
            ))}
            <div className="pt-3"><PillButton disabled={!role} onClick={next}>Continue</PillButton></div>
          </div>
        </div>
      )}

      {/* 5 · Office name — about the office, single field */}
      {id === "office" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="Name your office."
            payoff="It appears on every receipt buyers, sellers, and lenders see, bound to the record so it can't be faked." />
          <div className="mt-9 space-y-4">
            <label className="block">
              <span className="mb-2 block text-[13px] font-medium text-ink">Office name</span>
              <Autocomplete value={office} onChange={setOffice} placeholder="805 Escrow" options={OFFICE_SUGGESTIONS} icon="building" autoFocus />
              <span className="mt-2 block text-[12.5px] text-ink-soft">You can add branches later in settings.</span>
            </label>
            <div className="pt-1"><PillButton disabled={!office.trim()} onClick={next}>Continue</PillButton></div>
          </div>
        </div>
      )}

      {/* 7 · Invite your team — Mercury-style email chips, no per-row roles */}
      {id === "invite" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="Invite your team."
            payoff="A file can't record without a second review, so add the people you close with. They'll get a link to join." />
          <div className="mt-9">
            <span className="text-[13px] font-medium text-ink">Email addresses</span>
            <div className="mt-2">
              <EmailChips emails={invites} onChange={setInvites} autoFocus domain={(email.split("@")[1] || "").trim()} />
            </div>

            <div className="mt-5 flex max-w-[440px] items-center gap-3">
              <span className="h-px flex-1 bg-line" /><span className="text-[11.5px] text-muted-foreground">or share a link</span><span className="h-px flex-1 bg-line" />
            </div>
            <button type="button" onClick={() => { try { navigator.clipboard?.writeText("https://veto.co/join/805-4821"); } catch {} setLinkCopied(true); setTimeout(() => setLinkCopied(false), 1600); }}
              className="mt-3 flex w-full max-w-[440px] items-center gap-3 rounded-xl border border-line bg-surface/40 px-4 py-3 text-left transition hover:bg-surface">
              <Icon name="link" size={16} className="shrink-0 text-ink-soft" />
              <span className="min-w-0 flex-1 truncate font-mono text-[12.5px] text-ink">veto.co/join/805-4821</span>
              <span className="shrink-0 text-[12.5px] font-medium text-ink">{linkCopied ? "Copied" : "Copy"}</span>
            </button>

            <div className="mt-8 flex items-center gap-5">
              <PillButton disabled={invites.length === 0} onClick={finish}>{invites.length ? `Send ${invites.length} ${invites.length === 1 ? "invite" : "invites"}` : "Send invites"}</PillButton>
              <button onClick={finish} className="text-[12.5px] text-ink-soft underline decoration-line underline-offset-4 transition hover:text-ink">I'll do this later</button>
            </div>
          </div>
        </div>
      )}
    </OnbChrome>
  );
}

/* ------------------------------------------------------------ Join office */
/* Invite-link branch. Role + office come from the inviter, so this is short:
   prove the invite, say who you are, verify. */
const JOIN_STEPS = ["invite", "name", "email", "verify"];
function JoinOffice() {
  const [step, setStep] = useState(0);
  const [invite, setInvite] = useState("");
  const [first, setFirst] = useState("");
  const [last, setLast] = useState("");
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const office = "805 Escrow";
  const total = JOIN_STEPS.length;
  const id = JOIN_STEPS[step];
  const next = () => setStep((s) => Math.min(s + 1, total - 1));
  const back = () => setStep((s) => Math.max(s - 1, 0));
  const finish = () => {
    try { localStorage.setItem("veto.setup.first", first || "Madeline"); localStorage.setItem("veto.setup.office", office); localStorage.setItem("veto.setup.invitesDone", "1"); } catch {}
    navigate("/");
  };
  const rightCtx = first ? `${first}${last ? " " + last : ""}` : office;
  const inviteOk = invite.trim().length >= 4;
  const nameOk = first.trim().length > 0;
  const emailOk = /\S+@\S+\.\S+/.test(email);

  return (
    <OnbChrome step={step} total={total} right={rightCtx}>
      {id === "invite" && (
        <div>
          <QHead title="Join your office on Veto."
            payoff="Your manager sent an invite code. Enter it and we'll set up your seat, with your role already assigned." />
          <div className="mt-9 space-y-4">
            <BigField label="Invite code" value={invite} onChange={setInvite} placeholder="805-4821" autoFocus onEnter={() => inviteOk && next()} />
            <div className="pt-1"><PillButton disabled={!inviteOk} onClick={next}>Continue</PillButton></div>
          </div>
        </div>
      )}
      {id === "name" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title={<>You're joining {office}.</>}
            payoff="Your name signs every receipt you record, so everyone on the file knows the review is yours." />
          <div className="mt-9 space-y-4">
            <div className="grid grid-cols-2 gap-3">
              <BigField label="First name" value={first} onChange={(v) => setFirst(properCase(v))} placeholder="Madeline" autoFocus onEnter={() => nameOk && next()} />
              <BigField label="Last name" value={last} onChange={(v) => setLast(properCase(v))} placeholder="Lane" onEnter={() => nameOk && next()} />
            </div>
            <div className="pt-1"><PillButton disabled={!nameOk} onClick={next}>Continue</PillButton></div>
          </div>
        </div>
      )}
      {id === "email" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="What's your work email?"
            payoff="We'll send your sign-in code here, plus alerts when a file needs you. No passwords to remember." />
          <div className="mt-9 space-y-4">
            <BigField label="Work email" type="email" value={email} onChange={setEmail} placeholder="you@youroffice.com" autoFocus
              helper="We'll never share it or send marketing." onEnter={() => emailOk && next()} />
            <div className="pt-1"><PillButton disabled={!emailOk} onClick={next}>Send my code</PillButton></div>
          </div>
        </div>
      )}
      {id === "verify" && (
        <div>
          <GhostBack onClick={back} />
          <QHead title="Enter your code." payoff={<>We sent a 6-digit code to <span className="text-ink">{email || "your inbox"}</span>. It expires in 10 minutes.</>} />
          <div className="mt-9 max-w-[400px]">
            <CodeInput value={code} onChange={setCode} onComplete={finish} />
            <div className="mt-5 flex items-center gap-5">
              <PillButton disabled={code.length < 6} onClick={finish}>Join {office}</PillButton>
              <button className="text-[12.5px] text-ink-soft underline decoration-line underline-offset-4 transition hover:text-ink">Resend code</button>
            </div>
          </div>
        </div>
      )}
    </OnbChrome>
  );
}

Object.assign(window, { Welcome, Login, Verify, Onboarding, JoinOffice, EmailChips });
