"use client";

import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { Icon, Avatar } from "./icons";
import {
  Spinner, StepBack, AccountPill, FlashNote, MethodRow,
  RememberDevice, OtpBoxes, ResendLink, SocialButtons, startSocial,
  PasswordStrength,
} from "./bits";
import { lookupAccount, type Account } from "./data";

type Step =
  | "identify" | "connecting" | "notfound" | "primary" | "passkey" | "password"
  | "otp" | "another" | "totp" | "push" | "error" | "terms" | "success" | "recovery"
  | "fp_confirm" | "fp_code" | "fp_reset";

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function LoginFlow() {
  const router = useRouter();
  const [step, setStep] = useState<Step>("identify");
  const [email, setEmail] = useState("");
  const [account, setAccount] = useState<Account | null>(null);
  const [provider, setProvider] = useState<string>("");
  const [remember, setRemember] = useState(false);
  const [flash, setFlash] = useState<string>("");

  /* ---- history hash sync ---- */
  function push(s: Step) {
    setStep(s);
    try { window.history.pushState({ s }, "", `#${s}`); } catch { /* ignore */ }
  }
  function replace(s: Step) {
    setStep(s);
    try { window.history.replaceState({ s }, "", `#${s}`); } catch { /* ignore */ }
  }
  const back = () => window.history.back();
  function switchAccount() { setAccount(null); setEmail(""); setFlash(""); replace("identify"); }

  useEffect(() => {
    const onPop = () => {
      const h = window.location.hash.replace("#", "") as Step;
      setStep(h || "identify");
    };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  /* ---- auth resolution ---- */
  function afterAuth(factor: "password" | "passkey" | "otp" | "totp" | "push" | "social") {
    if (factor === "password") { setFlash(""); push("otp"); return; }
    let accepted = false;
    try { accepted = !!localStorage.getItem("lup_terms"); } catch { /* ignore */ }
    push(accepted ? "success" : "terms");
  }

  function onSocial(p: "google" | "microsoft" | "apple") {
    const real = startSocial(p);
    if (real) return; // redirected away
    setProvider(p);
    push("connecting");
    setTimeout(() => afterAuth("social"), 1300);
  }

  function identifyEmail() {
    if (!EMAIL_RE.test(email)) return;
    push("connecting");
    setProvider("");
    setTimeout(() => {
      const acc = lookupAccount(email);
      if (!acc) { replace("notfound"); return; }
      setAccount(acc);
      replace("primary");
    }, 650);
  }

  /* =================================================================== */
  return (
    <div className="card anim-fade-up" key={step}>
      {step === "identify" && <Identify email={email} setEmail={setEmail} onSocial={onSocial} onEmail={identifyEmail} toRegister={() => router.push("/portal/register")} />}

      {step === "connecting" && (
        <div className="interstitial">
          <Spinner lg />
          <div>
            <h1 style={{ fontSize: 20 }}>{provider ? `Connecting to ${cap(provider)}…` : "Looking up your account…"}</h1>
            {provider && <p className="sub" style={{ marginTop: 6 }}>Demo mode — no provider keys configured.</p>}
          </div>
        </div>
      )}

      {step === "notfound" && (
        <div>
          <div className="conn-banner conn-error-like" style={{ background: "rgba(239,68,68,.1)", border: "1px solid rgba(239,68,68,.35)", color: "#fca5a5", marginBottom: 18 }}>
            <Icon name="alert" size={18} /> No account found for <b>&nbsp;{email}</b>
          </div>
          <h1>We couldn&apos;t find that account</h1>
          <p className="sub">No account is on file for this email. Try another email or register a new account.</p>
          <div className="col gap-3" style={{ marginTop: 22 }}>
            <button className="btn" onClick={() => replace("identify")}>Try a different email</button>
            <button className="btn btn-primary" onClick={() => router.push("/portal/register")}>Register a new account <Icon name="arrowR" size={16} /></button>
          </div>
        </div>
      )}

      {step === "primary" && account && (
        <div>
          <h1>Hi {account.firstName}</h1>
          <p className="sub">Choose how you want to sign in.</p>
          <div style={{ margin: "18px 0" }}>
            <AccountPill initials={account.initials} email={email} onChange={() => replace("identify")} />
          </div>
          <div className="col gap-3">
            {account.hasPasskey && <MethodRow icon="key" title="Use your passkey" sub="Fingerprint, face or screen lock" badge="Fastest" onClick={() => push("passkey")} />}
            <MethodRow icon="lock" title="Enter your password" sub="Sign in with your password" onClick={() => push("password")} />
            <MethodRow icon="sparkle" title="Try another way" sub="Authenticator, push, OTP…" onClick={() => push("another")} />
          </div>
        </div>
      )}

      {step === "passkey" && account && (
        <Passkey account={account} onBack={back} onPassword={() => replace("password")} onAnother={() => replace("another")} onSuccess={() => afterAuth("passkey")} onFail={() => { setFlash("Passkey was cancelled or timed out."); replace("error"); }} />
      )}

      {step === "password" && account && (
        <Password account={account} flash={flash} onBack={back} onForgot={() => push("fp_confirm")} onOtp={() => replace("otp")} onLocked={() => setFlash("This account is temporarily locked.")} onOk={() => afterAuth("password")} />
      )}

      {step === "otp" && account && (
        <OtpVerify account={account} remember={remember} setRemember={setRemember} onBack={back} onVerified={() => afterAuth("otp")} />
      )}

      {step === "another" && account && (
        <AnotherWay account={account} onBack={back} go={(s) => push(s)} />
      )}

      {step === "totp" && account && (
        <Totp remember={remember} setRemember={setRemember} onBack={back} onVerified={() => afterAuth("totp")} />
      )}

      {step === "push" && (
        <PushApprove onBack={back} onApproved={() => afterAuth("push")} onCancel={() => { setFlash("Sign-in request cancelled."); replace("another"); }} />
      )}

      {step === "error" && (
        <div>
          <CenterIcon name="shield" tone="amber" />
          <h1 style={{ textAlign: "center" }}>Couldn&apos;t sign you in</h1>
          <p className="sub" style={{ textAlign: "center" }}>{flash || "Something interrupted the sign-in."}</p>
          <ul className="tips">
            <li>Make sure you&apos;re using the correct device or account.</li>
            <li>Check your internet connection and try again.</li>
            <li>You can switch to another verification method.</li>
          </ul>
          <div className="col gap-3" style={{ marginTop: 18 }}>
            <button className="btn btn-primary" onClick={() => (account ? replace("primary") : replace("identify"))}>Try again</button>
            <button className="btn" onClick={switchAccount}>Use a different account</button>
          </div>
        </div>
      )}

      {step === "terms" && <TermsGate onAccept={() => { try { localStorage.setItem("lup_terms", "1"); } catch { /* ignore */ } replace("success"); }} />}

      {step === "success" && (
        <Success account={account} email={email} remember={remember} onContinue={() => router.push("/dashboard")} />
      )}

      {step === "recovery" && (
        <div>
          <StepBack onClick={back} />
          <CenterIcon name="info" tone="blue" />
          <h1 style={{ textAlign: "center" }}>Account recovery</h1>
          <p className="sub" style={{ textAlign: "center" }}>None of the available methods worked. Our team can help verify your identity and restore access.</p>
          <FlashNote tone="info">Contact support at <b>help@lynkeduppro.com</b> with your property or account details.</FlashNote>
          <button className="btn" style={{ marginTop: 16 }} onClick={() => replace("identify")}>Back to sign in</button>
        </div>
      )}

      {step === "fp_confirm" && account && (
        <ForgotConfirm masked={account.maskedEmail} onBack={back} onSend={() => push("fp_code")} />
      )}
      {step === "fp_code" && (
        <ForgotCode onBack={back} onOk={() => push("fp_reset")} />
      )}
      {step === "fp_reset" && (
        <ForgotReset onDone={() => { setFlash("Password updated. Please sign in."); replace("password"); }} />
      )}
    </div>
  );
}

/* ============================ screens ============================ */

function Identify({ email, setEmail, onSocial, onEmail, toRegister }: {
  email: string; setEmail: (v: string) => void;
  onSocial: (p: "google" | "microsoft" | "apple") => void; onEmail: () => void; toRegister: () => void;
}) {
  const [showEmail, setShowEmail] = useState(false);
  const valid = EMAIL_RE.test(email);
  return (
    <div>
      <div className="kicker">Welcome back</div>
      <h1>Sign in to LynkedUp</h1>
      <p className="sub">Drone inspections, AI estimates and insurance-ready reports — all in one place.</p>

      <div style={{ marginTop: 22 }}>
        <SocialButtons onPick={onSocial} />
        <div className="divider">or continue with email</div>

        {!showEmail ? (
          <button className="btn" onClick={() => setShowEmail(true)}><Icon name="mail" size={18} /> Continue with email</button>
        ) : (
          <form onSubmit={(e) => { e.preventDefault(); onEmail(); }}>
            <div className="field">
              <label className="label" htmlFor="lemail">Email address</label>
              <div className="input-wrap">
                <span className="input-ico"><Icon name="mail" size={17} /></span>
                <input id="lemail" className="input" type="email" autoFocus value={email}
                  onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" />
              </div>
            </div>
            <button className="btn btn-primary" style={{ marginTop: 12 }} disabled={!valid}>
              Continue <Icon name="arrowR" size={17} />
            </button>
          </form>
        )}
      </div>

      <p className="foot-note">New homeowner or contractor? <button className="link" onClick={toRegister}>Register here</button></p>
      <div className="secure-footer">
        <span><Icon name="lock" size={13} /> 256-bit SSL</span>
        <span><Icon name="shield" size={13} /> Licensed &amp; Insured</span>
        <span><Icon name="check" size={13} /> Drone-Powered</span>
      </div>
      <p className="demo-hint">Demo: any email signs in; an email starting with “new” shows “not found”.</p>
    </div>
  );
}

function Passkey({ account, onBack, onPassword, onAnother, onSuccess, onFail }: {
  account: Account; onBack: () => void; onPassword: () => void; onAnother: () => void; onSuccess: () => void; onFail: () => void;
}) {
  const [waiting, setWaiting] = useState(false);
  async function attempt() {
    setWaiting(true);
    try {
      if (navigator.credentials && "get" in navigator.credentials) {
        await navigator.credentials.get({
          publicKey: { challenge: new Uint8Array(32), rpId: window.location.hostname, userVerification: "preferred", timeout: 8000 },
        } as CredentialRequestOptions).catch(() => null);
      }
    } catch { /* ignore */ }
    setTimeout(onSuccess, 900); // demo: succeed
  }
  return (
    <div>
      <StepBack onClick={onBack} />
      <CenterIcon name="key" tone="amber" />
      <h1 style={{ textAlign: "center" }}>Use your passkey</h1>
      <p className="sub" style={{ textAlign: "center" }}>Verify it&apos;s you with your device&apos;s fingerprint, face or screen lock.</p>
      {waiting ? (
        <div className="interstitial"><Spinner lg /><p className="muted">Waiting for your device…</p></div>
      ) : (
        <button className="btn btn-primary" style={{ marginTop: 20 }} onClick={attempt}>Verify with passkey</button>
      )}
      <div className="col gap-2" style={{ marginTop: 16, alignItems: "center" }}>
        <button className="link" onClick={onPassword}>Use your password instead</button>
        <button className="link" onClick={onAnother}>Try another way</button>
      </div>
      <p className="demo-hint">Demo: passkey always succeeds here.</p>
      <button hidden onClick={onFail} />
    </div>
  );
}

function Password({ account, flash, onBack, onForgot, onOtp, onLocked, onOk }: {
  account: Account; flash: string; onBack: () => void; onForgot: () => void; onOtp: () => void; onLocked: () => void; onOk: () => void;
}) {
  const [pw, setPw] = useState("");
  const [show, setShow] = useState(false);
  const [err, setErr] = useState("");
  function submit(e: React.FormEvent) {
    e.preventDefault();
    if (pw.toLowerCase() === "wrong") { setErr("locked"); onLocked(); return; }
    if (!pw) return;
    onOk();
  }
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>Enter your password</h1>
      <p className="sub">Signing in as {account.maskedEmail}</p>
      {flash && <div style={{ marginTop: 14 }}><FlashNote tone="info">{flash}</FlashNote></div>}
      {err === "locked" && <div style={{ marginTop: 14 }}><FlashNote tone="error">Account temporarily locked after too many attempts. <button className="link" onClick={onOtp}>Get a one-time code instead</button>.</FlashNote></div>}
      <form onSubmit={submit} style={{ marginTop: 16 }}>
        <div className="field">
          <label className="label" htmlFor="lpw">Password</label>
          <div className="input-wrap">
            <span className="input-ico"><Icon name="lock" size={17} /></span>
            <input id="lpw" className="input" type={show ? "text" : "password"} autoFocus value={pw} onChange={(e) => setPw(e.target.value)} placeholder="••••••••" />
            <button type="button" className="input-eye" onClick={() => setShow((s) => !s)} aria-label={show ? "Hide" : "Show"}>
              <Icon name={show ? "eyeOff" : "eye"} size={18} />
            </button>
          </div>
        </div>
        <button className="btn btn-primary" style={{ marginTop: 14 }}>Sign in <Icon name="arrowR" size={16} /></button>
      </form>
      <div className="row between" style={{ marginTop: 16 }}>
        <button className="link" onClick={onForgot}>Forgot password?</button>
        <button className="link" onClick={onOtp}>Sign in using email OTP</button>
      </div>
      <p className="demo-hint">Demo: any password works; type “wrong” to see the lockout. Password always needs 2-step next.</p>
    </div>
  );
}

function OtpVerify({ account, remember, setRemember, onBack, onVerified }: {
  account: Account; remember: boolean; setRemember: (v: boolean) => void; onBack: () => void; onVerified: () => void;
}) {
  const [channel, setChannel] = useState<"email" | "sms" | "wa">("email");
  const [error, setError] = useState(false);
  const target = channel === "email" ? account.maskedEmail : channel === "sms" ? account.maskedPhone : account.maskedWa;
  function complete(code: string) {
    if (code === "000000") { setError(true); return; }
    setError(false); onVerified();
  }
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>2-step verification</h1>
      <p className="sub">Enter the 6-digit code we sent you to finish signing in.</p>
      <div className="seg" style={{ margin: "16px 0 14px" }}>
        <button className={channel === "email" ? "on" : ""} onClick={() => { setChannel("email"); setError(false); }}><Icon name="mail" size={15} /> Email</button>
        <button className={channel === "sms" ? "on" : ""} onClick={() => { setChannel("sms"); setError(false); }}><Icon name="sms" size={15} /> SMS</button>
        <button className={channel === "wa" ? "on" : ""} onClick={() => { setChannel("wa"); setError(false); }}><Icon name="whatsapp" size={15} /> WhatsApp</button>
      </div>
      <p className="faint" style={{ fontSize: 12.5, marginBottom: 12 }}>Code sent to {target}</p>
      <OtpBoxes onComplete={complete} error={error} />
      {error && <div style={{ marginTop: 12 }}><FlashNote tone="error">Incorrect code. Please try again.</FlashNote></div>}
      <div className="row between" style={{ margin: "14px 0" }}>
        <ResendLink seconds={30} />
        <span />
      </div>
      <RememberDevice checked={remember} onChange={setRemember} note="2-step is still required at each sign-in." />
      <p className="demo-hint">Demo: any 6 digits verify; “000000” shows an error.</p>
    </div>
  );
}

