const LoginModal = ({ onClose, onLogin, basketIdent }) => {
  const { user, ensureBasket } = useContext(StoreCtx);
  const [authing, setAuthing] = useState(null); // null | "cfx" | "discord"
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape" && !authing) onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [authing]);

  // Stage: no user yet → must sign in with CFX first.
  // User signed in with CFX → can optionally link Discord.
  const cfxLinked = !!user && user.via === "CFX.re";
  const discordLinked = !!user && user.discord;

  // Tebex's CFX auth is scoped to a basket, so we need a valid ident before we
  // can kick off the redirect. ensureBasket() creates one on the fly if needed.
  // Set `authing` immediately so the button shows a loading state — the
  // ensureBasket round-trip plus Tebex's auth-provider lookup can take 1–2s
  // before the browser navigates, which otherwise feels like a dead click.
  const startCfx = async () => {
    if (authing) return;
    setAuthing("cfx");
    const ident = basketIdent || await ensureBasket();
    window.location.href = tebexAuthUrl(ident, "cfx");
  };

  // Discord opens in a popup so the storefront stays open in the main tab.
  // When Discord bounces the user back, an inline script in index.html sees
  // the ?discord_popup=1 marker on the returnUrl and postMessages this
  // window + closes the popup. We re-fetch the session to pick up the newly
  // linked Discord info.
  const linkDiscord = async () => {
    if (authing) return;
    setAuthing("discord");
    const ident = basketIdent || await ensureBasket();
    // Compose a returnUrl that keeps whatever path the user was on, plus our
    // popup marker so the closer script in index.html can fire.
    const loc = window.location;
    const sep = loc.search ? "&" : "?";
    const returnPath = loc.pathname + loc.search + sep + "discord_popup=1" + loc.hash;
    const url = tebexAuthUrl(ident, "discord", returnPath);

    const w = 520, h = 720;
    const left = Math.max(0, (window.screen.availWidth - w) / 2);
    const top = Math.max(0, (window.screen.availHeight - h) / 2);
    const popup = window.open(
      url,
      "discord-link",
      `width=${w},height=${h},left=${left},top=${top},resizable=yes,scrollbars=yes`,
    );
    if (!popup) {
      // Popup blocked — fall back to a full-page redirect so linking still works.
      window.location.href = url;
      return;
    }

    const refreshSession = () =>
      fetch("/api/session", { credentials: "same-origin" })
        .then((r) => (r.ok ? r.json() : { user: null }))
        .then((d) => { if (d && d.user && onLogin) onLogin(d.user); })
        .catch(() => {});

    const onMessage = (ev) => {
      if (ev.origin !== window.location.origin) return;
      if (!ev.data || ev.data.type !== "discord-linked") return;
      cleanup();
      refreshSession().finally(() => setAuthing(null));
    };
    const poll = setInterval(() => {
      if (!popup.closed) return;
      cleanup();
      // Pull fresh session in case the flow completed before the popup closed.
      refreshSession().finally(() => setAuthing(null));
    }, 400);
    const cleanup = () => {
      window.removeEventListener("message", onMessage);
      clearInterval(poll);
    };
    window.addEventListener("message", onMessage);
  };

  return (
    <div className="modal-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal">
        <div className="modal-head">
          <h3>{cfxLinked ? "Account linked" : "Sign in to Lint Error"}</h3>
          <p>
            {cfxLinked
              ? "CFX.re is connected. You can optionally link Discord for faster support."
              : "Tebex requires a CFX.re account to issue your script. Discord can be linked after."}
          </p>
        </div>
        <div className="modal-body">
          {/* STEP 1 — CFX */}
          <button
            className="oauth-btn"
            data-brand="cfx"
            onClick={cfxLinked ? undefined : startCfx}
            disabled={cfxLinked || !!authing}
            style={cfxLinked ? { opacity: 0.7 } : null}
          >
            <span className="ic"><Icon.CfxMark size={18} /></span>
            <span className="grow">
              {cfxLinked ? `CFX.re · ${user.name}` : authing === "cfx" ? "Opening CFX.re…" : "Continue with CFX.re"}
              <span style={{ display: "block", fontSize: 11, color: "var(--fg-3)", fontFamily: "var(--font-mono)", marginTop: 2 }}>
                {cfxLinked ? "linked" : authing === "cfx" ? "redirecting…" : "required · step 1 of 2"}
              </span>
            </span>
            <span className="arrow">
              {cfxLinked ? <Icon.Check size={14} /> : <Icon.Arrow size={14} />}
            </span>
          </button>

          {/* STEP 2 — Discord (gated behind CFX) */}
          <button
            className="oauth-btn"
            data-brand="discord"
            onClick={cfxLinked && !discordLinked ? linkDiscord : undefined}
            disabled={!cfxLinked || discordLinked || !!authing}
            style={!cfxLinked ? { opacity: 0.45, cursor: "not-allowed" } : null}
            title={!cfxLinked ? "Sign in with CFX.re first" : ""}
          >
            <span className="ic"><Icon.Discord size={18} /></span>
            <span className="grow">
              {discordLinked ? `Discord · ${user.discord.name}` : authing === "discord" ? "Opening Discord…" : "Link Discord"}
              <span style={{ display: "block", fontSize: 11, color: "var(--fg-3)", fontFamily: "var(--font-mono)", marginTop: 2 }}>
                {discordLinked ? "linked" : authing === "discord" ? "redirecting…" : cfxLinked ? "optional · step 2 of 2" : "locked · link CFX first"}
              </span>
            </span>
            <span className="arrow">
              {discordLinked ? <Icon.Check size={14} /> : !cfxLinked ? <Icon.Lock size={12} /> : <Icon.Arrow size={14} />}
            </span>
          </button>

          {cfxLinked && !discordLinked ? (
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--fg-3)", letterSpacing: "0.04em", textAlign: "center", marginTop: -4, lineHeight: 1.5 }}>
              // linking will add you to our Discord server
            </div>
          ) : null}

          {cfxLinked ? (
            <button className="btn btn-primary btn-block btn-lg" onClick={onClose} style={{ marginTop: 4 }}>
              Done
            </button>
          ) : (
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)", textAlign: "center", marginTop: 8, lineHeight: 1.5 }}>
              // script is tied to CFX account
            </div>
          )}
        </div>
        <div className="modal-foot">
          By continuing you agree to our{" "}
          <a
            href="/terms"
            onClick={(e) => {
              e.preventDefault();
              onClose();
              document.dispatchEvent(new CustomEvent("le:navigate", { detail: { route: "terms" } }));
            }}
            style={{ color: "var(--fg-1)", textDecoration: "underline" }}
          >
            Terms
          </a>.
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { LoginModal });
