// screens-setup.jsx — API setup + Extension install + Subscription

// ── API SETUP ─────────────────────────────────────────────────
const COM_CURRENCIES = ["USDT", "BTC", "ETH", "LTC", "SOL", "DOGE", "TRX", "XRP", "BNB"];
const COM_REGIONS = [
  { value: "norway", label: "Norway · no.decodo.com (recommended)" },
  { value: "malta",  label: "Malta · mt.decodo.com" },
  { value: "japan",  label: "Japan · jp.decodo.com" },
];

const ApiSetup = ({ goto, path, setApiState, apiState }) => {
  // Step 0 = platform picker, Step 1 = key entry
  const [step, setStep]           = React.useState(0);
  const [platforms, setPlatforms] = React.useState(apiState?.platforms || "both");

  const [comKey, setComKey]       = React.useState(apiState?.comKey || "");
  const [comClaims, setComClaims] = React.useState(apiState?.comClaims || [{ id: 1, currency: "USDT" }]);
  const [comRegion, setComRegion] = React.useState(apiState?.comRegion || "norway");
  const [usKey, setUsKey]         = React.useState(apiState?.usKey || "");
  // Stake.us is forced to sweeps + Texas
  const usCurrency = "Sweeps";
  const usRegion   = "texas";

  const [testing, setTesting]     = React.useState(false);
  const [log, setLog]             = React.useState([]);
  const [done, setDone]           = React.useState(false);
  const [saving, setSaving]       = React.useState(false);
  const [saveError, setSaveError] = React.useState("");

  const addComClaim = () => {
    if (comClaims.length >= 6) return;
    const used = new Set(comClaims.map(c => c.currency));
    const next = COM_CURRENCIES.find(c => !used.has(c)) || COM_CURRENCIES[0];
    setComClaims([...comClaims, { id: Date.now(), currency: next }]);
  };
  const removeComClaim = (id) => setComClaims(comClaims.filter(c => c.id !== id));
  const updateComClaim = (id, currency) => setComClaims(comClaims.map(c => c.id === id ? { ...c, currency } : c));

  const runTest = async () => {
    setTesting(true);
    setLog([]);
    setDone(false);
    const token = localStorage.getItem("cc_token");
    if (!token) { setTesting(false); return; }
    const platform = wantUs ? "stake_us" : "stake_com";
    const apiKey   = wantUs ? usKey : comKey;
    try {
      const r = await fetch("/api/keys/test", {
        method: "POST",
        headers: { "content-type": "application/json", "Authorization": `Bearer ${token}` },
        body: JSON.stringify({ platform, api_key: apiKey }),
      });
      const d = await r.json();
      const lines = d.log || [];
      let t = 0;
      lines.forEach((l, i) => {
        t += 300;
        setTimeout(() => {
          setLog((prev) => [...prev, { text: l.text, ok: l.ok }]);
          if (i === lines.length - 1) { setDone(!!d.success); setTesting(false); }
        }, t);
      });
      if (!lines.length) { setDone(false); setTesting(false); }
    } catch {
      setLog([{ text: "Network error — could not reach server", ok: "err" }]);
      setTesting(false);
    }
  };

  const wantCom = platforms === "com" || platforms === "both";
  const wantUs  = platforms === "us"  || platforms === "both";
  const canProceed = (wantCom ? comKey.trim().length > 0 : true) &&
                     (wantUs  ? usKey.trim().length  > 0 : true) &&
                     (wantCom || wantUs);

  const proceed = async () => {
    setSaveError("");
    const token = localStorage.getItem("cc_token");
    if (!token) { goto("signup"); return; }

    const comEntries = wantCom && comKey
      ? comClaims.map(c => ({ api_key: comKey, currency: c.currency.toLowerCase() }))
      : [];
    const usEntries = wantUs && usKey ? [{ api_key: usKey, currency: "sweeps" }] : [];

    setSaving(true);
    try {
      // Save keys
      const r = await fetch("/api/keys", {
        method: "POST",
        headers: { "content-type": "application/json", "Authorization": `Bearer ${token}` },
        body: JSON.stringify({ stake_com: comEntries, stake_us: usEntries }),
      });
      const d = await r.json();
      if (d.error) { setSaveError(d.error); setSaving(false); return; }

      // Save proxy region preference
      if (wantCom) {
        await fetch("/api/me/proxy-region", {
          method: "POST",
          headers: { "content-type": "application/json", "Authorization": `Bearer ${token}` },
          body: JSON.stringify({ com_region: comRegion }),
        }).catch(() => {});
      }

      setApiState({ platforms, comKey, comClaims, comRegion, usKey, usCurrency, usRegion, tested: done });
      goto("dashboard");
    } catch {
      setSaveError("Network error — try again");
      setSaving(false);
    }
  };

  const comCurrencyOptions = (currentId) => {
    const taken = new Set(comClaims.filter(c => c.id !== currentId).map(c => c.currency));
    return COM_CURRENCIES.map(c => ({ value: c, label: taken.has(c) ? `${c} · already added` : c, disabled: taken.has(c) }));
  };

  return (
    <div className="container fade-in" style={{ maxWidth: 980, padding: "44px 28px" }}>
      <div className="row" style={{ gap: 12, marginBottom: 24 }}>
        <Steps items={["Account", "Path", "Plan", "Setup"]} current={3} />
        <span className="muted" style={{ marginLeft: "auto", fontSize: 12 }}>
          {path === "hybrid" ? "API · then extension" : "API setup"}
        </span>
      </div>

      <span className="eyebrow">step 3a · cloud setup</span>
      <h2 style={{ fontSize: 36, marginTop: 8, marginBottom: 6 }}>
        Paste your Stake API keys
      </h2>
      <p className="muted" style={{ marginBottom: 22 }}>
        On Stake → <span className="mono" style={{ color: "var(--text)" }}>Settings → API</span> → Generate key.
        We encrypt keys at rest with Fernet.
      </p>

      <div className="grid-2" style={{ gap: 20 }}>
        <div className="stack">
          {/* ── Stake.com card ── */}
          <Card>
            <div className="row between" style={{ marginBottom: 10 }}>
              <span className="row" style={{ gap: 8 }}>
                <Platform name="stake_com" />
                <Pill>optional</Pill>
              </span>
              <span className="muted mono" style={{ fontSize: 11 }}>{comClaims.length} currencies</span>
            </div>
            <Field label="API key">
              <Input placeholder="sk_live_…" value={comKey} onChange={(e) => setComKey(e.target.value)} />
            </Field>
            <Field label="Proxy region · Stake.com">
              <Select value={comRegion} onChange={(e) => setComRegion(e.target.value)} options={COM_REGIONS} />
            </Field>

            <div className="row between" style={{ marginTop: 8, marginBottom: 6 }}>
              <span className="field-label" style={{ marginBottom: 0 }}>Currencies to claim with</span>
              <span className="muted" style={{ fontSize: 11 }}>one Turnstile token per currency · per code</span>
            </div>
            <div className="stack-sm">
              {comClaims.map((c, idx) => (
                <div key={c.id} className="row" style={{ gap: 8 }}>
                  <span className="muted mono" style={{ fontSize: 11, width: 22 }}>#{idx + 1}</span>
                  <Select
                    value={c.currency}
                    onChange={(e) => updateComClaim(c.id, e.target.value)}
                    options={comCurrencyOptions(c.id)}
                  />
                  {comClaims.length > 1
                    ? <Btn sm kind="ghost" onClick={() => removeComClaim(c.id)} aria-label="Remove"><Icon name="x" /></Btn>
                    : <span style={{ width: 30 }}></span>}
                </div>
              ))}
              <Btn
                sm
                kind="ghost"
                onClick={addComClaim}
                disabled={!comKey || comClaims.length >= COM_CURRENCIES.length}>
                + Add another .com claim
              </Btn>
            </div>
            {comClaims.length > 1 && (
              <p className="muted" style={{ fontSize: 11, marginTop: 8 }}>
                Each currency fires a separate claim from a fresh Turnstile token. More currencies = more claims per code.
              </p>
            )}
          </Card>

          {/* ── Stake.us card ── */}
          <Card accent={!!usKey}>
            <div className="row between" style={{ marginBottom: 10 }}>
              <span className="row" style={{ gap: 8 }}>
                <Platform name="stake_us" />
                {usKey ? <Pill kind="ok" dot>format ok</Pill> : <Pill kind="warn">needed</Pill>}
              </span>
              <Pill>sweeps only</Pill>
            </div>
            <Field label="API key">
              <Input placeholder="sk_live_…" value={usKey} onChange={(e) => setUsKey(e.target.value)} />
            </Field>
            <div className="grid-2" style={{ gap: 12 }}>
              <Field label="Currency" hint="Stake.us is sweeps-only">
                <Input value={usCurrency} disabled readOnly style={{ opacity: .8 }} />
              </Field>
              <Field label="Proxy region · Stake.us" hint="locked · Stake.us geo-fences to Texas">
                <Input value="US · Texas (Decodo residential)" disabled readOnly style={{ opacity: .8, fontSize: 11 }} />
              </Field>
            </div>
          </Card>
        </div>

        <div className="stack">
          <Card glow={done} style={{ minHeight: 320, padding: 0, overflow: "hidden" }}>
            <div className="row between" style={{ padding: 14, borderBottom: "1px solid var(--border)" }}>
              <span className="row" style={{ gap: 8 }}>
                <span className={done ? "glow-ring" : ""} style={!done ? { width: 8, height: 8, borderRadius: 999, background: "var(--text-3)" } : {}}></span>
                <strong style={{ fontSize: 13 }}>Test claim</strong>
              </span>
              <Pill kind={done ? "ok" : testing ? "warn" : ""} dot={done || testing}>
                {done ? "verified · 218ms" : testing ? "running…" : "ready"}
              </Pill>
            </div>
            <div style={{ padding: 14, fontFamily: "var(--font-mono)", fontSize: 12, lineHeight: 1.8, minHeight: 220 }}>
              {log.length === 0 && (
                <span className="muted">Click "Fire test claim" to verify your keys, proxy, and Turnstile pool with a synthetic code.</span>
              )}
              {log.map((l, i) => (
                <div key={i} className="fade-in">
                  <span className="muted" style={{ marginRight: 8 }}>{`[${String(i+1).padStart(2,"0")}]`}</span>
                  <span className={l.ok === "ok" || l.ok === "done" ? "ok" : ""} style={{
                    color: l.ok === "ok" || l.ok === "done" ? "var(--ok)" :
                           l.ok === "pending" ? "var(--text-2)" : "var(--text)"
                  }}>{l.text}</span>
                </div>
              ))}
              {done && (
                <div className="scale-in" style={{ marginTop: 10, padding: 10, border: "1px solid var(--ok)", borderRadius: 6, color: "var(--ok)" }}>
                  ✓ Pipeline working. You're good to go.
                </div>
              )}
            </div>
          </Card>
          <Btn kind={done ? "ghost" : "primary"} block lg disabled={testing || !usKey} onClick={runTest}>
            {testing ? <><span className="spin" style={{ display: "inline-block" }}>◐</span> Testing…</> : done ? <>Re-run <Icon name="refresh" /></> : <>Fire test claim <Icon name="bolt" /></>}
          </Btn>
        </div>
      </div>

      {saveError && (
        <p style={{ color: "var(--red, #f55)", fontSize: 13, marginTop: 12 }}>{saveError}</p>
      )}
      <div className="row between" style={{ marginTop: 28 }}>
        <Btn onClick={() => goto("subscription")}><Icon name="left" /> Back</Btn>
        <Btn kind="primary" lg onClick={proceed} disabled={!canProceed || saving}>
          {saving
            ? <><span className="spin" style={{ display: "inline-block" }}>◐</span> Saving…</>
            : path === "hybrid" ? "Next · install extension" : "Continue · pick a plan"}
          {!saving && <Icon name="arrow" />}
        </Btn>
      </div>
    </div>
  );
};