function AnotherWay({ account, onBack, go }: { account: Account; onBack: () => void; go: (s: Step) => void }) {
  const [more, setMore] = useState(false);
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>Try another way</h1>
      <p className="sub">Choose a different way to verify it&apos;s you.</p>
      <div className="col gap-3" style={{ marginTop: 18 }}>
        {account.hasPasskey && <MethodRow icon="key" title="Use your passkey" sub="Fingerprint, face or screen lock" onClick={() => go("passkey")} />}
        {account.hasPush && <MethodRow icon="smartphone" title="Approve sign-in with a mobile app" sub="Send a push to your phone" onClick={() => go("push")} />}
        <MethodRow icon="lock" title="Enter your password" onClick={() => go("password")} />
        {account.hasTotp && <MethodRow icon="totp" title="Get a code from your authenticator app" onClick={() => go("totp")} />}
        <MethodRow icon="mail" title="Email a one-time code" sub={account.maskedEmail} onClick={() => go("otp")} />
        {more && <>
          <MethodRow icon="sms" title="Text a one-time code" sub={account.maskedPhone} onClick={() => go("otp")} />
          <MethodRow icon="whatsapp" title="WhatsApp a one-time code" sub={account.maskedWa} onClick={() => go("otp")} />
        </>}
      </div>
      {!more
        ? <button className="link" style={{ marginTop: 16 }} onClick={() => setMore(true)}>Show more options</button>
        : <button className="link" style={{ marginTop: 16 }} onClick={() => go("recovery")}>None of these work →</button>}
    </div>
  );
}

