/* auth.jsx
 *
 * Dedicated-route auth UI (no modal). Three exported components:
 *
 *   <window.AuthButton/>     — top-right TopBar button. "Sign in" link when
 *                              logged out, user menu when logged in.
 *   <window.LoginView/>      — full-page login form. Email + Password.
 *   <window.SignupView/>     — full-page signup form. Full Name + Email +
 *                              Password + Confirm Password. No username
 *                              (auto-generated server-side from email).
 *   <window.LockedView/>     — interstitial for gated tabs; provides a
 *                              "Go to sign in" button.
 *
 * Why no modal: browser password managers (Firefox, Chrome, Safari) all
 * have poor autofill heuristics for dynamically-rendered modal forms.
 * Dedicated routes with proper <form> semantics get reliable autofill.
 *
 * View navigation happens via the app's existing `setView` mechanism —
 * we expose a global setter that the components call so they don't need
 * to be wired into the app's prop tree. window.AuthNav.setView is set
 * by app.jsx on mount.
 */
(function () {
  "use strict";

  // ──────────────── Hook ────────────────
  function useAuth() {
    const [, setTick] = React.useState(0);
    React.useEffect(() => {
      const unsub = window.AuthStore.subscribe(() => setTick((t) => t + 1));
      return unsub;
    }, []);
    return {
      user: window.AuthStore.user,
      isLoggedIn: window.AuthStore.isLoggedIn,
      config: window.AuthStore.config,
    };
  }

  function nav(view) {
    if (window.AuthNav && window.AuthNav.setView) window.AuthNav.setView(view);
  }

  // ──────────────── Login View ────────────────
  function LoginView() {
    const { config } = useAuth();
    const [email, setEmail] = React.useState("");
    const [password, setPassword] = React.useState("");
    const [err, setErr] = React.useState(null);
    const [busy, setBusy] = React.useState(false);

    async function handleSubmit(e) {
      e.preventDefault();
      e.stopPropagation();
      setErr(null);
      setBusy(true);
      try {
        await window.AuthStore.login({
          username_or_email: email.trim(),
          password: password,
        });
        const cm = (window.UserData && window.UserData.getCertMode && window.UserData.getCertMode()) || null;
        nav(cm ? "cert-home" : "certs");
      } catch (e) {
        setErr(e && e.message ? e.message : "Login failed. Check your email and password.");
      } finally {
        setBusy(false);
      }
    }

    const googleEnabled = !!(config && config.google_enabled);

    return React.createElement(
      "div",
      { className: "auth-page" },
      React.createElement(
        "div",
        { className: "auth-card" },
        React.createElement("h1", { className: "auth-title" }, "Sign in"),
        React.createElement(
          "form",
          {
            className: "auth-form",
            method: "post",
            action: "/api/login",
            onSubmit: handleSubmit,
          },
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Email"),
            React.createElement("input", {
              type: "email",
              name: "email",
              autoComplete: "email",
              value: email,
              onChange: (e) => setEmail(e.target.value),
              required: true,
              autoFocus: true,
            })
          ),
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Password"),
            React.createElement("input", {
              type: "password",
              name: "password",
              autoComplete: "current-password",
              value: password,
              onChange: (e) => setPassword(e.target.value),
              required: true,
            })
          ),
          err && React.createElement("div", { className: "auth-err" }, err),
          React.createElement(
            "button",
            {
              type: "submit",
              className: "btn btn-primary auth-submit",
              disabled: busy,
            },
            busy ? "Signing in…" : "Sign in"
          )
        ),
        React.createElement("div", { className: "auth-divider" }, "or"),
        React.createElement(
          "button",
          {
            type: "button",
            className: "btn auth-google",
            disabled: !googleEnabled,
            title: googleEnabled
              ? "Continue with Google"
              : "Google sign-in is not configured on this server",
            onClick: () => window.AuthStore.loginWithGoogle(),
          },
          googleIcon(),
          React.createElement(
            "span",
            null,
            googleEnabled ? "Continue with Google" : "Google (not configured)"
          )
        ),
        React.createElement(
          "div",
          { className: "auth-switch" },
          React.createElement(
            "button",
            {
              type: "button",
              className: "auth-switch-link",
              onClick: () => nav("forgot"),
            },
            "Forgot password?"
          )
        ),
        React.createElement(
          "div",
          { className: "auth-switch" },
          "Don't have an account? ",
          React.createElement(
            "button",
            {
              type: "button",
              className: "auth-switch-link",
              onClick: () => nav("signup"),
            },
            "Create one"
          )
        )
      )
    );
  }

  // ──────────────── Signup View ────────────────
  function SignupView() {
    const { config } = useAuth();
    const [name, setName] = React.useState("");
    const [email, setEmail] = React.useState("");
    const [password, setPassword] = React.useState("");
    const [password2, setPassword2] = React.useState("");
    const [err, setErr] = React.useState(null);
    const [busy, setBusy] = React.useState(false);

    const passwordsMatch = password === password2;
    const showPwMismatch = password && password2 && !passwordsMatch;
    const hasLocal = window.AuthStore.hasLocalState();

    async function handleSubmit(e) {
      e.preventDefault();
      e.stopPropagation();
      if (!passwordsMatch) {
        setErr("Passwords do not match.");
        return;
      }
      setErr(null);
      setBusy(true);
      try {
        await window.AuthStore.signup({
          email: email.trim(),
          name: name.trim(),
          password: password,
        });
        const cm = (window.UserData && window.UserData.getCertMode && window.UserData.getCertMode()) || null;
        nav(cm ? "cert-home" : "certs");
      } catch (e) {
        setErr(e && e.message ? e.message : "Signup failed. Try again.");
      } finally {
        setBusy(false);
      }
    }

    const googleEnabled = !!(config && config.google_enabled);

    return React.createElement(
      "div",
      { className: "auth-page" },
      React.createElement(
        "div",
        { className: "auth-card" },
        React.createElement("h1", { className: "auth-title" }, "Create account"),
        hasLocal &&
          React.createElement(
            "div",
            { className: "auth-notice" },
            "We'll move your current progress into your account automatically."
          ),
        React.createElement(
          "form",
          {
            className: "auth-form",
            method: "post",
            action: "/api/signup",
            onSubmit: handleSubmit,
          },
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Full name"),
            React.createElement("input", {
              type: "text",
              name: "name",
              autoComplete: "name",
              value: name,
              onChange: (e) => setName(e.target.value),
              required: true,
              autoFocus: true,
            })
          ),
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Email"),
            React.createElement("input", {
              type: "email",
              name: "email",
              autoComplete: "email",
              value: email,
              onChange: (e) => setEmail(e.target.value),
              required: true,
            })
          ),
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Password"),
            React.createElement("input", {
              type: "password",
              name: "password",
              autoComplete: "new-password",
              minLength: 8,
              value: password,
              onChange: (e) => setPassword(e.target.value),
              required: true,
            })
          ),
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Confirm password"),
            React.createElement("input", {
              type: "password",
              name: "password_confirm",
              autoComplete: "new-password",
              minLength: 8,
              value: password2,
              onChange: (e) => setPassword2(e.target.value),
              required: true,
            })
          ),
          showPwMismatch &&
            React.createElement(
              "div",
              { className: "auth-err" },
              "Passwords do not match."
            ),
          err && React.createElement("div", { className: "auth-err" }, err),
          React.createElement(
            "button",
            {
              type: "submit",
              className: "btn btn-primary auth-submit",
              disabled: busy || !passwordsMatch || !password,
            },
            busy ? "Creating account…" : "Create account"
          )
        ),
        React.createElement("div", { className: "auth-divider" }, "or"),
        React.createElement(
          "button",
          {
            type: "button",
            className: "btn auth-google",
            disabled: !googleEnabled,
            title: googleEnabled
              ? "Continue with Google"
              : "Google sign-in is not configured on this server",
            onClick: () => window.AuthStore.loginWithGoogle(),
          },
          googleIcon(),
          React.createElement(
            "span",
            null,
            googleEnabled ? "Continue with Google" : "Google (not configured)"
          )
        ),
        React.createElement(
          "div",
          { className: "auth-switch" },
          "Already have an account? ",
          React.createElement(
            "button",
            {
              type: "button",
              className: "auth-switch-link",
              onClick: () => nav("login"),
            },
            "Sign in"
          )
        )
      )
    );
  }

  function googleIcon() {
    return React.createElement(
      "svg",
      { width: 16, height: 16, viewBox: "0 0 48 48", "aria-hidden": "true" },
      React.createElement("path", {
        fill: "#4285F4",
        d: "M45.12 24.5c0-1.56-.14-3.06-.4-4.5H24v8.51h11.84c-.51 2.75-2.06 5.08-4.39 6.64v5.52h7.11c4.16-3.83 6.56-9.47 6.56-16.17z",
      }),
      React.createElement("path", {
        fill: "#34A853",
        d: "M24 46c5.94 0 10.92-1.97 14.56-5.33l-7.11-5.52c-1.97 1.32-4.49 2.1-7.45 2.1-5.73 0-10.58-3.87-12.31-9.07H4.34v5.7C7.96 41.07 15.4 46 24 46z",
      }),
      React.createElement("path", {
        fill: "#FBBC05",
        d: "M11.69 28.18c-.44-1.32-.69-2.73-.69-4.18 0-1.45.25-2.86.69-4.18v-5.7H4.34A21.94 21.94 0 002 24c0 3.55.85 6.91 2.34 9.88l7.35-5.7z",
      }),
      React.createElement("path", {
        fill: "#EA4335",
        d: "M24 10.75c3.23 0 6.13 1.11 8.41 3.29l6.31-6.31C34.91 4.18 29.93 2 24 2 15.4 2 7.96 6.93 4.34 14.12l7.35 5.7C13.42 14.62 18.27 10.75 24 10.75z",
      })
    );
  }

  // ──────────────── Forgot Password View ────────────────
  // Step 1 of reset: ask for email. Always shows a generic success message
  // afterward, matching the backend's enumeration-prevention behavior.
  function ForgotPasswordView() {
    const [email, setEmail] = React.useState("");
    const [err, setErr] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const [sent, setSent] = React.useState(null);  // server's response message

    async function handleSubmit(e) {
      e.preventDefault();
      e.stopPropagation();
      setErr(null);
      setBusy(true);
      try {
        const r = await window.AuthStore.requestPasswordReset(email.trim());
        setSent(r && r.message ? r.message : "If an account exists, a reset link has been sent.");
      } catch (e) {
        setErr(e && e.message ? e.message : "Request failed. Try again in a moment.");
      } finally {
        setBusy(false);
      }
    }

    if (sent) {
      return React.createElement(
        "div",
        { className: "auth-page" },
        React.createElement(
          "div",
          { className: "auth-card" },
          React.createElement("h1", { className: "auth-title" }, "Check your email"),
          React.createElement("p", { className: "auth-notice" }, sent),
          React.createElement(
            "p",
            { className: "auth-fineprint" },
            "Didn't receive it within a few minutes? Check your spam folder. " +
            "If it's not there, email whertz0215@gmail.com and we'll help."
          ),
          React.createElement(
            "div",
            { className: "auth-switch" },
            React.createElement(
              "button",
              {
                type: "button",
                className: "auth-switch-link",
                onClick: () => nav("login"),
              },
              "Back to sign in"
            )
          )
        )
      );
    }

    return React.createElement(
      "div",
      { className: "auth-page" },
      React.createElement(
        "div",
        { className: "auth-card" },
        React.createElement("h1", { className: "auth-title" }, "Reset your password"),
        React.createElement(
          "p",
          { className: "auth-notice" },
          "Enter the email address for your account and we'll send a reset link."
        ),
        React.createElement(
          "form",
          { className: "auth-form", onSubmit: handleSubmit },
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Email"),
            React.createElement("input", {
              type: "email",
              autoComplete: "email",
              required: true,
              value: email,
              onChange: (e) => setEmail(e.target.value),
              disabled: busy,
            })
          ),
          err && React.createElement("div", { className: "auth-error" }, err),
          React.createElement(
            "button",
            {
              type: "submit",
              className: "btn btn-primary auth-submit",
              disabled: busy || !email.trim(),
            },
            busy ? "Sending…" : "Send reset link"
          )
        ),
        React.createElement(
          "div",
          { className: "auth-switch" },
          React.createElement(
            "button",
            {
              type: "button",
              className: "auth-switch-link",
              onClick: () => nav("login"),
            },
            "Back to sign in"
          )
        )
      )
    );
  }

  // ──────────────── Reset Password View ────────────────
  // Step 2 of reset: user lands here after clicking the email link. App.jsx
  // captures the ?reset_token=... query param into window.__resetToken and
  // routes here. We read it from there, then submit token + new password.
  function ResetPasswordView() {
    const token = (typeof window !== "undefined" && window.__resetToken) || "";
    const [password, setPassword] = React.useState("");
    const [password2, setPassword2] = React.useState("");
    const [err, setErr] = React.useState(null);
    const [busy, setBusy] = React.useState(false);
    const [done, setDone] = React.useState(false);

    const passwordsMatch = password === password2;
    const showPwMismatch = password && password2 && !passwordsMatch;

    // No token at all (page reload, back button, direct link without param).
    // Auto-redirect to /forgot instead of showing an interstitial — the
    // interstitial was the source of the post-reset "loop" UX bug.
    // The redirect happens once on mount; the rest of the render is skipped.
    React.useEffect(() => {
      if (!token && !done) nav("forgot");
    }, [token, done]);

    async function handleSubmit(e) {
      e.preventDefault();
      e.stopPropagation();
      if (!passwordsMatch) {
        setErr("Passwords do not match.");
        return;
      }
      if (password.length < 8) {
        setErr("Password must be at least 8 characters.");
        return;
      }
      setErr(null);
      setBusy(true);
      try {
        await window.AuthStore.confirmPasswordReset(token, password);
        setDone(true);
        // Clear the token from memory once redeemed so a re-render can't
        // accidentally re-submit, AND so navigating back to /reset doesn't
        // re-show the form with a stale token.
        try { window.__resetToken = null; } catch (_) {}
        // Also clear any session flags that might have been set by an
        // earlier failed reset attempt.
        try { sessionStorage.removeItem("ccna.flash.auth_error"); } catch (_) {}
      } catch (e) {
        setErr(e && e.message ? e.message : "Reset failed. The link may have expired.");
      } finally {
        setBusy(false);
      }
    }

    // No token + not done -> render nothing while the useEffect redirect fires.
    if (!token && !done) {
      return null;
    }

    if (done) {
      return React.createElement(
        "div",
        { className: "auth-page" },
        React.createElement(
          "div",
          { className: "auth-card" },
          React.createElement("h1", { className: "auth-title" }, "Password updated"),
          React.createElement(
            "p",
            { className: "auth-notice" },
            "Your password has been changed. You can sign in now."
          ),
          React.createElement(
            "button",
            {
              className: "btn btn-primary auth-submit",
              onClick: () => nav("login"),
            },
            "Go to sign in"
          )
        )
      );
    }

    return React.createElement(
      "div",
      { className: "auth-page" },
      React.createElement(
        "div",
        { className: "auth-card" },
        React.createElement("h1", { className: "auth-title" }, "Set a new password"),
        React.createElement(
          "form",
          { className: "auth-form", onSubmit: handleSubmit },
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "New password"),
            React.createElement("input", {
              type: "password",
              autoComplete: "new-password",
              required: true,
              minLength: 8,
              value: password,
              onChange: (e) => setPassword(e.target.value),
              disabled: busy,
            })
          ),
          React.createElement(
            "label",
            null,
            React.createElement("span", null, "Confirm new password"),
            React.createElement("input", {
              type: "password",
              autoComplete: "new-password",
              required: true,
              minLength: 8,
              value: password2,
              onChange: (e) => setPassword2(e.target.value),
              disabled: busy,
            })
          ),
          showPwMismatch &&
            React.createElement("div", { className: "auth-error" }, "Passwords do not match."),
          err && React.createElement("div", { className: "auth-error" }, err),
          React.createElement(
            "button",
            {
              type: "submit",
              className: "btn btn-primary auth-submit",
              disabled: busy || !passwordsMatch || password.length < 8,
            },
            busy ? "Updating…" : "Update password"
          )
        )
      )
    );
  }

  // ──────────────── TopBar button (Sign in link / user menu) ────────────────
  function AuthButton() {
    const { user, isLoggedIn } = useAuth();
    const [menuOpen, setMenuOpen] = React.useState(false);

    React.useEffect(() => {
      if (!menuOpen) return;
      const onDoc = (e) => {
        if (!e.target.closest(".user-menu-wrap")) setMenuOpen(false);
      };
      document.addEventListener("click", onDoc);
      return () => document.removeEventListener("click", onDoc);
    }, [menuOpen]);

    if (!isLoggedIn) {
      return React.createElement(
        "button",
        {
          className: "btn btn-sm auth-signin-btn",
          onClick: () => nav("login"),
        },
        "Sign in"
      );
    }

    const display = user.name || user.username || user.email;

    return React.createElement(
      "div",
      { className: "user-menu-wrap" },
      React.createElement(
        "button",
        {
          className: "user-menu-trigger",
          onClick: (e) => {
            e.stopPropagation();
            setMenuOpen((v) => !v);
          },
        },
        React.createElement("span", { className: "user-name" }, display),
        React.createElement("span", { className: "user-chev" }, menuOpen ? "▴" : "▾")
      ),
      menuOpen &&
        React.createElement(
          "div",
          { className: "user-menu" },
          React.createElement("div", { className: "user-menu-email" }, user.email || ""),
          React.createElement(
            "button",
            {
              className: "user-menu-item",
              onClick: () => {
                setMenuOpen(false);
                nav("profile");
              },
            },
            "Profile"
          ),
          // Switch cert: routes back to the cert chooser. Goes through
          // AuthNav.switchCert (defined in app.jsx) which handles the
          // force-chooser flag + state updates correctly.
          React.createElement(
            "button",
            {
              className: "user-menu-item",
              onClick: () => {
                setMenuOpen(false);
                if (window.AuthNav && window.AuthNav.switchCert) {
                  window.AuthNav.switchCert();
                } else if (window.UserData) {
                  window.UserData.setCertMode(null);
                  nav("home");
                }
              },
            },
            "Switch certification track"
          ),
          // Admin panel link — only rendered if the user is an admin.
          // Routes to /admin dashboard, which has a nav strip to all
          // admin sub-pages (users, requests, cert reviews, audit log).
          // Server-side require_admin enforces real security; this is
          // UI hygiene. is_admin comes from /api/me which checks the
          // is_admin DB column plus the legacy ADMIN_USERNAMES env var.
          user.is_admin && React.createElement(
            "button",
            {
              className: "user-menu-item",
              onClick: () => {
                setMenuOpen(false);
                nav("admin");
              },
            },
            "Admin panel"
          ),
          React.createElement(
            "button",
            {
              className: "user-menu-item",
              onClick: () => {
                setMenuOpen(false);
                window.AuthStore.logout();
                // Clear cert so the user lands on the chooser screen.
                // The app re-renders with !certMode and shows CertSelectScreen.
                if (window.UserData) window.UserData.setCertMode(null);
                nav("certs");
              },
            },
            "Sign out"
          )
        )
    );
  }

  // ──────────────── Locked-tab interstitial ────────────────
  function LockedView({ tabName, description }) {
    return React.createElement(
      "div",
      { className: "locked-view" },
      React.createElement("div", { className: "locked-icon" }, "🔒"),
      React.createElement("h2", { className: "locked-title" }, `${tabName} requires an account`),
      React.createElement(
        "p",
        { className: "locked-desc" },
        description ||
          "Sign in to access this section. Your account also syncs your progress across devices."
      ),
      React.createElement(
        "div",
        { className: "locked-actions" },
        React.createElement(
          "button",
          { className: "btn btn-primary", onClick: () => nav("login") },
          "Sign in"
        ),
        React.createElement(
          "button",
          { className: "btn", onClick: () => nav("signup") },
          "Create account"
        )
      )
    );
  }

  window.AuthButton = AuthButton;
  window.LoginView = LoginView;
  window.SignupView = SignupView;
  window.ForgotPasswordView = ForgotPasswordView;
  window.ResetPasswordView = ResetPasswordView;
  window.LockedView = LockedView;
  window.useAuth = useAuth;
})();
