/* global React, ReactDOM */
const { useState, useEffect, useRef } = React;

const TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{
  "paletteWarmth": "noon",
  "heroDensity": "full",
  "reducedMotionPreview": false,
  "showScrollCue": true
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = window.useTweaks
    ? window.useTweaks(TWEAKS_DEFAULTS)
    : [TWEAKS_DEFAULTS, () => {}];

  const [submitted, setSubmitted] = useState(false);
  const [submittedFooter, setSubmittedFooter] = useState(false);
  const [submitting, setSubmitting] = useState(null); // 'hero' | 'footer' | null
  const [submitError, setSubmitError] = useState(null);
  const [hammerTwitch, setHammerTwitch] = useState(false);
  const [scrollSpeed, setScrollSpeed] = useState(0);
  const [scrollY, setScrollY] = useState(0);
  const lastScrollY = useRef(0);
  const lastScrollT = useRef(performance.now());
  const decayRef = useRef(0);

  // Detect reduced motion (system or tweak)
  const systemReduced =
    typeof window !== "undefined" &&
    window.matchMedia &&
    window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const reduced = systemReduced || tweaks.reducedMotionPreview;

  // Hammer twitch every 3-4s
  useEffect(() => {
    if (reduced) return;
    let t;
    const loop = () => {
      const delay = 3000 + Math.random() * 1500;
      t = setTimeout(() => {
        setHammerTwitch(true);
        setTimeout(() => setHammerTwitch(false), 220);
        loop();
      }, delay);
    };
    loop();
    return () => clearTimeout(t);
  }, [reduced]);

  // Scroll handler — parallax + dust speed
  useEffect(() => {
    const onScroll = () => {
      const y = window.scrollY;
      const now = performance.now();
      const dt = Math.max(1, now - lastScrollT.current);
      const dy = y - lastScrollY.current;
      const v = Math.min(1, Math.abs(dy) / dt * 12);
      decayRef.current = Math.max(decayRef.current, v);
      lastScrollY.current = y;
      lastScrollT.current = now;
      setScrollY(y);
    };
    window.addEventListener("scroll", onScroll, { passive: true });

    let raf;
    const decay = () => {
      decayRef.current *= 0.92;
      setScrollSpeed(decayRef.current);
      raf = requestAnimationFrame(decay);
    };
    decay();

    return () => {
      window.removeEventListener("scroll", onScroll);
      cancelAnimationFrame(raf);
    };
  }, []);

  // Apply reduced-motion class to body
  useEffect(() => {
    document.body.classList.toggle("reduced-motion", reduced);
  }, [reduced]);

  const handleSubmit = async (e, which) => {
    e.preventDefault();
    if (submitting) return; // prevent double-submit

    const form = e.currentTarget;
    const email = form.email.value.trim();
    if (!email) return;

    setSubmitting(which);
    setSubmitError(null);

    try {
      const data = new FormData();
      data.append("email", email);
      data.append("metadata__source", which); // 'hero' or 'footer'
      data.append("embed", "1");

      await fetch(
        "https://buttondown.com/api/emails/embed-subscribe/dueling",
        {
          method: "POST",
          body: data,
          mode: "no-cors",
        }
      );

      // 'no-cors' means we can't read the response. Buttondown sends a
      // double-opt-in confirmation email; the user clicks the link to confirm.
      if (which === "hero") setSubmitted(true);
      else setSubmittedFooter(true);
    } catch (err) {
      setSubmitError(
        "We couldn't send your telegraph. Check your connection and try again."
      );
    } finally {
      setSubmitting(null);
    }
  };

  const heroParallax = Math.min(scrollY * 0.15, 200);
  const buildingsParallax = Math.min(scrollY * 0.08, 100);

  return (
    <>
      {/* ================== HEADER / HERO ================== */}
      <header className="hero" data-screen-label="01 Hero">
        <div className="hero-sun" style={{ transform: `translateX(-50%) translateY(${heroParallax * 0.3}px)` }} />
        <HeroRidge />
        <HeroBuildings parallaxY={buildingsParallax} />
        <HeroStreet />
        <div className="hero-shimmer" />
        <DustCanvas scrollSpeed={scrollSpeed} reduced={reduced} />
        <HudRevolver hammerTwitch={hammerTwitch} />

        <div className="hero-content">
          <h1 className="wordmark">Dueling</h1>
          <p className="subtitle">
            <span className="subtitle-rule" aria-hidden="true" />
            A modernized Western · Mobile · Coming
            <span className="subtitle-rule" aria-hidden="true" />
          </p>

          <div className="hero-opponent-wrap">
            <div className="hero-opponent">
              <HeroOpponent />
            </div>
            <div className="hero-opponent-shadow" />
          </div>

          {!submitted ? (
            <form
              className="telegraph-form"
              onSubmit={(e) => handleSubmit(e, "hero")}
              action="https://buttondown.com/api/emails/embed-subscribe/dueling"
              method="post"
              aria-label="Sign up to be notified"
            >
              <label className="telegraph-label" htmlFor="email-hero">
                Telegraph address
              </label>
              <input
                id="email-hero"
                name="email"
                type="email"
                required
                placeholder="you@playdueling.com"
                className="telegraph-input"
                autoComplete="email"
                disabled={submitting === "hero"}
              />
              <button
                type="submit"
                className="telegraph-button"
                disabled={submitting === "hero"}
              >
                <span>{submitting === "hero" ? "Sending…" : "Telegraph me"}</span>
                <span className="glint" aria-hidden="true" />
              </button>
              {submitError && submitting !== "hero" && (
                <p className="telegraph-error" role="alert">
                  {submitError}
                </p>
              )}
            </form>
          ) : (
            <div className="telegraph-success" role="status" aria-live="polite">
              <div className="telegraph-success-eyebrow">— Western Union —</div>
              <p className="telegraph-success-headline">
                Telegraph received. We'll send word.
              </p>
            </div>
          )}

          {!submitted && (
            <p className="form-helper">
              No spam. One message when the doors open.
            </p>
          )}
        </div>

        {tweaks.showScrollCue && (
          <div className="scroll-cue" aria-hidden="true">
            <span className="scroll-cue-line" />
            Read on
            <span className="scroll-cue-line" />
          </div>
        )}
      </header>

      {/* ================== MAIN ================== */}
      <main>
        <section className="below" data-screen-label="02 About">
          <div className="container">
            <div className="about">
              <div className="section-eyebrow">About</div>
              <p className="about-body">
                Two duelists. One street. Your phone is your draw, your aim, your
                shot. <em>Dueling</em> is a mobile motion-sensor reflex shooter
                that asks the question every Western asks: who's faster. We're
                building it now.
              </p>
            </div>

            {/* PILLARS */}
            <div className="pillars" data-screen-label="03 Pillars">
              <div className="pillar">
                <IconRevolver />
                <div className="pillar-number">I.</div>
                <h3 className="pillar-label">Reflex through motion</h3>
              </div>
              <div className="pillar">
                <IconStar />
                <div className="pillar-number">II.</div>
                <h3 className="pillar-label">Fair by server, always</h3>
              </div>
              <div className="pillar">
                <IconShield />
                <div className="pillar-number">III.</div>
                <h3 className="pillar-label">Free-to-play, respectfully</h3>
              </div>
            </div>

            {/* ROSTER */}
            <section className="roster" data-screen-label="04 Roster" aria-labelledby="roster-h">
              <div className="roster-header">
                <div className="section-eyebrow">The Roster</div>
                <h2 id="roster-h" style={{
                  fontFamily: "var(--display)",
                  fontSize: "clamp(28px, 3.4vw, 44px)",
                  letterSpacing: "0.02em",
                  margin: 0,
                  lineHeight: 1.1,
                  color: "var(--ironwood)",
                }}>
                  The duelists you'll face.
                </h2>
              </div>
              <div className="roster-stage">
                <div className="roster-row">
                  <div className="roster-figure">
                    <SilRiley />
                    <div className="roster-figure-shadow" />
                  </div>
                  <div className="roster-figure">
                    <SilDoc />
                    <div className="roster-figure-shadow" />
                  </div>
                  <div className="roster-figure">
                    <SilCassidy />
                    <div className="roster-figure-shadow" />
                  </div>
                  <div className="roster-figure">
                    <SilBlackEye />
                    <div className="roster-figure-shadow" />
                  </div>
                </div>
              </div>
              <div className="roster-names" role="list">
                <div className="roster-name" role="listitem">Riley</div>
                <div className="roster-name" role="listitem">Doc</div>
                <div className="roster-name" role="listitem">Cassidy</div>
                <div className="roster-name" role="listitem">Black-Eye</div>
              </div>
            </section>
          </div>

          {/* REPEATED FORM */}
          <section className="repeat-form-section" data-screen-label="05 Sign up" aria-labelledby="signup-h">
            <h2 id="signup-h" className="repeat-form-headline">
              When the doors open, we'll wire you first.
            </h2>
            <p className="repeat-form-sub">
              One telegram. No social. No spam.
            </p>
            {!submittedFooter ? (
              <form
                className="telegraph-form"
                onSubmit={(e) => handleSubmit(e, "footer")}
                action="https://buttondown.com/api/emails/embed-subscribe/dueling"
                method="post"
                aria-label="Sign up to be notified (repeated)"
              >
                <label className="telegraph-label" htmlFor="email-foot">
                  Telegraph address
                </label>
                <input
                  id="email-foot"
                  name="email"
                  type="email"
                  required
                  placeholder="you@playdueling.com"
                  className="telegraph-input"
                  autoComplete="email"
                  disabled={submitting === "footer"}
                />
                <button
                  type="submit"
                  className="telegraph-button"
                  disabled={submitting === "footer"}
                >
                  <span>{submitting === "footer" ? "Sending…" : "Telegraph me"}</span>
                  <span className="glint" aria-hidden="true" />
                </button>
                {submitError && submitting !== "footer" && (
                  <p className="telegraph-error" role="alert">
                    {submitError}
                  </p>
                )}
              </form>
            ) : (
              <div className="telegraph-success" role="status" aria-live="polite" style={{ margin: "0 auto" }}>
                <div className="telegraph-success-eyebrow">— Western Union —</div>
                <p className="telegraph-success-headline">
                  Telegraph received. We'll send word.
                </p>
              </div>
            )}
          </section>
        </section>
      </main>

      {/* ================== FOOTER ================== */}
      <footer className="fine" data-screen-label="06 Footer">
        <div className="container">
          <div className="footer-mark">DUELING</div>
          <div>© 2026 Dueling. All claims reserved.</div>
          <div style={{ display: "flex", gap: 24, flexWrap: "wrap" }}>
            <a href="mailto:press@playdueling.com">press@playdueling.com</a>
            <a href="privacy.html">Privacy</a>
          </div>
        </div>
      </footer>

      {/* ================== TWEAKS PANEL ================== */}
      {/* Hidden in production. Visit ?tweaks to enable. */}
      {window.TweaksPanel &&
        typeof window !== "undefined" &&
        new URLSearchParams(window.location.search).has("tweaks") && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection title="Atmosphere">
            <window.TweakRadio
              label="Hero density"
              value={tweaks.heroDensity}
              onChange={(v) => setTweak("heroDensity", v)}
              options={[
                { value: "sparse", label: "Sparse" },
                { value: "full", label: "Full" },
              ]}
            />
            <window.TweakToggle
              label="Reduced-motion preview"
              checked={tweaks.reducedMotionPreview}
              onChange={(v) => setTweak("reducedMotionPreview", v)}
            />
            <window.TweakToggle
              label="Scroll cue"
              checked={tweaks.showScrollCue}
              onChange={(v) => setTweak("showScrollCue", v)}
            />
          </window.TweakSection>
        </window.TweaksPanel>
      )}
    </>
  );
}

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