function Totp({ remember, setRemember, onBack, onVerified }: { remember: boolean; setRemember: (v: boolean) => void; onBack: () => void; onVerified: () => void }) {
  const [setupKey, setSetupKey] = useState(false);
  const [error, setError] = useState(false);
  const [key, setKey] = useState("");
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>Authenticator code</h1>
      <p className="sub">Open your authenticator app and enter the 6-digit code.</p>
      <div style={{ marginTop: 18 }}>
        {!setupKey ? (
          <OtpBoxes onComplete={(c) => { if (c === "000000") setError(true); else onVerified(); }} error={error} />
        ) : (
          <div className="field">
            <label className="label">Setup key</label>
            <input className="input" value={key} onChange={(e) => setKey(e.target.value)} placeholder="xxxx-xxxx-xxxx" />
            <button className="btn btn-primary" style={{ marginTop: 12 }} onClick={() => onVerified()}>Verify</button>
          </div>
        )}
      </div>
      {error && <div style={{ marginTop: 12 }}><FlashNote tone="error">Incorrect code.</FlashNote></div>}
      <button className="link" style={{ margin: "14px 0" }} onClick={() => setSetupKey((s) => !s)}>
        {setupKey ? "Enter a 6-digit code instead" : "Enter setup key instead"}
      </button>
      <RememberDevice checked={remember} onChange={setRemember} />
      <p className="demo-hint">Demo: any 6 digits verify; “000000” fails.</p>
    </div>
  );
}

