// Shared auth — LoginModal + session helpers. SPEC §10.3.
//
// Drives Supabase Auth sign-in / sign-up via `window.supabase.auth.*` and
// syncs membership state from GET /me into `window.gfUser`. Exposes:
//
//   window.LoginModal       React component with Sign-in / Create-account tabs
//   window.useAuth          Hook that subscribes to `gf:auth` events
//   window.isMember         `gfUser.membership.active === true` check
//   window.getGfUser        Snapshot accessor for the in-memory cache
//   window.signOut          Calls supabase.auth.signOut and clears the cache
//
// Membership state is derived entirely from the /me response — no
// sessionStorage flags are read or written here.

const { useState: useStateA, useEffect: useEffectA } = React;

// ───── helpers ─────────────────────────────────────────────────────────────
function getGfUser() {
  return window.gfUser || null;
}
function isMember() {
  const u = getGfUser();
  return !!(u && u.membership && u.membership.active === true);
}
function useAuth() {
  const [user, setUserState] = useStateA(getGfUser());
  useEffectA(() => {
    const on = () => setUserState(getGfUser());
    window.addEventListener("gf:auth", on);
    return () => window.removeEventListener("gf:auth", on);
  }, []);
  return { user, member: !!(user && user.membership && user.membership.active), isMember };
}

async function signOut() {
  try {
    await window.supabase.auth.signOut();
  } finally {
    window.gfUser = null;
    window.dispatchEvent(new Event("gf:auth"));
  }
}

// Kick off one /me read on load if we already have a stored session.
if (typeof window !== "undefined" && window.supabase && !window.__gfMeBootstrapped) {
  window.__gfMeBootstrapped = true;
  window.refreshGfUser && window.refreshGfUser();
}

