/* Mixto Math — Coming Soon (final, responsive).
   Direction C built out: full-bleed mastery-map constellation behind a
   centered lockup + waitlist capture. Built on the Mixto DS. */

const { Button } = window.MixtoMathDesignSystem_51e530;
const { HeroMap } = window;
const { useTweaks, TweaksPanel, TweakSection, TweakSlider, TweakSelect, TweakToggle } = window;

/* ============================================================
   WAITLIST ENDPOINT — paste your form provider's URL here.
   Works out of the box with Formspree: create a form at
   formspree.io, then set this to "https://formspree.io/f/XXXXXXXX".
   (Buttondown / ConvertKit / a custom endpoint also work — they all
   accept a JSON { email } POST; tweak the body below if your provider
   wants different field names.)
   Leave it as "" to run in demo mode: submissions are validated and
   stored locally (localStorage) so the page still works before you
   connect a provider.
   ============================================================ */
const WAITLIST_ENDPOINT = "https://formspree.io/f/maqzqeda";

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "headline": "gray-green",
  "fullness": 52,
  "showLegend": true,
  "starDust": true
}/*EDITMODE-END*/;

/* ----- constellation cluster defs, driven by a "fullness" 0..100 ----- */
function buildCDefs(fullness) {
  const f = Math.max(0, Math.min(1, fullness / 100));
  const base = [
    { op: "×", label: "Multiply", color: "#18C9D6", fx: 0.16, fy: 0.30, sx: 0.16, sy: 0.26, count: 40, seed: 7, m: 0.36, p: 0.34 },
    { op: "÷", label: "Divide", color: "#FF7A2D", fx: 0.85, fy: 0.26, sx: 0.13, sy: 0.22, count: 26, seed: 21, m: 0.22, p: 0.34 },
    { op: "+", label: "Add", color: "#BFEF3C", fx: 0.12, fy: 0.80, sx: 0.12, sy: 0.18, count: 22, seed: 33, m: 0.30, p: 0.30 },
    { op: "−", label: "Subtract", color: "#84E8EF", fx: 0.86, fy: 0.82, sx: 0.13, sy: 0.16, count: 22, seed: 49, m: 0.28, p: 0.34 },
  ];
  return base.map((c) => {
    const mastered = Math.max(0.04, Math.min(0.84, c.m + (f - 0.5) * 0.55));
    const progress = Math.max(0.08, Math.min(0.5, c.p - (f - 0.5) * 0.12));
    return { op: c.op, label: c.label, color: c.color, fx: c.fx, fy: c.fy, sx: c.sx, sy: c.sy, count: c.count, seed: c.seed, mix: [mastered, progress] };
  });
}

/* ----- the three sacred states legend ----- */
function StateLegend() {
  const items = [
    { c: "#C8CCDE", k: "Unseen", ring: "#B4BAD2" },
    { c: "#FFC23D", k: "Learning", ring: "rgba(255,255,255,.8)" },
    { c: "#28D072", k: "Mastered", ring: "rgba(255,255,255,.8)", glow: true },
  ];
  return (
    <div className="cs-legend">
      {items.map((it) => (
        <span key={it.k} className="cs-legend-item">
          <span className="cs-dot" style={{ background: it.c, boxShadow: it.glow ? "0 0 12px rgba(40,208,114,.6)" : "none", outline: `1.5px solid ${it.ring}`, outlineOffset: -1 }}></span>
          {it.k}
        </span>
      ))}
    </div>
  );
}