function PushApprove({ onBack, onApproved, onCancel }: { onBack: () => void; onApproved: () => void; onCancel: () => void }) {
  const [approved, setApproved] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => { setApproved(true); setTimeout(onApproved, 900); }, 3200);
    return () => clearTimeout(t);
  }, [onApproved]);
  return (
    <div>
      <StepBack onClick={onBack} />
      <CenterIcon name="smartphone" tone={approved ? "green" : "amber"} />
      <h1 style={{ textAlign: "center" }}>{approved ? "Approved — signing you in…" : "Check your phone"}</h1>
      <p className="sub" style={{ textAlign: "center" }}>{approved ? "Your sign-in was approved." : "We sent a notification to your mobile app. Approve it to continue."}</p>
      <div className="interstitial">{approved ? <Icon name="check" size={30} /> : <Spinner lg />}</div>
      {!approved && <button className="btn" onClick={onCancel}>Cancel</button>}
      <p className="demo-hint">Demo: auto-approves after ~3 seconds.</p>
    </div>
  );
}

function TermsGate({ onAccept }: { onAccept: () => void }) {
  const [reviewed, setReviewed] = useState(false);
  const [checked, setChecked] = useState(false);
  const scrollRef = useRef<HTMLDivElement>(null);
  // If the terms fit without scrolling, enable the checkbox right away.
  useEffect(() => {
    const el = scrollRef.current;
    if (el && el.scrollHeight <= el.clientHeight + 12) setReviewed(true);
  }, []);
  function onScroll(e: React.UIEvent<HTMLDivElement>) {
    const el = e.currentTarget;
    if (el.scrollTop + el.clientHeight >= el.scrollHeight - 12) setReviewed(true);
  }
  return (
    <div>
      <h1>Before you continue</h1>
      <p className="sub">Please review and accept the portal terms to finish signing in.</p>
      <div className="terms-scroll" ref={scrollRef} onScroll={onScroll}>
        {["Authorised use", "Accuracy of records", "Data & privacy", "Security", "Acceptable conduct"].map((h, i) => (
          <div key={h} style={{ marginBottom: 14 }}>
            <h4 style={{ fontSize: 14, fontWeight: 700, marginBottom: 5 }}>{i + 1}. {h}</h4>
            <p style={{ fontSize: 13, color: "var(--muted)", lineHeight: 1.6 }}>
              By using the Lynkedup Pro portal you agree to access only records you are entitled to, keep your information accurate, protect your credentials, and use the service lawfully. Verification is required to safeguard your account.
            </p>
          </div>
        ))}
        <p className="faint" style={{ fontSize: 12 }}>— End of terms —</p>
      </div>
      <label className={`remember-card ${!reviewed ? "is-disabled" : ""}`} style={{ marginTop: 14 }}>
        <input type="checkbox" disabled={!reviewed} checked={checked} onChange={(e) => setChecked(e.target.checked)} />
        <span style={{ fontWeight: 600, fontSize: 13.5 }}>I accept the Terms of Use and Privacy Policy{!reviewed && <span className="faint" style={{ fontWeight: 500 }}> — scroll to the end to enable</span>}</span>
      </label>
      <button className="btn btn-primary" style={{ marginTop: 16 }} disabled={!checked} onClick={onAccept}>I accept</button>
    </div>
  );
}

