/* global React */
// ============================================================
// WAVE AIR · STUDIO (V6) — load-assembling hero + tee mockup. -> window.DGV6
// ============================================================
(function () {
const { useState, useEffect, useRef } = React;
const { Icon, PRODUCT, money, useShop } = window.DGShop;

const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
const easeOut = (t) => 1 - Math.pow(1 - t, 3);
const easeBack = (t) => { const c = 1.9; return 1 + c * Math.pow(t - 1, 3) + (c + 1) * Math.pow(t - 1, 2); };

// Final positions (% of stage) + the moment each piece flies in (timeline 0..1).
const LAYERS = [
  { key: "bg",     src: "assets/scene/bg-w.png",       left: 0,    top: 0,    width: 100, z: 1, phase: [0.00, 0.22], from: { sc: 1.06, op: 0 }, e: "out" },
  { key: "plane",  src: "assets/scene/plane-w.png",    left: 31,   top: 21,   width: 38, z: 4, phase: [0.18, 0.42], from: { x: -150, y: -8, rot: -8, op: 0 }, e: "out", idle: "w-idle-bob" },
  { key: "d1",     src: "assets/scene/disk-1-w.png",   left: 12,   top: 31,   width: 13, z: 3, phase: [0.30, 0.50], from: { y: -260, rot: -14, op: 0 }, e: "back", idle: "w-idle-sway" },
  { key: "d2",     src: "assets/scene/disk-2-w.png",   left: 77,   top: 35,   width: 13, z: 3, phase: [0.34, 0.54], from: { y: -300, rot: 12, op: 0 }, e: "back", idle: "w-idle-sway" },
  { key: "d3",     src: "assets/scene/disk-3-w.png",   left: 23,   top: 53,   width: 13, z: 5, phase: [0.38, 0.58], from: { y: -360, rot: -10, op: 0 }, e: "back", idle: "w-idle-sway" },
  { key: "d4",     src: "assets/scene/disk-4-w.png",   left: 43.5, top: 55,   width: 13, z: 5, phase: [0.42, 0.62], from: { y: -420, rot: 8, op: 0 }, e: "back", idle: "w-idle-sway" },
  { key: "d5",     src: "assets/scene/disk-5-w.png",   left: 73,   top: 55,   width: 13, z: 5, phase: [0.46, 0.66], from: { y: -380, rot: 14, op: 0 }, e: "back", idle: "w-idle-sway" },
  { key: "pa",     src: "assets/scene/people-a-w.png", left: 17,   top: 62,   width: 44, z: 6, phase: [0.56, 0.78], from: { y: 80, op: 0 }, e: "out", idle: "w-idle-dance" },
  { key: "pb",     src: "assets/scene/people-b-w.png", left: 44,   top: 62,   width: 40, z: 6, phase: [0.62, 0.84], from: { y: 90, op: 0 }, e: "out", idle: "w-idle-dance" },
];

// the two wordmarks stamp in as a centered headline overlay (never cropped)
const MARKS = [
  { src: "assets/scene/disco-w.png",  cls: "disco",  phase: [0.74, 0.90] },
  { src: "assets/scene/gringo-w.png", cls: "gringo", phase: [0.84, 1.00] },
];

function Layer({ L, p, idleOn }) {
  const [s, eN] = L.phase;
  const t = clamp((p - s) / (eN - s), 0, 1);
  const e = L.e === "back" ? easeBack(t) : easeOut(t);
  const inv = 1 - e;
  const f = L.from;
  const dx = (f.x || 0) * inv, dy = (f.y || 0) * inv, rot = (f.rot || 0) * inv;
  const sc = 1 + ((f.sc || 1) - 1) * inv;
  const op = (f.op != null ? f.op : 1) + (1 - (f.op != null ? f.op : 1)) * clamp(t * 1.6, 0, 1);
  const style = {
    position: "absolute", left: L.left + "%", top: L.top + "%", width: L.width + "%",
    height: "auto", zIndex: L.z, opacity: op, pointerEvents: "none",
    transform: `translate(${dx}%, ${dy}%) rotate(${rot}deg) scale(${sc})`,
    transformOrigin: "center center", willChange: "transform, opacity",
  };
  // wrap so idle animation on inner img composes with the assembly transform on the wrapper
  if (L.idle) {
    return (
      <div style={style}>
        <img src={L.src} alt="" draggable={false} className={idleOn && t >= 1 ? L.idle : ""} style={{ width: "100%", height: "auto", display: "block" }} />
      </div>
    );
  }
  return <img src={L.src} alt="" draggable={false} style={style} />;
}

// load timeline 0..1 over `dur` ms; replayKey re-triggers it
function useLoadTimeline(dur, replayKey) {
  const [p, setP] = useState(0);
  useEffect(() => {
    let raf, start = null, stop = false;
    const tick = (now) => {
      if (stop) return;
      if (start == null) start = now;
      const prog = clamp((now - start) / dur, 0, 1);
      setP(prog);
      if (prog < 1) raf = requestAnimationFrame(tick);
    };
    setP(0);
    raf = requestAnimationFrame(tick);
    return () => { stop = true; cancelAnimationFrame(raf); };
  }, [dur, replayKey]);
  return p;
}

// scroll progress of an element through the viewport (rAF + scroll, robust)
function useScrollProgress(ref, opts = {}) {
  const { start = 0.85, end = 0.4 } = opts; // when el top crosses these vh fractions
  const [p, setP] = useState(0);
  useEffect(() => {
    let raf = 0, last = -1;
    const compute = () => {
      const el = ref.current; if (!el) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const prog = clamp((start * vh - r.top) / ((start - end) * vh), 0, 1);
      if (Math.abs(prog - last) > 0.002) { last = prog; setP(prog); }
    };
    const loop = () => { compute(); raf = requestAnimationFrame(loop); };
    window.addEventListener("scroll", compute, { passive: true });
    window.addEventListener("resize", compute);
    raf = requestAnimationFrame(loop);
    compute();
    return () => { window.removeEventListener("scroll", compute); window.removeEventListener("resize", compute); cancelAnimationFrame(raf); };
  }, []);
  return p;
}

// light flash glow over each baked-in speaker (no movement, no rings)
function SpeakerFX({ left, top, color, on }) {
  if (!on) return null;
  return (
    <div className={`w-spkfx ${color}`} style={{ left: left + "%", top: top + "%" }}>
      <span className="glow" />
    </div>
  );
}

// ---------------- HERO ----------------
function Hero() {
  const { navigate, t } = useShop();
  const [replay, setReplay] = useState(0);
  const dur = ({ relaxed: 4000, normal: 2700, snappy: 1700 })[(t && t.buildspeed)] || 2700;
  const p = useLoadTimeline(dur, replay);
  const built = p >= 1;
  const markStyle = (ph) => {
    const tt = clamp((p - ph[0]) / (ph[1] - ph[0]), 0, 1);
    const e = easeBack(tt); const inv = 1 - e;
    return { opacity: clamp(tt * 1.6, 0, 1), transform: `translateY(${inv * -8}%) scale(${1 + 0.22 * inv}) rotate(${inv * -3}deg)` };
  };
  return (
    <section className="w-hero">
      <div className="w-stage">
        {LAYERS.map((L) => <Layer key={L.key} L={L} p={p} idleOn={built} />)}
        <div className={`w-hero-flash ${built ? "on" : ""}`} />
        <SpeakerFX left={20.5} top={70} color="pink" on={built} />
        <SpeakerFX left={79.5} top={70} color="teal" on={built} />
      </div>

      <div className="w-hero-scrim" />

      <div className="w-hero-mark">
        {MARKS.map((m) => <img key={m.cls} src={m.src} alt="" className={m.cls} style={markStyle(m.phase)} />)}
      </div>

      <div className="w-hero-top">
        <span className="w-kicker" style={{ opacity: clamp((p - 0.1) * 3, 0, 1), transition: "opacity .3s" }}>Live drop · tonight 9PM · Palmas Beach</span>
      </div>

      <div className="w-hero-bottom">
        <div className="w-wrap" style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 24, flexWrap: "wrap" }}>
          <div>
            <div className="w-head" style={{ fontSize: "clamp(1.5rem,2.6vw,2.1rem)", marginBottom: 4 }}>The party drops tonight.</div>
            <div className="w-body" style={{ maxWidth: 440, margin: 0 }}>One heavyweight tee — the whole jungle disco printed across the front. Watch it land, then make it yours.</div>
          </div>
          <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
            <button className="w-btn lg" onClick={() => navigate("product")}>Shop the tee · {money(PRODUCT.price)}</button>
            <button className="w-ghostbtn" onClick={() => setReplay((n) => n + 1)} aria-label="Replay build">↻ Replay</button>
          </div>
        </div>
      </div>

      <div className="w-hero-cue" style={{ opacity: built ? 1 : 0, transition: "opacity .5s" }}>
        <div className="w-mono" style={{ fontSize: "0.68rem", letterSpacing: "0.14em" }}>SEE IT ON THE TEE</div>
        <Icon name="chevron-down" size={20} />
      </div>
    </section>
  );
}

