// auth.jsx — the login gate. AuthGate decides which screen to show:
//   • checking            → a quiet "Loading…"
//   • signed out          → <LoginView>  (log in / register)
//   • signed in, unverified → <VerifyNotice>  (check your email)
//   • signed in, verified → <App>  (the dashboard, from app.jsx)
// Loaded *after* app.jsx so <App> and <EfimeraMark> are already in scope, and
// it owns the single ReactDOM root.

function useAuth() {
  const [state, setState] = React.useState({ status: "checking", user: null });
  const refresh = React.useCallback(() => {
    setState((s) => ({ ...s, status: s.status === "checking" ? "checking" : s.status }));
    fetch("/auth/me", { credentials: "same-origin" })
      .then((r) => (r.ok ? r.json() : null))
      .then((user) =>
        setState({ status: user ? "in" : "out", user: user || null }))
      .catch(() => setState({ status: "out", user: null }));
  }, []);
  React.useEffect(refresh, [refresh]);
  return {
    ...state,
    refresh,
    setOut: () => setState({ status: "out", user: null }),
  };
}

function LoginView({ onAuthed }) {
  const [tab, setTab] = React.useState("login"); // "login" | "register"
  const [identifier, setIdentifier] = React.useState("");
  const [username, setUsername] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");
  const [error, setError] = React.useState(null);
  const [busy, setBusy] = React.useState(false);

  const submit = (e) => {
    e.preventDefault();
    setError(null);
    setBusy(true);
    const isReg = tab === "register";
    const body = isReg
      ? { username, email, password }
      : { identifier, password };
    fetch(isReg ? "/auth/register" : "/auth/login", {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    })
      .then(async (r) => {
        if (!r.ok) {
          const d = await r.json().catch(() => ({}));
          const detail = d && d.detail;
          throw new Error(
            typeof detail === "string"
              ? detail
              : (detail && detail.message) || "Something went wrong"
          );
        }
        onAuthed(); // re-checks /auth/me — AuthGate routes from there
      })
      .catch((err) => setError(err.message))
      .finally(() => setBusy(false));
  };

  return (
    <div className="login">
      <div className="login__card">
        <div className="login__brand">
          <EfimeraMark night={false} />
        </div>
        <h1 className="login__title">
          <em>Every ticker,</em>
          <br />
          one current price.
        </h1>
        <div className="login__tabs">
          <button
            type="button"
            className={"login__tab" + (tab === "login" ? " login__tab--on" : "")}
            onClick={() => { setTab("login"); setError(null); }}
          >
            Log in
          </button>
          <button
            type="button"
            className={"login__tab" + (tab === "register" ? " login__tab--on" : "")}
            onClick={() => { setTab("register"); setError(null); }}
          >
            Register
          </button>
        </div>
        <form className="login__form" onSubmit={submit}>
          {tab === "register" ? (
            <>
              <input
                className="login__input"
                placeholder="Username"
                value={username}
                autoComplete="username"
                onChange={(e) => setUsername(e.target.value)}
              />
              <input
                className="login__input"
                placeholder="Email"
                type="email"
                value={email}
                autoComplete="email"
                onChange={(e) => setEmail(e.target.value)}
              />
            </>
          ) : (
            <input
              className="login__input"
              placeholder="Username or email"
              value={identifier}
              autoComplete="username"
              onChange={(e) => setIdentifier(e.target.value)}
            />
          )}
          <input
            className="login__input"
            placeholder="Password"
            type="password"
            value={password}
            autoComplete={tab === "register" ? "new-password" : "current-password"}
            onChange={(e) => setPassword(e.target.value)}
          />
          {error && <div className="login__error">{error}</div>}
          <button className="login__submit" type="submit" disabled={busy}>
            {busy ? "…" : tab === "register" ? "Create account" : "Log in"}
          </button>
        </form>
        {tab === "register" && (
          <p className="login__fineprint">
            We&rsquo;ll email you a link to confirm your address.
          </p>
        )}
      </div>
    </div>
  );
}

function VerifyNotice({ user, onRefresh, onLogout }) {
  const [busy, setBusy] = React.useState(false);
  const [note, setNote] = React.useState(null);

  const resend = () => {
    setBusy(true);
    setNote(null);
    fetch("/auth/resend-verification", {
      method: "POST",
      credentials: "same-origin",
    })
      .then((r) => {
        if (!r.ok) throw new Error();
        setNote("Sent — check your inbox.");
      })
      .catch(() => setNote("Couldn't resend just now. Try again in a moment."))
      .finally(() => setBusy(false));
  };

  return (
    <div className="login">
      <div className="login__card">
        <div className="login__brand">
          <EfimeraMark night={false} />
        </div>
        <h1 className="login__title">Confirm your email</h1>
        <p className="login__verify-text">
          We sent a confirmation link to <strong>{user.email}</strong>. Click it
          to activate your dashboard, then come back here.
        </p>
        {note && <div className="login__note">{note}</div>}
        <div className="login__form">
          <button className="login__submit" type="button" onClick={onRefresh}>
            I&rsquo;ve confirmed — continue
          </button>
          <button className="login__tab" type="button" disabled={busy}
                  onClick={resend}>
            {busy ? "…" : "Resend the email"}
          </button>
          <button className="login__linkbtn" type="button" onClick={onLogout}>
            Log out
          </button>
        </div>
      </div>
    </div>
  );
}

function AuthGate() {
  const auth = useAuth();
  if (auth.status === "checking") {
    return <div className="login login--checking">Loading…</div>;
  }
  if (auth.status === "out") {
    return <LoginView onAuthed={auth.refresh} />;
  }
  // status === "in"
  if (!auth.user.email_verified) {
    return (
      <VerifyNotice
        user={auth.user}
        onRefresh={auth.refresh}
        onLogout={() => {
          fetch("/auth/logout", { method: "POST", credentials: "same-origin" })
            .finally(auth.setOut);
        }}
      />
    );
  }
  return <App onLogout={auth.setOut} />;
}

window.AuthGate = AuthGate;

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<AuthGate />);