function Success({ account, email, remember, onContinue }: { account: Account | null; email: string; remember: boolean; onContinue: () => void }) {
  useEffect(() => {
    if (remember) { try { localStorage.setItem("lup_trusted", String(Date.now() + 90 * 864e5)); } catch { /* ignore */ } }
    const t = setTimeout(onContinue, 2600);
    return () => clearTimeout(t);
  }, [remember, onContinue]);
  return (
    <div style={{ textAlign: "center" }}>
      <CenterIcon name="check" tone="green" />
      <h1>You&apos;re signed in</h1>
      <p className="sub">Welcome back to the Lynkedup Pro portal.</p>
      <div style={{ display: "inline-flex", alignItems: "center", gap: 10, margin: "18px 0", padding: "8px 14px", border: "1px solid var(--line-2)", borderRadius: 999 }}>
        <Avatar initials={account?.initials ?? "LP"} size={28} />
        <span style={{ fontSize: 13.5, fontWeight: 600 }}>{email || account?.name}</span>
      </div>
      {remember && <p className="faint" style={{ fontSize: 12.5 }}>We&apos;ll remember this device for 90 days.</p>}
      <button className="btn btn-primary" style={{ marginTop: 16 }} onClick={onContinue}>Go to dashboard now <Icon name="arrowR" size={16} /></button>
    </div>
  );
}

