// ─────────────────────────────────────────────────────────────────────────
// Meridian — Login (real auth via POST /api/auth/login)
// Email + password, optional/required 2FA code, friendly errors, lockout.
// ─────────────────────────────────────────────────────────────────────────
function Login({ onLogin, theme, onToggleTheme }) {
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [showPw, setShowPw] = useState(false);
  const [use2fa, setUse2fa] = useState(false);
  const [code, setCode] = useState(["", "", "", "", "", ""]);
  const [err, setErr] = useState("");
  const [loading, setLoading] = useState(false);
  const codeRefs = useRef([]);

  const setDigit = (i, v) => {
    v = v.replace(/\D/g, "").slice(-1);
    setCode((c) => { const n = [...c]; n[i] = v; return n; });
    if (v && i < 5) codeRefs.current[i + 1]?.focus();
  };
  const onCodeKey = (i, e) => { if (e.key === "Backspace" && !code[i] && i > 0) codeRefs.current[i - 1]?.focus(); };
  const showTwoFa = () => { setUse2fa(true); setTimeout(() => codeRefs.current[0]?.focus(), 50); };

  const submit = async (e) => {
    e && e.preventDefault();
    setErr("");
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) { setErr("That doesn't look like a valid email address."); return; }
    if (!pw) { setErr("Enter your password to continue."); return; }
    const totp = use2fa ? code.join("") : "";
    if (use2fa && totp.length < 6) { setErr("Enter all six digits of your 2FA code."); return; }
    setLoading(true);
    try {
      const res = await API.login(email.trim(), pw, totp || undefined);
      const me = await API.me().catch(() => null);
      onLogin({ ...res, user: me && me.user });
    } catch (ex) {
      const code = ex.status;
      const e = ex.data && ex.data.error;
      if (e === "totp_required") {
        setErr("Enter your 2FA code to finish signing in.");
        if (!use2fa) showTwoFa();
      } else if (e === "totp_invalid") {
        setErr("That 2FA code wasn't accepted. Try the current code.");
      } else if (code === 429) {
        const s = ex.data && ex.data.retry_after_s;
        setErr(`Too many attempts. Try again${s ? " in " + s + " s" : " shortly"}.`);
      } else if (code === 401) {
        setErr("Invalid email or password.");
      } else {
        setErr(ex.message || "Sign-in failed. Please try again.");
      }
      setLoading(false);
    }
  };

  return (
    <div style={{ minHeight: "100%", display: "flex", flexDirection: "column", background: "var(--bg-app)", position: "relative", overflow: "hidden" }}>
      <div aria-hidden style={{ position: "absolute", top: "-22%", left: "50%", transform: "translateX(-50%)", width: 720, height: 720, borderRadius: 999, background: "radial-gradient(circle, color-mix(in srgb, var(--sage-300) 38%, transparent), transparent 62%)", filter: "blur(20px)", opacity: 0.55, pointerEvents: "none" }} />

      <Row justify="space-between" style={{ padding: "20px 24px", position: "relative", zIndex: 2 }}>
        <Logo withText size={30} />
        <button className="btn btn-icon btn-sm" onClick={onToggleTheme} aria-label="Toggle theme"><Icon name={theme === "dark" ? "sun" : "moon"} size={15} /></button>
      </Row>

      <div style={{ flex: 1, display: "grid", placeItems: "center", padding: "12px 20px 60px", position: "relative", zIndex: 2 }}>
        <div className="rise" style={{ width: "100%", maxWidth: 420 }}>
          <div className="card" style={{ padding: 32, boxShadow: "var(--elev-3)" }}>
            <Col gap={4} style={{ marginBottom: 22 }}>
              <h1 style={{ fontSize: 24, fontWeight: 600, letterSpacing: "var(--tracking-tighter)", margin: 0 }}>Welcome back</h1>
              <p className="muted" style={{ fontSize: 14, margin: 0 }}>Sign in to your investment cockpit.</p>
            </Col>

            <form onSubmit={submit}>
              <Col gap={16}>
                <div>
                  <label className="label">Email</label>
                  <div className="input-icon">
                    <Icon name="mail" size={15} />
                    <input className="input" type="email" autoComplete="username" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" />
                  </div>
                </div>

                <div>
                  <Row justify="space-between" style={{ marginBottom: 6 }}>
                    <label className="label" style={{ margin: 0 }}>Password</label>
                  </Row>
                  <div className="input-icon">
                    <Icon name="lock" size={15} />
                    <input className="input" type={showPw ? "text" : "password"} autoComplete="current-password" value={pw} onChange={(e) => setPw(e.target.value)} placeholder="••••••••" style={{ paddingRight: 40 }} />
                    <button type="button" onClick={() => setShowPw(!showPw)} style={{ position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", background: "none", border: 0, padding: 6, color: "var(--fg-3)", display: "grid", placeItems: "center" }} aria-label="Toggle password">
                      <Icon name={showPw ? "eye-off" : "eye"} size={15} />
                    </button>
                  </div>
                </div>

                {use2fa ? (
                  <div className="fade">
                    <Row justify="space-between" style={{ marginBottom: 6 }}>
                      <label className="label" style={{ margin: 0 }}>2FA code</label>
                      <button type="button" onClick={() => { setUse2fa(false); setCode(["","","","","",""]); }} style={{ fontSize: 12, color: "var(--fg-3)", background: "none", border: 0 }}>Skip</button>
                    </Row>
                    <Row gap={8}>
                      {code.map((d, i) => (
                        <input key={i} ref={(el) => (codeRefs.current[i] = el)} className="input mono" inputMode="numeric" maxLength={1} value={d}
                          onChange={(e) => setDigit(i, e.target.value)} onKeyDown={(e) => onCodeKey(i, e)}
                          style={{ textAlign: "center", padding: "10px 0", fontSize: 18, fontWeight: 600 }} />
                      ))}
                    </Row>
                  </div>
                ) : (
                  <button type="button" onClick={showTwoFa} style={{ alignSelf: "flex-start", display: "inline-flex", alignItems: "center", gap: 7, background: "none", border: 0, color: "var(--sage-700)", fontSize: 13, fontWeight: 500, padding: 0, whiteSpace: "nowrap" }}>
                    <Icon name="shield-check" size={14} /> Use a 2FA code
                  </button>
                )}

                {err && (
                  <Row gap={8} className="fade" style={{ background: "var(--danger-bg)", color: "var(--danger-fg)", padding: "9px 12px", borderRadius: "var(--radius-3)", fontSize: 13, alignItems: "flex-start" }}>
                    <Icon name="alert-circle" size={15} style={{ marginTop: 1, flexShrink: 0 }} /> <span>{err}</span>
                  </Row>
                )}

                <button type="submit" className="btn btn-primary btn-block" disabled={loading} style={{ padding: "11px 14px", fontSize: 15, marginTop: 2 }}>
                  {loading ? <><Icon name="loader" size={15} className="spin" style={{ color: "#fff" }} /> Signing in…</> : <>Sign in <Icon name="arrow-right" size={15} style={{ color: "#fff" }} /></>}
                </button>
              </Col>
            </form>
          </div>

          <Row justify="center" gap={7} style={{ marginTop: 18, fontSize: 12, color: "var(--fg-3)" }}>
            <Icon name="server" size={13} /> Self-hosted · single user · your keys stay local
          </Row>
        </div>
      </div>
    </div>
  );
}
window.Login = Login;