// ── EXTENSION INSTALL ─────────────────────────────────────────
const ExtInstall = ({ goto, path, setExtState, extState }) => {
  const [browser, setBrowser]   = React.useState(extState?.browser || "chrome");
  const [stage, setStage]       = React.useState(extState?.installed ? 3 : 0); // 0 pick, 1 installing, 2 linking, 3 done
  const [progress, setProgress] = React.useState(0);
  const [linked, setLinked]     = React.useState(extState?.linked || { stake_com: false, stake_us: false, shuffle: false, thrill: false });

  React.useEffect(() => {
    if (stage !== 1) return;
    setProgress(0);
    const tick = setInterval(() => {
      setProgress((p) => {
        if (p >= 100) { clearInterval(tick); setStage(2); return 100; }
        return p + 5;
      });
    }, 90);
    return () => clearInterval(tick);
  }, [stage]);

  const allLinked = Object.values(linked).every(Boolean);
  const linkAll = () => {
    const keys = Object.keys(linked);
    keys.forEach((k, i) => setTimeout(() => setLinked((prev) => ({ ...prev, [k]: true })), 400 * (i + 1)));
    setTimeout(() => setStage(3), 400 * keys.length + 400);
  };

  const proceed = () => {
    setExtState({ browser, installed: stage >= 2, linked });
    goto("subscription");
  };

  return (
    <div className="container fade-in" style={{ maxWidth: 1100, padding: "44px 28px" }}>
      <div className="row" style={{ gap: 12, marginBottom: 24 }}>
        <Steps items={["Account", "Path", "Plan", "Setup"]} current={3} />
        <span className="muted" style={{ marginLeft: "auto", fontSize: 12 }}>
          {path === "hybrid" ? "extension · then plan" : "extension setup"}
        </span>
      </div>

      <span className="eyebrow">step 3b · local setup</span>
      <h2 style={{ fontSize: 36, marginTop: 8, marginBottom: 6 }}>
        Install the extension
      </h2>
      <p className="muted" style={{ marginBottom: 22 }}>
        Pick your browser. Pin the icon. Log into Stake / Shuffle / Thrill in a normal tab — we'll link them in one click.
      </p>

      <div className="grid-2" style={{ gap: 22, alignItems: "start" }}>
        <div className="stack-lg">
          {/* Browser picker */}
          <Card>
            <div className="row between" style={{ marginBottom: 12 }}>
              <strong>① Browser</strong>
              <Pill kind={browser ? "ok" : ""} dot={!!browser}>{browser ? `${browser} selected` : "pick one"}</Pill>
            </div>
            <div className="grid-4">
              {[
                { id: "chrome", label: "Chrome" },
                { id: "brave", label: "Brave" },
                { id: "firefox", label: "Firefox" },
                { id: "safari", label: "Safari" },
              ].map(b => (
                <div key={b.id}
                  onClick={() => setBrowser(b.id)}
                  className={"path-card " + (browser === b.id ? "selected" : "")}
                  style={{ padding: 12, textAlign: "center", cursor: "pointer" }}>
                  <Browser name={b.id} size={36} />
                  <div style={{ marginTop: 6, fontSize: 13, fontWeight: 600 }}>{b.label}</div>
                </div>
              ))}
            </div>
          </Card>

          {/* Install */}
          <Card>
            <div className="row between" style={{ marginBottom: 12 }}>
              <strong>② Install &amp; pin</strong>
              <Pill kind={stage >= 2 ? "ok" : ""} dot={stage >= 2}>{stage >= 2 ? "installed" : stage === 1 ? "installing" : "ready"}</Pill>
            </div>
            {stage === 0 && (
              <Btn kind="primary" block lg onClick={() => setStage(1)}>
                <Icon name="external" /> Add Stake Sauce to {browser}
              </Btn>
            )}
            {stage === 1 && (
              <div className="stack-sm">
                <div className="row" style={{ gap: 10 }}>
                  <span className="spin" style={{ display: "inline-block", color: "var(--accent)" }}>◐</span>
                  <span style={{ fontSize: 13 }}>Downloading &amp; verifying signature…</span>
                  <span className="muted mono" style={{ marginLeft: "auto", fontSize: 12 }}>{progress}%</span>
                </div>
                <div style={{ height: 6, background: "var(--surf-3)", borderRadius: 999, overflow: "hidden" }}>
                  <div style={{ height: "100%", width: progress + "%", background: "var(--accent)", transition: "width .15s" }}></div>
                </div>
                <p className="muted" style={{ fontSize: 12, marginTop: 8 }}>
                  Don't see the icon? <span style={{ color: "var(--text)" }}>Browser menu → puzzle → pin Stake Sauce.</span>
                </p>
              </div>
            )}
            {stage >= 2 && (
              <div className="stack-sm">
                <div className="row" style={{ gap: 10 }}>
                  <Icon name="check" style={{ color: "var(--ok)" }} />
                  <span style={{ fontSize: 13 }}>Installed in {browser} · pinned to toolbar</span>
                </div>
                <p className="muted" style={{ fontSize: 12 }}>Auth token already provisioned — your account &amp; the extension are paired.</p>
              </div>
            )}
          </Card>

          {/* Link */}
          <Card>
            <div className="row between" style={{ marginBottom: 12 }}>
              <strong>③ Link platforms</strong>
              <Pill kind={allLinked ? "ok" : ""} dot={allLinked}>{Object.values(linked).filter(Boolean).length} of 4</Pill>
            </div>
            {stage < 2 && <p className="muted" style={{ fontSize: 13 }}>Finish install first.</p>}
            {stage >= 2 && (
              <div className="stack-sm">
                {[
                  { id: "stake_com" },
                  { id: "stake_us" },
                  { id: "shuffle" },
                  { id: "thrill" },
                ].map((p) => (
                  <div key={p.id} className="link-row">
                    <Platform name={p.id} />
                    {linked[p.id]
                      ? <Pill kind="ok" dot>linked · session ok</Pill>
                      : <Btn sm onClick={() => setLinked((prev) => ({ ...prev, [p.id]: true }))}>Link</Btn>}
                  </div>
                ))}
                <Btn kind="primary" block style={{ marginTop: 8 }} onClick={linkAll} disabled={allLinked}>
                  {allLinked ? "All platforms linked ✓" : "Link all (demo)"}
                </Btn>
              </div>
            )}
          </Card>
        </div>

        {/* Right side: live extension popup mock */}
        <div style={{ position: "sticky", top: 24 }}>
          <div style={{ display: "flex", justifyContent: "center", padding: "20px 0" }}>
            <div className="ext-popup scale-in">
              <div className="ext-head">
                <span className="brand-mark" style={{ width: 24, height: 24, fontSize: 12 }}>SS</span>
                <strong style={{ fontSize: 13 }}>Stake Sauce</strong>
                <span className="muted mono" style={{ marginLeft: "auto", fontSize: 11 }}>v1.4.0</span>
              </div>
              <div className="ext-body">
                <div className="row between" style={{ marginBottom: 10 }}>
                  <Pill kind={stage >= 2 ? "ok" : ""} dot={stage >= 2}>{stage >= 2 ? "connected · SSE" : "not yet installed"}</Pill>
                  <span className="muted mono" style={{ fontSize: 11 }}>{stage >= 2 ? "live · 0s" : "—"}</span>
                </div>
                <div className="stack-sm">
                  {[
                    { id: "stake_com" },
                    { id: "stake_us" },
                    { id: "shuffle" },
                    { id: "thrill" },
                  ].map((p) => (
                    <div key={p.id} className="link-row" style={{ padding: "8px 10px" }}>
                      <Platform name={p.id} />
                      {linked[p.id]
                        ? <Pill kind="ok" dot>linked</Pill>
                        : <Pill>—</Pill>}
                    </div>
                  ))}
                </div>
                <div className="divider"></div>
                <p className="muted" style={{ fontSize: 11 }}>
                  Last claim: {allLinked ? "shuf · AB12CD · 1.4s · ✓" : "—"}
                </p>
              </div>
            </div>
          </div>
          <p className="muted" style={{ fontSize: 12, textAlign: "center" }}>
            ↑ this is your browser popup, mirrored.
          </p>
        </div>
      </div>

      <div className="row between" style={{ marginTop: 28 }}>
        <Btn onClick={() => goto(path === "hybrid" ? "api-setup" : "onboarding")}><Icon name="left" /> Back</Btn>
        <Btn kind="primary" lg onClick={proceed} disabled={stage < 2}>
          Continue · pick a plan <Icon name="arrow" />
        </Btn>
      </div>
    </div>
  );
};