// ---------------- TEE MOCKUP ----------------
function TeeMockup() {
  const { navigate } = useShop();
  const ref = useRef(null);
  const p = useScrollProgress(ref, { start: 0.9, end: 0.45 });
  const e = easeOut(p);
  const printStyle = {
    opacity: clamp(p * 1.4, 0, 1),
    transform: `translateX(-50%) translateY(${(1 - e) * 5}%) scale(${0.9 + 0.1 * e}) rotate(${(1 - e) * -2}deg)`,
  };
  return (
    <section className="w-tee-sect" ref={ref} id="w-tee">
      <div className="w-wrap">
        <div className="w-tee-grid">
          <div className="w-tee-fig">
            <img className="blank" src="assets/scene/tee-blank.jpg" alt="Natural cotton tee" />
            <img className="print" src="assets/wave-air-tee-web.png" alt="WAVE AIR print" style={printStyle} />
          </div>
          <div>
            <span className="w-kicker">The drop · 001</span>
            <h2 className="w-disp" style={{ fontSize: "clamp(2.4rem,5vw,3.8rem)", margin: "8px 0 14px" }}>ON THE TEE</h2>
            <p className="w-body" style={{ maxWidth: 420 }}>
              Printed full-front on a heavyweight natural-cotton tee, boxy and oversized. The plane, the parachuted vinyl, the whole crowd — straight from the press onto the shirt.
            </p>
            <div style={{ display: "flex", flexDirection: "column", gap: 10, margin: "22px 0 26px" }}>
              {[["shirt", "Heavyweight 240gsm natural cotton"], ["maximize", "Boxy, oversized drop-shoulder fit"], ["badge-check", "Full-front print · numbered run"]].map(([ic, t]) => (
                <div key={t} style={{ display: "flex", alignItems: "center", gap: 11 }}>
                  <span style={{ width: 30, height: 30, borderRadius: "50%", background: "var(--w-pink)", border: "2px solid var(--w-ink)", display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}><Icon name={ic} size={15} /></span>
                  <span className="w-body" style={{ color: "var(--w-ink)", fontWeight: 600, fontSize: "1rem" }}>{t}</span>
                </div>
              ))}
            </div>
            <div style={{ display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap" }}>
              <button className="w-btn lg" onClick={() => navigate("product")}>Pick size &amp; color</button>
              <span className="w-disp" style={{ fontSize: "2rem" }}>{money(PRODUCT.price)}</span>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------------- SPECS ----------------
function Specs() {
  const cards = [
    { ic: "feather", t: "Heavyweight, soft", b: "240gsm natural cotton that wears in, not out. Boxy and oversized." },
    { ic: "printer", t: "Printed loud", b: "Full-front, edge to edge — pink, jade and ink. No tiny chest logo." },
    { ic: "plane", t: "Drops only", b: "One design, one numbered run. When the plane's gone, it's gone." },
  ];
  return (
    <section style={{ padding: "84px 0", background: "var(--w-paper)" }}>
      <div className="w-wrap">
        <div style={{ textAlign: "center", marginBottom: 40 }}>
          <span className="w-kicker">Why this one</span>
          <h2 className="w-disp" style={{ fontSize: "clamp(2rem,5vw,3.4rem)", margin: "8px 0 0" }}>ONE GOOD TEE</h2>
        </div>
        <div className="w-3" style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 20 }}>
          {cards.map((c, i) => (
            <div key={c.t} className={`w-card ${i === 1 ? "teal" : "pink"}`} style={{ height: "100%" }}>
              <span style={{ width: 52, height: 52, borderRadius: "50%", background: i === 1 ? "var(--w-teal)" : "var(--w-pink)", border: "2.5px solid var(--w-ink)", display: "inline-flex", alignItems: "center", justifyContent: "center", marginBottom: 14 }}><Icon name={c.ic} size={24} color={i === 1 ? "#fff" : "var(--w-ink)"} /></span>
              <h3 className="w-head" style={{ fontSize: "1.4rem", margin: "0 0 6px" }}>{c.t}</h3>
              <p className="w-body" style={{ margin: 0 }}>{c.b}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ---------------- Strip ----------------
function Strip() {
  const words = ["WAVE AIR", "THE PARTY DROPS TONIGHT", "DISCO GRINGO", "ONE TEE ONLY", "BYO MOVES", "JUNGLE DISCO"];
  return (
    <div className="w-strip">
      <div className="mq">
        {[0, 1].map((c) => (
          <div key={c} style={{ display: "flex", alignItems: "center" }}>
            {words.map((w, i) => (
              <span key={i} style={{ display: "inline-flex", alignItems: "center", flexShrink: 0 }}>
                <span style={{ fontFamily: "var(--w-disp)", fontSize: "1.1rem", padding: "0 20px", whiteSpace: "nowrap" }}>{w}</span>
                <span style={{ width: 10, height: 10, borderRadius: "50%", background: "var(--w-pink)", flexShrink: 0 }} />
              </span>
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

// ---------------- Nav ----------------
function Nav() {
  const { count, setDrawer, navigate } = useShop();
  const [solid, setSolid] = useState(false);
  useEffect(() => {
    const onScroll = () => setSolid(window.scrollY > window.innerHeight * 0.7);
    window.addEventListener("scroll", onScroll, { passive: true }); onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header className={`w-nav ${solid ? "solid" : ""}`}>
      <div className="w-wrap" style={{ height: 64, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16 }}>
        <button onClick={() => navigate("home")} className="w-logo" aria-label="Disco Gringo home">
          <img className="lg-disco" src="assets/scene/disco-w.png" alt="" />
          <img className="lg-gringo" src="assets/scene/gringo-w.png" alt="Disco Gringo" />
        </button>
        <nav style={{ display: "flex", alignItems: "center", gap: 22 }}>
          <button className="w-navlink w-hide" onClick={() => navigate("product")}>The Tee</button>
          <button className="w-navlink w-hide" onClick={() => document.getElementById("w-tee")?.scrollIntoView({ behavior: "smooth" })}>The Drop</button>
          <button onClick={() => setDrawer(true)} className="w-mono" style={{ display: "inline-flex", alignItems: "center", gap: 8, border: "2px solid var(--w-ink)", background: count > 0 ? "var(--w-ink)" : "transparent", color: count > 0 ? "var(--w-paper)" : "var(--w-ink)", padding: "7px 13px", cursor: "pointer", fontWeight: 700, fontSize: "0.72rem", letterSpacing: "0.12em", textTransform: "uppercase", borderRadius: 999 }}>
            <Icon name="shopping-bag" size={15} /> Bag · {count}
          </button>
        </nav>
      </div>
    </header>
  );
}

// ---------------- Footer ----------------
function Footer() {
  const { navigate } = useShop();
  const [email, setEmail] = useState(""); const [done, setDone] = useState(false);
  return (
    <footer style={{ background: "var(--w-ink)", color: "var(--w-paper)", borderTop: "2px solid var(--w-ink)" }}>
      <div className="w-wrap" style={{ padding: "60px 40px 30px" }}>
        <div className="w-3" style={{ display: "grid", gridTemplateColumns: "1.3fr 1fr", gap: 40 }}>
          <div>
            <span className="w-kicker" style={{ color: "var(--w-pink)" }}>Get on the list</span>
            <h3 className="w-disp" style={{ fontSize: "clamp(1.8rem,4vw,2.8rem)", margin: "8px 0 14px" }}>DON'T MISS<br />THE NEXT DROP</h3>
            <div style={{ display: "flex", gap: 10, maxWidth: 420, flexWrap: "wrap" }}>
              <input className="w-field" style={{ flex: "1 1 200px", background: "rgba(255,255,255,0.06)", color: "#fff", borderColor: "rgba(255,255,255,0.3)" }} placeholder="you@party.com" value={email} onChange={(e) => setEmail(e.target.value)} />
              <button className="w-btn teal" onClick={() => { if (email) { setDone(true); setEmail(""); } }}>{done ? "You're in!" : "Subscribe"}</button>
            </div>
          </div>
          <div style={{ display: "flex", gap: 50, flexWrap: "wrap" }}>
            <FCol title="Shop" links={[["The WAVE AIR tee", () => navigate("product")], ["Your bag", () => navigate("cart")]]} />
            <FCol title="Crew" links={[["Our story", () => navigate("home")], ["Sizing", () => navigate("product")], ["Shipping", () => navigate("product")]]} />
          </div>
        </div>
        <div style={{ marginTop: 44, borderTop: "1px solid rgba(255,255,255,0.18)", paddingTop: 18, display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 12 }}>
          <span className="w-mono" style={{ fontSize: "0.74rem", color: "rgba(255,255,255,0.6)" }}>© 2026 DISCO GRINGO · PALMAS BEACH</span>
          <div style={{ display: "flex", gap: 14 }}>{["instagram", "youtube", "music"].map((n) => <span key={n} style={{ color: "#fff" }}><Icon name={n} size={18} /></span>)}</div>
        </div>
      </div>
      <div className="w-disp" aria-hidden="true" style={{ fontSize: "clamp(2.6rem,15vw,11rem)", textAlign: "center", whiteSpace: "nowrap", margin: 0, padding: "6px 0 0", lineHeight: 0.8, color: "var(--w-pink)", WebkitTextStroke: "2px var(--w-paper)" }}>WAVE AIR</div>
    </footer>
  );
}
function FCol({ title, links }) {
  return (
    <div>
      <div className="w-mono" style={{ fontSize: "0.72rem", letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--w-pink)", marginBottom: 12 }}>{title}</div>
      <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
        {links.map(([l, go]) => <button key={l} onClick={go} style={{ background: "none", border: 0, textAlign: "left", padding: 0, cursor: "pointer", fontFamily: "var(--w-body)", fontWeight: 700, fontSize: "1.02rem", color: "var(--w-paper)" }}>{l}</button>)}
      </div>
    </div>
  );
}

function Home6() {
  return (
    <div>
      <Hero />
      <Strip />
      <TeeMockup />
      <Specs />
      <Footer />
    </div>
  );
}

window.DGV6 = { Hero, TeeMockup, Specs, Strip, Nav, Footer, Home6, useScrollProgress, clamp, easeOut };
})();