/* ---- forgot password mini machine ---- */
function ForgotConfirm({ masked, onBack, onSend }: { masked: string; onBack: () => void; onSend: () => void }) {
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>Reset your password</h1>
      <p className="sub">We&apos;ll send a verification code to {masked}.</p>
      <button className="btn btn-primary" style={{ marginTop: 18 }} onClick={onSend}>Send code <Icon name="arrowR" size={16} /></button>
    </div>
  );
}
function ForgotCode({ onBack, onOk }: { onBack: () => void; onOk: () => void }) {
  const [error, setError] = useState(false);
  return (
    <div>
      <StepBack onClick={onBack} />
      <h1>Enter the code</h1>
      <p className="sub">Enter the 6-digit code we just sent.</p>
      <div style={{ marginTop: 18 }}><OtpBoxes onComplete={(c) => (c === "000000" ? setError(true) : onOk())} error={error} /></div>
      {error && <div style={{ marginTop: 12 }}><FlashNote tone="error">Incorrect code.</FlashNote></div>}
      <div style={{ marginTop: 14 }}><ResendLink seconds={30} /></div>
      <p className="demo-hint">Demo: any 6 digits work; “000000” fails.</p>
    </div>
  );
}
function ForgotReset({ onDone }: { onDone: () => void }) {
  const [pw, setPw] = useState("");
  const [confirm, setConfirm] = useState("");
  const okMatch = pw.length > 0 && pw === confirm;
  const strongEnough = pw.length >= 8;
  return (
    <div>
      <h1>Create a new password</h1>
      <p className="sub">Choose a strong password you haven&apos;t used before.</p>
      <div className="field" style={{ marginTop: 16 }}>
        <label className="label">New password</label>
        <input className="input" type="password" value={pw} onChange={(e) => setPw(e.target.value)} placeholder="New password" />
      </div>
      <PasswordStrength pw={pw} />
      <div className="field" style={{ marginTop: 14 }}>
        <label className="label">Confirm password</label>
        <input className="input" type="password" value={confirm} onChange={(e) => setConfirm(e.target.value)} placeholder="Re-enter password" />
      </div>
      {confirm && !okMatch && <p className="faint" style={{ fontSize: 12, color: "#fca5a5", marginTop: 6 }}>Passwords do not match.</p>}
      <button className="btn btn-primary" style={{ marginTop: 16 }} disabled={!(okMatch && strongEnough)} onClick={onDone}>Update password</button>
    </div>
  );
}

/* ---- helpers ---- */
function CenterIcon({ name, tone }: { name: string; tone: "amber" | "green" | "blue" }) {
  const bg = tone === "green" ? "rgba(52,211,153,.14)" : tone === "blue" ? "rgba(56,189,248,.14)" : "var(--primary-ghost)";
  const fg = tone === "green" ? "#6ee7b7" : tone === "blue" ? "#7dd3fc" : "var(--primary-2)";
  return (
    <span style={{ width: 64, height: 64, margin: "4px auto 16px", display: "grid", placeItems: "center", borderRadius: 18, background: bg, color: fg }}>
      <Icon name={name} size={28} />
    </span>
  );
}
function cap(s: string) { return s.charAt(0).toUpperCase() + s.slice(1); }