// ───── LoginModal ──────────────────────────────────────────────────────────
function LoginModal({ open, onClose, onSuccess, initialTab = "signin" }) {
  const [tab, setTab] = useStateA(initialTab);
  const [email, setEmail] = useStateA("");
  const [pw, setPw] = useStateA("");
  const [firstName, setFirstName] = useStateA("");
  const [lastName, setLastName] = useStateA("");
  const [err, setErr] = useStateA("");
  const [busy, setBusy] = useStateA(false);
  const [done, setDone] = useStateA(false);

  useEffectA(() => {
    if (open) {
      setTab(initialTab);
      setEmail("");
      setPw("");
      setFirstName("");
      setLastName("");
      setErr("");
      setBusy(false);
      setDone(false);
    }
    document.body.classList.toggle("scroll-lock", !!open);
    return () => document.body.classList.remove("scroll-lock");
  }, [open, initialTab]);

  const finish = () => {
    setTimeout(() => {
      onSuccess && onSuccess();
      onClose && onClose();
    }, 700);
  };

  const submit = async (e) => {
    e && e.preventDefault();
    setErr("");
    if (!window.isValidEmail(email)) return setErr("Please enter a valid email.");
    if (!window.isValidPassword(pw)) return setErr("Password must be at least 6 characters.");
    if (tab === "signup") {
      if (!firstName.trim()) return setErr("Please enter your first name.");
      if (!lastName.trim()) return setErr("Please enter your last name.");
    }
    if (!window.supabase || !window.supabase.auth) {
      return setErr("Authentication is not configured. Update Supabase credentials to continue.");
    }
    setBusy(true);
    try {
      if (tab === "signin") {
        const { error } = await window.supabase.auth.signInWithPassword({ email, password: pw });
        if (error) throw error;
      } else {
        const { data, error } = await window.supabase.auth.signUp({
          email,
          password: pw,
          options: { data: { first_name: firstName, last_name: lastName } },
        });
        if (error) throw error;
        // Persist the name fields into public.profiles. RLS allows self-update
        // via the anon role when a session exists (SPEC §5.2).
        if (data?.user) {
          try {
            await window.supabase
              .from("profiles")
              .update({ first_name: firstName, last_name: lastName })
              .eq("id", data.user.id);
          } catch {
            // Non-fatal. The session still works; names are editable later.
          }
        }
      }
      await window.refreshGfUser();
      setBusy(false);
      setDone(true);
      finish();
    } catch (error) {
      setBusy(false);
      const msg = (error && (error.message || error.error_description)) || "Something went wrong.";
      // Friendly mapping for the most common Supabase errors.
      if (/invalid.*(login|credential)/i.test(msg)) {
        setErr("Email or password is incorrect.");
      } else if (/already (registered|exists)|user_already_exists/i.test(msg)) {
        setErr("An account with that email already exists. Try signing in instead.");
      } else {
        setErr(msg);
      }
    }
  };

  return (
    <>
      <div
        onClick={onClose}
        style={{
          position: "fixed",
          inset: 0,
          zIndex: 130,
          background: "rgba(2,2,4,.78)",
          backdropFilter: "blur(10px)",
          opacity: open ? 1 : 0,
          pointerEvents: open ? "auto" : "none",
          transition: "opacity .25s ease",
        }}
      />
      <div
        role="dialog"
        aria-modal="true"
        aria-label={tab === "signin" ? "Sign in" : "Create account"}
        style={{
          position: "fixed",
          zIndex: 140,
          top: "50%",
          left: "50%",
          transform: `translate(-50%, ${open ? "-50%" : "-46%"})`,
          opacity: open ? 1 : 0,
          pointerEvents: open ? "auto" : "none",
          transition: "transform .3s cubic-bezier(.2,.8,.2,1), opacity .25s ease",
          width: "min(480px, 94vw)",
          background: "linear-gradient(180deg,#0c0d12 0%,#07080b 100%)",
          border: "1px solid var(--line-strong)",
          boxShadow: "0 40px 120px rgba(0,0,0,.7)",
        }}
      >
        <div style={{ padding: "24px 32px 18px", borderBottom: "1px solid var(--line)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: ".3em", color: "var(--gold)" }}>
            {tab === "signin" ? "MEMBER SIGN IN" : "CREATE ACCOUNT"}
          </div>
          <button onClick={onClose} aria-label="Close" style={{ width: 34, height: 34, display: "grid", placeItems: "center" }}>
            <svg width="16" height="16" viewBox="0 0 18 18">
              <path d="M3 3l12 12M15 3L3 15" stroke="#f2eee4" strokeWidth="1.4" strokeLinecap="round" />
            </svg>
          </button>
        </div>
        <div style={{ padding: "28px 36px 28px" }}>
          {done ? (
            <div style={{ textAlign: "center", padding: "20px 0" }}>
              <div style={{ width: 56, height: 56, borderRadius: "50%", border: "1px solid var(--gold)", display: "grid", placeItems: "center", margin: "0 auto 20px", background: "rgba(201,169,97,.1)" }}>
                <svg width="22" height="22" viewBox="0 0 22 22"><path d="M4 11l5 5 9-12" stroke="#d9bd7a" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" fill="none"/></svg>
              </div>
              <h3 className="serif" style={{ fontSize: 26, fontWeight: 300, letterSpacing: "-0.01em", margin: "0 0 10px" }}>
                {tab === "signin" ? "Welcome back." : "Welcome aboard."}
              </h3>
              <p style={{ fontSize: 13, color: "var(--soft)" }}>Unlocking your content…</p>
            </div>
          ) : (
            <form onSubmit={submit}>
              <div style={{ display: "flex", gap: 4, marginBottom: 22, borderBottom: "1px solid var(--line)" }}>
                {[
                  ["signin", "Sign in"],
                  ["signup", "Create account"],
                ].map(([id, label]) => {
                  const active = tab === id;
                  return (
                    <button
                      type="button"
                      key={id}
                      onClick={() => setTab(id)}
                      className="mono"
                      style={{
                        padding: "10px 14px",
                        fontSize: 10,
                        letterSpacing: ".24em",
                        color: active ? "var(--gold)" : "var(--muted)",
                        borderBottom: active ? "1px solid var(--gold)" : "1px solid transparent",
                        marginBottom: -1,
                      }}
                    >
                      {label.toUpperCase()}
                    </button>
                  );
                })}
              </div>
              <h2 className="serif" style={{ fontSize: 28, fontWeight: 300, letterSpacing: "-0.02em", lineHeight: 1.1, marginBottom: 8 }}>
                {tab === "signin" ? (
                  <>
                    Sign in to your <em style={{ color: "var(--gold-2)", fontStyle: "italic" }}>account.</em>
                  </>
                ) : (
                  <>
                    Become a <em style={{ color: "var(--gold-2)", fontStyle: "italic" }}>member.</em>
                  </>
                )}
              </h2>
              <p style={{ fontSize: 13, color: "var(--soft)", lineHeight: 1.6, marginBottom: 22 }}>
                {tab === "signin"
                  ? "Continue where you left off — articles, podcasts, AMAs, and members-only protocols."
                  : "Create your account first; pick a plan on the next step."}
              </p>
              {tab === "signup" && (
                <>
                  <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 14 }}>
                    <AField label="First Name" value={firstName} onChange={setFirstName} placeholder="First" />
                    <AField label="Last Name" value={lastName} onChange={setLastName} placeholder="Last" />
                  </div>
                </>
              )}
              <AField label="Email" type="email" value={email} onChange={setEmail} placeholder="you@example.com" autoFocus />
              <div style={{ height: 14 }} />
              <AField
                label="Password"
                type="password"
                value={pw}
                onChange={setPw}
                placeholder="••••••••"
                right={
                  tab === "signin" ? (
                    <a href="#" onClick={(e) => { e.preventDefault(); }} className="mono" style={{ fontSize: 9, letterSpacing: ".24em", color: "var(--gold-2)" }}>
                      FORGOT?
                    </a>
                  ) : null
                }
              />
              {err && <div style={{ marginTop: 14, fontSize: 12.5, color: "#e9a58c" }}>{err}</div>}
              <button
                type="submit"
                disabled={busy}
                style={{
                  marginTop: 22,
                  width: "100%",
                  padding: "18px 24px",
                  background: "var(--gold)",
                  color: "#0b0b0d",
                  fontWeight: 600,
                  letterSpacing: ".2em",
                  fontSize: 12,
                  textTransform: "uppercase",
                  opacity: busy ? 0.7 : 1,
                  cursor: busy ? "wait" : "pointer",
                  display: "inline-flex",
                  alignItems: "center",
                  justifyContent: "center",
                  gap: 12,
                }}
              >
                {busy ? (tab === "signin" ? "Signing in…" : "Creating account…") : tab === "signin" ? "Sign In" : "Create Account"}
                {!busy && (
                  <svg width="14" height="14" viewBox="0 0 14 14">
                    <path d="M1 7h12M9 3l4 4-4 4" stroke="#0b0b0d" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                )}
              </button>
              {tab === "signin" && (
                <div style={{ marginTop: 20, paddingTop: 20, borderTop: "1px solid var(--line)", textAlign: "center", fontSize: 13, color: "var(--soft)" }}>
                  Not a member yet?{" "}
                  <a href="checkout.html" style={{ color: "var(--gold-2)", borderBottom: "1px solid var(--gold-3)", paddingBottom: 2 }}>
                    Become one →
                  </a>
                </div>
              )}
            </form>
          )}
        </div>
      </div>
    </>
  );
}

function AField({ label, value, onChange, type = "text", placeholder, right, autoFocus }) {
  return (
    <label style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
        <span className="mono" style={{ fontSize: 10, letterSpacing: ".24em", color: "var(--gold)" }}>
          {label.toUpperCase()}
        </span>
        {right}
      </div>
      <input
        autoFocus={autoFocus}
        type={type}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          background: "rgba(255,255,255,.02)",
          border: "1px solid var(--line-strong)",
          padding: "14px 16px",
          fontSize: 15,
          color: "var(--bone)",
          outline: "none",
          fontFamily: "Inter, system-ui, sans-serif",
          transition: "border-color .15s",
        }}
        onFocus={(e) => (e.target.style.borderColor = "var(--gold)")}
        onBlur={(e) => (e.target.style.borderColor = "var(--line-strong)")}
      />
    </label>
  );
}

Object.assign(window, { LoginModal, isMember, useAuth, getGfUser, signOut });