// ── SUBSCRIPTION ──────────────────────────────────────────────
const MAX_SLOTS = 4;

const Subscription = ({ goto, path, plan, setPlan }) => {
  const [billing, setBilling]   = React.useState("monthly");
  const [chosen, setChosen]     = React.useState(plan || "house_cut");
  const [slotCount, setSlots]   = React.useState(1);
  const [promoCode, setPromoCode]         = React.useState("");
  const [promoInfo, setPromoInfo]         = React.useState(null);
  const [promoErr, setPromoErr]           = React.useState("");
  const [checking, setChecking]           = React.useState(false);
  const [checkingOut, setCheckingOut]     = React.useState(false);
  const [payError, setPayError]           = React.useState("");

  // Three paid tiers — every plan covers both Stake.com and Stake.us, ships
  // with reloads + daily dollar, and grants the (forthcoming) Shuffle/Thrill
  // extension. What separates them is which code tiers BoostMonitor will route
  // to the user: regular only / + highroller / + Saturday stream.
  const PLANS = [
    {
      id: "house_cut", name: "The House Cut", tag: "Regular codes",
      price: { monthly: 10, yearly: 96 },
      blurb: "Regular bonus drops on both Stake.com and Stake.us — daily dollar and reloads on us.",
      features: [
        "Regular bonus codes (both platforms)",
        "Reloads + Stake.us daily dollar — bundled",
        "Pre-solved captchas, residential proxy",
        "Extension access (Shuffle + Thrill — coming soon)",
      ],
    },
    {
      id: "prime_cut", name: "The Prime Cut", tag: "+ Highroller",
      price: { monthly: 15, yearly: 144 },
      blurb: "Regular + highroller codes, both platforms. The pour-over of bonus claiming.",
      features: [
        "Everything in House Cut",
        "Highroller codes (both platforms)",
        "Same bundled reloads + daily dollar",
        "Telegram alerts on every claim",
      ],
      featured: true,
    },
    {
      id: "grand_feast", name: "The Grand Feast", tag: "Every code",
      price: { monthly: 30, yearly: 288 },
      blurb: "The whole spread — regular, highroller, and Saturday stream codes for both platforms.",
      features: [
        "Everything in Prime Cut",
        "Saturday stream codes (both platforms)",
        "First in line on every drop tier",
        "Priority support",
      ],
    },
  ];

  const chosenPlan = PLANS.find(p => p.id === chosen);
  const basePrice = billing === "monthly"
    ? (chosenPlan?.price.monthly ?? 0)
    : (chosenPlan?.price.yearly ?? 0);

  // Price scales linearly with slot count. 1 slot = 1 API key bound to one
  // platform; buying a 2nd slot lets the user run both Stake.com and Stake.us
  // in parallel under the same tier.
  const total = basePrice * slotCount;

  const checkPromo = async () => {
    if (!promoCode.trim()) return;
    setPromoErr(""); setChecking(true); setPromoInfo(null);
    const token = localStorage.getItem("cc_token");
    try {
      const r = await fetch("/api/promo/check", {
        method: "POST",
        headers: { "content-type": "application/json", "Authorization": `Bearer ${token}` },
        body: JSON.stringify({ code: promoCode.trim() }),
      });
      const d = await r.json();
      if (d.error) { setPromoErr(d.error); } else { setPromoInfo(d); }
    } catch (_) { setPromoErr("Network error"); }
    setChecking(false);
  };

  const checkout = async () => {
    setPayError("");
    const token = localStorage.getItem("cc_token");
    if (!token) { goto("signup"); return; }
    setCheckingOut(true);
    try {
      const r = await fetch("/api/payments/create", {
        method: "POST",
        headers: { "content-type": "application/json", "Authorization": `Bearer ${token}` },
        body: JSON.stringify({
          plan: chosen,
          addons: { reload: addonReload, extra_seat: addonSeat },
          promo_code: promoCode.trim() || undefined,
        }),
      });
      const d = await r.json();
      if (d.error) { setPayError(d.error); setCheckingOut(false); return; }
      if (d.dev_mode || !d.invoice_url) {
        setPlan(chosen);
        goto("api-setup");
      } else {
        window.location.href = d.invoice_url;
      }
    } catch {
      setPayError("Network error — try again");
      setCheckingOut(false);
    }
  };

  const pill = (label) => (
    <span style={{
      fontSize: 10, fontFamily: "var(--font-display)", letterSpacing: ".08em",
      textTransform: "uppercase", fontWeight: 700,
      padding: "2px 7px", borderRadius: 3,
      background: "var(--accent)", color: "#07090c",
    }}>{label}</span>
  );

  return (
    <div className="container fade-in" style={{ maxWidth: 1100, padding: "44px 28px" }}>
      <div className="row" style={{ gap: 12, marginBottom: 24 }}>
        <Steps items={["Account", "Path", "Plan", "Setup"]} current={2} />
        <span className="muted" style={{ marginLeft: "auto", fontSize: 12 }}>cancel anytime</span>
      </div>
      <span className="eyebrow">step 3 · pick your cut</span>
      <h2 style={{ fontSize: 36, marginTop: 8, marginBottom: 6 }}>What'll it be?</h2>
      <p className="muted" style={{ marginBottom: 20 }}>Choose your platform. Add extras below. Yearly saves ~20%.</p>

      {/* Billing toggle */}
      <div className="row" style={{ gap: 8, marginBottom: 24 }}>
        <div style={{ display: "inline-flex", border: "1px solid var(--border-2)", borderRadius: 999, padding: 3, background: "var(--surf-2)" }}>
          {["monthly", "yearly"].map(b => (
            <button key={b} onClick={() => setBilling(b)} style={{
              border: 0, padding: "6px 14px", borderRadius: 999, cursor: "pointer",
              background: billing === b ? "var(--accent)" : "transparent",
              color: billing === b ? "#07090c" : "var(--text-2)",
              fontFamily: "var(--font-display)", fontSize: 12, letterSpacing: ".06em", textTransform: "uppercase", fontWeight: 600,
            }}>{b}{b === "yearly" && " · −20%"}</button>
          ))}
        </div>
      </div>

      {/* Plan cards */}
      <div className="grid-4" style={{ gap: 14, marginBottom: 28 }}>
        {PLANS.map(p => (
          <div key={p.id}
            className={"path-card " + (chosen === p.id ? "selected " : "") + (p.featured ? "featured" : "")}
            onClick={() => setChosen(p.id)}
            style={{ minHeight: 300, position: "relative", cursor: "pointer" }}>
            {p.featured && <span className="ribbon">best value</span>}
            <div className="row" style={{ gap: 8, alignItems: "center", marginBottom: 4 }}>
              <strong style={{ fontSize: 16 }}>{p.name}</strong>
              {pill(p.tag)}
            </div>
            <p className="muted" style={{ fontSize: 12, marginTop: 2, minHeight: 32 }}>{p.blurb}</p>
            <div style={{ display: "flex", alignItems: "baseline", gap: 3, marginTop: 10 }}>
              <span style={{ fontFamily: "var(--font-num)", fontSize: 38, fontWeight: 700, color: "var(--text)", letterSpacing: "-.02em" }}>
                ${billing === "monthly" ? p.price.monthly : p.price.yearly}
              </span>
              <span className="muted" style={{ fontSize: 12 }}>/{billing === "monthly" ? "mo" : "yr"}</span>
            </div>
            <div className="divider" style={{ margin: "10px 0" }} />
            <ul style={{ listStyle: "none", padding: 0, margin: 0 }}>
              {p.features.map((f, i) => (
                <li key={i} className="row" style={{ gap: 7, fontSize: 12, padding: "3px 0" }}>
                  <Icon name="check" style={{ color: "var(--accent)", flexShrink: 0 }} />
                  <span>{f}</span>
                </li>
              ))}
            </ul>
            <div className="row" style={{ marginTop: 12, gap: 7 }}>
              <span style={{
                width: 16, height: 16, borderRadius: 999, flexShrink: 0,
                border: "2px solid var(--border-2)", display: "grid", placeItems: "center",
                background: chosen === p.id ? "var(--accent)" : "transparent",
              }}>
                {chosen === p.id && <Icon name="check" size={10} style={{ color: "#07090c" }} />}
              </span>
              <span className="muted" style={{ fontSize: 12 }}>{chosen === p.id ? "selected" : "tap to select"}</span>
            </div>
          </div>
        ))}
      </div>

      {/* Add-ons */}
      <div style={{ marginBottom: 28 }}>
        <div className="row" style={{ gap: 8, marginBottom: 12, alignItems: "center" }}>
          <span className="eyebrow" style={{ margin: 0 }}>secret seasonings</span>
          {!hasApi && <span className="muted" style={{ fontSize: 12 }}>— requires a Stake.com or Stake.us plan</span>}
        </div>
        <div style={{ display: "flex", gap: 14, flexWrap: "wrap" }}>
          {ADDONS.map(a => {
            const active = addonStates[a.id];
            const disabled = a.requiresApi && !hasApi;
            return (
              <div key={a.id}
                onClick={() => !disabled && addonSetters[a.id](!active)}
                style={{
                  border: `2px solid ${active ? "var(--accent)" : "var(--border-2)"}`,
                  borderRadius: "var(--radius-sm)",
                  padding: "14px 18px",
                  minWidth: 200, flex: 1, maxWidth: 320,
                  cursor: disabled ? "not-allowed" : "pointer",
                  opacity: disabled ? 0.4 : 1,
                  background: active ? "rgba(0,230,77,.07)" : "var(--surf)",
                  transition: "border-color .15s, background .15s",
                }}>
                <div className="row" style={{ gap: 10, alignItems: "center", marginBottom: 6 }}>
                  <span style={{ fontSize: 20 }}>{a.icon}</span>
                  <strong style={{ fontSize: 14 }}>{a.name}</strong>
                  <span style={{ marginLeft: "auto", fontFamily: "var(--font-num)", fontSize: 15, fontWeight: 700 }}>
                    +${billing === "monthly" ? a.price.monthly : a.price.yearly}
                    <span className="muted" style={{ fontSize: 11, fontWeight: 400 }}>/{billing === "monthly" ? "mo" : "yr"}</span>
                  </span>
                </div>
                <p className="muted" style={{ fontSize: 12, margin: 0 }}>{a.blurb}</p>
                <div className="row" style={{ marginTop: 10, gap: 7 }}>
                  <span style={{
                    width: 16, height: 16, borderRadius: 3, flexShrink: 0,
                    border: `2px solid ${active ? "var(--accent)" : "var(--border-2)"}`,
                    display: "grid", placeItems: "center",
                    background: active ? "var(--accent)" : "transparent",
                  }}>
                    {active && <Icon name="check" size={10} style={{ color: "#07090c" }} />}
                  </span>
                  <span className="muted" style={{ fontSize: 12 }}>{active ? "added" : "tap to add"}</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Order summary */}
      <div style={{
        border: "1px solid var(--border-2)", borderRadius: "var(--radius-sm)",
        padding: "16px 20px", marginBottom: 20, background: "var(--surf-2)", maxWidth: 420,
      }}>
        <div className="row between" style={{ fontSize: 13, marginBottom: 6 }}>
          <span className="muted">{chosenPlan?.name}</span>
          <span>${basePrice}/{billing === "monthly" ? "mo" : "yr"}</span>
        </div>
        {addonReload && (
          <div className="row between" style={{ fontSize: 13, marginBottom: 6 }}>
            <span className="muted">+ Reload Claimer</span>
            <span>+${ADDONS[0].price[billing]}/{billing === "monthly" ? "mo" : "yr"}</span>
          </div>
        )}
        {addonSeat && (
          <div className="row between" style={{ fontSize: 13, marginBottom: 6 }}>
            <span className="muted">+ Extra API Slot</span>
            <span>+${ADDONS[1].price[billing]}/{billing === "monthly" ? "mo" : "yr"}</span>
          </div>
        )}
        {promoInfo && (
          <div className="row between" style={{ fontSize: 13, marginBottom: 6, color: "var(--ok)" }}>
            <span>✓ {promoInfo.code}</span>
            <span>−{promoInfo.description}</span>
          </div>
        )}
        <div className="divider" style={{ margin: "10px 0" }} />
        <div className="row between" style={{ fontWeight: 700, fontSize: 15 }}>
          <span>Total</span>
          <span style={{ fontFamily: "var(--font-num)" }}>${total}/{billing === "monthly" ? "mo" : "yr"}</span>
        </div>
      </div>

      {/* Promo code */}
      <div className="row" style={{ gap: 8, marginBottom: 8, maxWidth: 380 }}>
        <input value={promoCode} onChange={e => { setPromoCode(e.target.value.toUpperCase()); setPromoInfo(null); setPromoErr(""); }}
          placeholder="Promo code (optional)"
          style={{ flex: 1, padding: "8px 12px", fontSize: 13, background: "var(--surf-2)", color: "var(--text)", border: "1px solid var(--border-2)", borderRadius: "var(--radius-sm)", textTransform: "uppercase", letterSpacing: ".06em", outline: "none" }} />
        <Btn sm kind="ghost" onClick={checkPromo} disabled={checking || !promoCode.trim()}>
          {checking ? "…" : "Apply"}
        </Btn>
      </div>
      {promoErr  && <p style={{ color: "var(--err)", fontSize: 13, marginTop: 4 }}>{promoErr}</p>}
      {payError  && <p style={{ color: "var(--err)", fontSize: 13, marginTop: 4 }}>{payError}</p>}

      <div className="row between" style={{ marginTop: 20 }}>
        <Btn onClick={() => goto("onboarding")}><Icon name="left" /> Back</Btn>
        <Btn kind="primary" lg onClick={checkout} disabled={checkingOut}>
          {checkingOut
            ? <><span className="spin" style={{ display: "inline-block" }}>◐</span> Starting…</>
            : <>Subscribe · ${total}/{billing === "monthly" ? "mo" : "yr"} <Icon name="arrow" /></>}
        </Btn>
      </div>
    </div>
  );
};

Object.assign(window, { ApiSetup, ExtInstall, Subscription });
