// Tebex Headless checkout — no custom payment form; we redirect to Tebex-hosted
// payment after confirming the CFX identity is attached to the basket.
const CheckoutPage = ({ navigate }) => {
  const { cart, cartTotal, clearCart, clearBasket, user, refreshSession, ensureBasket, basketIdent, setBasketIdent, fmt } = useContext(StoreCtx);
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState("");

  // Any cart product that has requiresDiscord set forces a Discord link
  // before the buyer can hit Tebex's checkout. Tebex's webstore expects a
  // valid discord_id option on baskets containing those packages, and we
  // only get one from the buyer going through Discord OAuth on our side.
  const cartProductsList = cart.map((line) => PRODUCTS.find((p) => p.id === line.id)).filter(Boolean);
  const cartNeedsDiscord = cartProductsList.some((p) => p.requiresDiscord);
  const discordLinked = !!(user && user.discord && user.discord.id);
  const discordBlocking = cartNeedsDiscord && !discordLinked;

  // Capture URL markers ONCE on mount. The SPA's navigate() never touches
  // the URL, so re-reading window.location.search every render would re-fire
  // these branches on every subsequent /checkout visit.
  const [justCompleted] = useState(() => new URLSearchParams(window.location.search).get("checkout") === "success");
  const [justCanceled] = useState(() => new URLSearchParams(window.location.search).get("checkout") === "cancel");
  const [authFailed] = useState(() => new URLSearchParams(window.location.search).get("auth") === "failed");

  useEffect(() => {
    if (!justCompleted && !justCanceled && !authFailed) return;
    if (justCompleted) {
      clearCart();
      clearBasket();
    }
    if (justCanceled) {
      setErr("Checkout canceled — your cart's still here whenever you're ready.");
      localStorage.removeItem("le_continue_checkout");
    }
    if (authFailed) {
      setErr("CFX sign-in didn't complete. Try again.");
      localStorage.removeItem("le_continue_checkout");
    }
    // Scrub one-shot markers so subsequent visits are clean.
    const url = new URL(window.location.href);
    url.searchParams.delete("checkout");
    url.searchParams.delete("auth");
    window.history.replaceState({}, "", url.pathname + (url.search ? url.search : "") + url.hash);
  }, []);

  if (justCompleted) {
    return (
      <div className="route-enter container">
        <div style={{ padding: "80px 0", maxWidth: 600, margin: "0 auto", textAlign: "center" }}>
          <div style={{ width: 56, height: 56, borderRadius: "50%", background: "var(--accent)", color: "var(--accent-ink)", display: "inline-grid", placeItems: "center", margin: "0 auto 24px" }}>
            <Icon.Check size={24} stroke={2.5} />
          </div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--fg-3)", textTransform: "uppercase", letterSpacing: "0.08em" }}>
            order_complete
          </div>
          <h1 style={{ fontSize: 32, fontWeight: 600, letterSpacing: "-0.02em", margin: "8px 0 14px" }}>
            Thanks — your script is ready.
          </h1>
          <p style={{ color: "var(--fg-2)", fontSize: 15, margin: "0 0 28px" }}>
            Your script has been issued against your CFX.re account. Install from your CFX Portal at any time.
          </p>
          <div style={{ display: "flex", gap: 10, justifyContent: "center" }}>
            <button className="btn btn-primary btn-lg" onClick={() => navigate("home")}>Back to store</button>
            <a className="btn btn-lg" href="https://portal.cfx.re" target="_blank" rel="noreferrer">Open CFX Portal <Icon.Arrow size={14} /></a>
          </div>
        </div>
      </div>
    );
  }

  if (cart.length === 0) {
    return (
      <div className="route-enter container">
        <div style={{ padding: "80px 0", textAlign: "center" }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--fg-3)", textTransform: "uppercase", letterSpacing: "0.08em" }}>/ checkout</div>
          <h1 style={{ fontSize: 32, fontWeight: 600, letterSpacing: "-0.02em", margin: "8px 0 14px" }}>Your cart is empty.</h1>
          <p style={{ color: "var(--fg-2)", fontSize: 15, margin: "0 0 24px" }}>Pick up a script before heading to checkout.</p>
          <button className="btn btn-primary btn-lg" onClick={() => navigate("scripts")}>Browse scripts</button>
        </div>
      </div>
    );
  }

  const handleCheckout = async () => {
    setErr("");
    if (!user) { setErr("Please sign in with CFX.re first — your script is tied to your CFX account."); return; }
    if (user.via !== "CFX.re") { setErr("CFX.re login is required by Tebex to issue your script."); return; }
    setLoading(true);
    try {
      // (1) Re-verify the session against the server. React state can be
      //     stale (bfcache restore, cookie expired since last mount, or
      //     someone switched accounts in another tab). Checkouts must be
      //     authorized against the session that actually exists right now.
      const sess = await refreshSession();
      if (!sess || sess.via !== "CFX.re") {
        setErr("Your CFX session expired. Please sign in again.");
        setLoading(false);
        document.dispatchEvent(new CustomEvent("le:open-login"));
        return;
      }

      // (2) Fetch or create the basket.
      let basket = null;
      if (basketIdent) {
        basket = await tebexGetBasket(basketIdent);
        if (basket?.complete) { clearBasket(); basket = null; }
      }
      if (!basket) {
        basket = await tebexCreateBasket();
        setBasketIdent(basket.ident);
      }

      // (3) CRITICAL — refuse to check out a basket bound to a DIFFERENT
      //     CFX account than the one currently signed in. Without this,
      //     a shared-device / session-switch scenario could issue the
      //     license to the prior user's CFX while charging the new user's
      //     card. If we detect a mismatch, ditch the stale basket and make
      //     a fresh one (which will then fall into the re-bind branch).
      const boundId = basket.username_id != null ? String(basket.username_id) : null;
      if (basket.username && boundId && boundId !== String(sess.cfxId)) {
        console.warn("Basket identity mismatch, resetting",
          { basket: boundId, session: String(sess.cfxId) });
        clearBasket();
        basket = await tebexCreateBasket();
        setBasketIdent(basket.ident);
      }

      // (4) Basket needs CFX identity → bounce through Tebex's FiveM auth
      //     flow, set a one-shot flag, auto-resume on return.
      if (!basket.username) {
        localStorage.setItem("le_continue_checkout", "1");
        window.location.href = tebexAuthUrl(basket.ident, "cfx");
        return;
      }

      // (5) Some packages require a linked Discord account (Tebex sets a
      //     "discord_id" option on them). If the cart has any such product
      //     and the buyer hasn't linked Discord, surface a clear error and
      //     pop the login modal instead of letting Tebex throw a 400.
      const cartProducts = cart.map((line) => PRODUCTS.find((p) => p.id === line.id)).filter(Boolean);
      const needsDiscord = cartProducts.some((p) => p.requiresDiscord);
      if (needsDiscord && !sess.discord?.id) {
        setErr("This product requires a linked Discord account. Click 'Link Discord' to continue.");
        setLoading(false);
        document.dispatchEvent(new CustomEvent("le:open-login"));
        return;
      }

      // (6) Sync: only POST the packages the Tebex basket doesn't already have.
      //     Pass discord_id as a variable when we have one — Tebex needs it
      //     for any package with a "discord_id" option configured.
      const existing = new Set((basket.packages || []).map((p) => p.id));
      const wanted = cartProducts.map((p) => p.tebexPackageId).filter(Boolean);
      const missing = wanted.filter((pid) => !existing.has(pid));
      const variables = sess.discord?.id ? { discord_id: sess.discord.id } : null;
      for (const pid of missing) {
        await tebexAddPackage(basket.ident, pid, 1, variables);
      }
      // After adding items, Tebex updates `links.checkout`. Re-fetch only if
      // we actually changed something.
      if (missing.length > 0) {
        basket = await tebexGetBasket(basket.ident);
      }

      if (!basket?.links?.checkout) throw new Error("No checkout link from Tebex");
      window.location.href = basket.links.checkout;
    } catch (e) {
      setErr("Could not start checkout: " + (e?.message || "unknown error"));
      setLoading(false);
    }
  };

  // Auto-resume checkout after a mid-flow CFX re-auth (see handleCheckout).
  // Runs whenever we have a signed-in user + non-empty cart — on page load
  // after the CFX redirect round-trip, both are true and the flag is set.
  useEffect(() => {
    if (authFailed) return;
    if (!user || user.via !== "CFX.re") return;
    if (!cart.length) return;
    if (localStorage.getItem("le_continue_checkout") !== "1") return;
    localStorage.removeItem("le_continue_checkout");
    handleCheckout();
  }, [user, cart.length]);

  return (
    <div className="route-enter container">
      <div className="pd-breadcrumbs" style={{ paddingTop: 32 }}>
        <a href="/" onClick={(e) => { e.preventDefault(); navigate("home"); }} style={{ cursor: "pointer" }}>Home</a> / checkout
      </div>
      <h1 style={{ fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em", margin: "8px 0 4px" }}>Checkout</h1>
      <p style={{ color: "var(--fg-2)", fontSize: 14, margin: "0 0 24px" }}>
        <Icon.Lock size={12} /> Payment handled by Tebex · script issued to your CFX.re account
      </p>

      <div className="checkout-layout">
        <div>
          <div className={`checkout-step ${user ? "done" : "active"}`}>
            <div className="step-head">
              <h3><span className="num">1</span> CFX.re account</h3>
              {user ? <span className="tag tag-accent"><Icon.Check size={10} /> signed in</span> : null}
            </div>
            {user ? (
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, color: "var(--fg-2)" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <Icon.CfxMark size={14} /> <span>{user.name}</span>
                  <Icon.Check size={12} style={{ color: "var(--accent)" }} />
                  <span style={{ color: "var(--fg-3)", marginLeft: 4 }}>· via {user.via}</span>
                </div>
                {user.discord ? (
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 8 }}>
                    <Icon.Discord size={14} /> <span>{user.discord.name}</span>
                    <Icon.Check size={12} style={{ color: "var(--accent)" }} />
                    <span style={{ color: "var(--fg-3)", marginLeft: 4 }}>· linked</span>
                  </div>
                ) : user.via === "CFX.re" ? (
                  <div style={{ marginTop: 12, padding: "10px 12px", border: "1px dashed var(--line)", borderRadius: "var(--r)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
                    <div>
                      <div style={{ color: "var(--fg-1)", fontSize: 12.5 }}>Link Discord for faster support</div>
                      <div style={{ color: "var(--fg-3)", fontSize: 11, marginTop: 2 }}>optional · we'll DM you your script details</div>
                    </div>
                    <button className="btn btn-sm" onClick={() => document.dispatchEvent(new CustomEvent("le:open-login"))}>
                      <Icon.Discord size={13} /> Link
                    </button>
                  </div>
                ) : null}
                {user.via !== "CFX.re" ? (
                  <div style={{ color: "var(--err)", marginTop: 8 }}>⚠ Tebex requires CFX.re specifically. Sign out and use CFX.</div>
                ) : null}
              </div>
            ) : (
              <>
                <p style={{ color: "var(--fg-2)", fontSize: 13.5, margin: "0 0 14px" }}>
                  Tebex ties your script to your CFX.re account. Sign in to continue.
                </p>
                <button className="btn btn-primary" onClick={() => document.dispatchEvent(new CustomEvent("le:open-login"))}>
                  Sign in with CFX.re <Icon.Arrow size={14} />
                </button>
              </>
            )}
          </div>

          <div className={`checkout-step ${user && user.via === "CFX.re" ? "active" : ""}`}>
            <div className="step-head">
              <h3><span className="num">2</span> Payment</h3>
              <span className="tag tag-muted"><Icon.Lock size={10} /> TEBEX</span>
            </div>
            <p style={{ color: "var(--fg-2)", fontSize: 13.5, margin: "0 0 14px" }}>
              You'll be redirected to Tebex's secure checkout to complete payment. After payment you'll return here and your script will be ready in CFX Portal.
            </p>
            {err ? <div style={{ color: "var(--err)", fontFamily: "var(--font-mono)", fontSize: 12.5, marginBottom: 12 }}>{err}</div> : null}
            {discordBlocking ? (
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                  gap: 12,
                  padding: "10px 12px",
                  marginBottom: 12,
                  border: "1px dashed var(--line)",
                  borderRadius: "var(--r)",
                  background: "rgba(155,58,127,0.05)",
                  fontFamily: "var(--font-mono)",
                  fontSize: 12,
                  color: "var(--fg-2)",
                }}
              >
                <span>// Discord link required for this purchase.</span>
                <button
                  className="btn btn-sm"
                  onClick={() => document.dispatchEvent(new CustomEvent("le:open-login"))}
                >
                  <Icon.Discord size={13} /> Link Discord
                </button>
              </div>
            ) : null}
            <button
              className="btn btn-primary btn-lg btn-block"
              onClick={handleCheckout}
              disabled={loading || !user || user.via !== "CFX.re" || discordBlocking}
              title={discordBlocking ? "Link Discord first" : ""}
            >
              {loading
                ? "Opening Tebex…"
                : discordBlocking
                ? <><Icon.Lock size={13} /> Link Discord to continue</>
                : <>Continue to Tebex · {fmt(cartTotal)} <Icon.Arrow size={14} /></>}
            </button>
            {user && user.via === "CFX.re" && !discordBlocking ? (
              <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)", marginTop: 10, lineHeight: 1.5 }}>
                // you're signed in — continuing may include a quick one-time CFX confirmation to bind this order's license to your account.
              </div>
            ) : null}
          </div>
        </div>

        <div>
          <div className="summary">
            <h4>// order_summary</h4>
            {cart.map((line) => {
              const p = PRODUCTS.find((x) => x.id === line.id);
              if (!p) return null;
              return (
                <div className="summary-row" key={line.id}>
                  <span className="k">{p.name}</span>
                  <span className="v">{fmt(p.price)}</span>
                </div>
              );
            })}
            <div className="summary-row total"><span className="k">Total</span><span className="v">{fmt(cartTotal)}</span></div>

            <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--fg-3)", textTransform: "uppercase", letterSpacing: "0.06em", marginTop: 14, display: "flex", alignItems: "center", gap: 6 }}>
              <Icon.Shield size={11} /> Payments secured by Tebex
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { CheckoutPage });