/* ----- waitlist email capture: validation, submit, success ----- */
function Waitlist() {
  const [email, setEmail] = React.useState("");
  const [status, setStatus] = React.useState("idle"); // idle | error | submitting | done | neterror
  const inputRef = React.useRef(null);
  const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());

  const submit = async (e) => {
    e.preventDefault();
    if (!valid) { setStatus("error"); inputRef.current && inputRef.current.focus(); return; }
    setStatus("submitting");
    const value = email.trim();
    try {
      if (WAITLIST_ENDPOINT) {
        const res = await fetch(WAITLIST_ENDPOINT, {
          method: "POST",
          headers: { "Content-Type": "application/json", Accept: "application/json" },
          body: JSON.stringify({ email: value, source: "coming-soon" }),
        });
        if (!res.ok) throw new Error("Request failed: " + res.status);
      } else {
        // demo mode — no provider connected yet
        await new Promise((r) => setTimeout(r, 650));
      }
      // remember locally either way (de-dupes + survives reload)
      try {
        const list = JSON.parse(localStorage.getItem("mixto_waitlist") || "[]");
        if (!list.includes(value)) list.push(value);
        localStorage.setItem("mixto_waitlist", JSON.stringify(list));
      } catch {}
      setStatus("done");
    } catch (err) {
      setStatus("neterror");
    }
  };

  if (status === "done") {
    return (
      <div className="cs-success" role="status">
        <div className="cs-success-pill">
          <i className="ph-fill ph-check-circle"></i>
          You're on the list.
        </div>
        <p className="cs-success-note">We'll email <strong>{email.trim()}</strong> the moment Mixto opens.</p>
      </div>
    );
  }

  const busy = status === "submitting";

  return (
    <form className="cs-form" onSubmit={submit} noValidate>
      <div className="cs-formrow">
        <div className="cs-field">
          <i className={`ph-bold ph-envelope-simple cs-field-icon ${status === "error" ? "is-err" : ""}`}></i>
          <input
            ref={inputRef}
            type="email"
            className={`cs-input ${status === "error" || status === "neterror" ? "is-err" : ""}`}
            value={email}
            onChange={(e) => { setEmail(e.target.value); if (status === "error" || status === "neterror") setStatus("idle"); }}
            placeholder="you@email.com"
            aria-label="Email address"
            disabled={busy}
          />
        </div>
        <Button as="button" type="submit" variant="primary" size="lg" className="cs-submit"
          disabled={busy} iconRight={busy ? undefined : "ph-bold ph-arrow-right"}>
          {busy ? <span className="cs-busy"><i className="ph-bold ph-circle-notch cs-spin"></i> Joining…</span> : "Join the waitlist"}
        </Button>
      </div>
      <p className={`cs-formnote ${status === "error" || status === "neterror" ? "is-err" : ""}`}>
        {status === "error"
          ? "Please enter a valid email address."
          : status === "neterror"
          ? "Something went wrong — please try again."
          : "Be first in line. No spam — just one launch-day note."}
      </p>
    </form>
  );
}

/* ----- headline variants (all on-brand) ----- */
function Headline({ variant }) {
  if (variant === "signature") {
    return (
      <React.Fragment>
        <span className="cs-kicker">Coming soon</span>
        <h1 className="cs-headline">Mix it.<br /><span className="cs-accent">Master</span> it.</h1>
      </React.Fragment>
    );
  }
  if (variant === "confidence") {
    return (
      <React.Fragment>
        <span className="cs-kicker">Mix It. Master It.</span>
        <h1 className="cs-headline">Fast facts.<br />Real confidence.</h1>
      </React.Fragment>
    );
  }
  // default: gray → green
  return (
    <React.Fragment>
      <span className="cs-kicker">Mix It. Master It.</span>
      <h1 className="cs-headline">Watch every fact<br />go from gray to green.</h1>
    </React.Fragment>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const cdefs = React.useMemo(() => buildCDefs(t.fullness), [t.fullness]);

  return (
    <div className="cs-stage">
      {/* full-bleed ambient map */}
      <div className="cs-map" aria-hidden="true">
        <HeroMap width={1280} height={840} idSuffix="final" dust={t.starDust ? 90 : 0}
          showLabels={false} bgFrom="#FFFFFF" bgTo="#E4E9F8" clusterDefs={cdefs} />
      </div>
      {/* legibility veil */}
      <div className="cs-veil" aria-hidden="true"></div>

      {/* top bar */}
      <header className="cs-topbar">
        <span className="cs-wordmark">Mi<span className="cs-x">x</span>to</span>
        <span className="cs-eyebrow"><span className="cs-eyebrow-dot"></span>Coming soon</span>
      </header>

      {/* centered lockup */}
      <main className="cs-center">
        <Headline variant={t.headline} />
        <p className="cs-sub">Five minutes of daily practice, real measurable recall. The Reflex-quality fluency game, finally one you can buy.</p>
        <Waitlist />
        {t.showLegend && <StateLegend />}
      </main>

      <footer className="cs-footer">
        <span className="cs-platform">
          <i className="ph-bold ph-apple-logo"></i> iOS
          <span className="cs-sep">·</span>
          <i className="ph-bold ph-globe-hemisphere-west"></i> Web
        </span>
        <span className="cs-footmark">mixtomath.com</span>
      </footer>

      <TweaksPanel>
        <TweakSection label="Hero" />
        <TweakSelect label="Headline" value={t.headline}
          options={[
            { value: "gray-green", label: "Gray to green" },
            { value: "signature", label: "Mix It. Master It." },
            { value: "confidence", label: "Fast facts. Real confidence." },
          ]}
          onChange={(v) => setTweak("headline", v)} />
        <TweakSlider label="Map fullness" value={t.fullness} min={10} max={90} unit="%"
          onChange={(v) => setTweak("fullness", v)} />
        <TweakToggle label="State legend" value={t.showLegend} onChange={(v) => setTweak("showLegend", v)} />
        <TweakToggle label="Star dust" value={t.starDust} onChange={(v) => setTweak("starDust", v)} />
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
