// app.jsx — top-level wiring for the open-world frgmt park.

const { useState: aUseState, useEffect: aUseEffect, useRef: aUseRef, useCallback: aUseCallback } = React;

function App() {
  useGlobalCursor();

  // palette: "park", "after-hours", "riso", "concrete", and the secret "void"
  const [paletteId, setPaletteId] = aUseState("park");
  const [paletteUnlocked, setPaletteUnlocked] = aUseState({ park:1, "after-hours":1, riso:1, concrete:1, void:0 });
  aUseEffect(() => { applyPalette(PALETTES[paletteId]); }, [paletteId]);

  // wildness
  const [wild, setWild] = aUseState(1);

  // welcome flash (first 1.4s)
  const [welcome, setWelcome] = aUseState(true);
  aUseEffect(() => {
    const t = setTimeout(() => setWelcome(false), 1500);
    return () => clearTimeout(t);
  }, []);

  // easter egg state
  const [eggs, setEggs] = aUseState({ sun:0, bench:0, flag:0, stamp:0, garden:0 });
  const [fireworkSeed, setFireworkSeed] = aUseState(0);
  const [balloons, setBalloons] = aUseState([]);
  const balloonId = aUseRef(0);
  const [flashOn, setFlashOn] = aUseState(false);
  const [eggToast, setEggToast] = aUseState(null);

  const triggerEgg = aUseCallback((kind) => {
    setEggs((prev) => ({ ...prev, [kind]: (prev[kind] || 0) + 1 }));
    if (kind === "sun") {
      const order = ["park","riso","after-hours","concrete"];
      const next = order[(order.indexOf(paletteId) + 1) % order.length];
      setPaletteId(next);
      setEggToast({ text: `palette → ${PALETTES[next].label}`, color: "var(--sun)" });
    } else if (kind === "bench") {
      setEggToast({ text: "you sat for a moment.", color: "var(--gum)" });
    } else if (kind === "flag") {
      setFireworkSeed((n) => n + 1);
      setEggToast({ text: "flag · fragments fly", color: "var(--cherry)" });
    } else if (kind === "stamp") {
      setEggToast({ text: "00 / index — wild +", color: "var(--ink)" });
      setWild((w) => clamp(w + 0.4, 0.4, 2.4));
    } else if (kind === "garden") {
      setEggToast({ text: "the pebbles agree", color: "var(--grass)" });
      setFlashOn(true); setTimeout(() => setFlashOn(false), 240);
      setFireworkSeed((n) => n + 1);
    } else if (kind === "konami") {
      setPaletteUnlocked((u) => ({ ...u, void: 1 }));
      setPaletteId("void");
      setEggToast({ text: "void · unlocked", color: "var(--cherry)" });
    } else if (kind === "word") {
      setFireworkSeed((n) => n + 1);
      setFlashOn(true); setTimeout(() => setFlashOn(false), 200);
      setEggToast({ text: "frgmt · spelled", color: "var(--cherry)" });
    } else if (kind === "balloon") {
      // not used directly — see right-click handler
    }
  }, [paletteId]);

  // toast auto-clear
  aUseEffect(() => {
    if (!eggToast) return;
    const t = setTimeout(() => setEggToast(null), 1800);
    return () => clearTimeout(t);
  }, [eggToast]);

  // konami
  useKonami(() => triggerEgg("konami"));
  // word "frgmt"
  useWord("frgmt", () => triggerEgg("word"));

  // 1/2/3/0 hotkeys jump camera
  useHotkey({
    "1": () => window.dispatchEvent(new CustomEvent("frgmt:goto", { detail:{ zone:"slide" }})),
    "2": () => window.dispatchEvent(new CustomEvent("frgmt:goto", { detail:{ zone:"sandbox" }})),
    "3": () => window.dispatchEvent(new CustomEvent("frgmt:goto", { detail:{ zone:"swings" }})),
    "0": () => window.dispatchEvent(new CustomEvent("frgmt:goto-home", {})),
  });

  // right-click anywhere to release a balloon
  aUseEffect(() => {
    const onContext = (e) => {
      e.preventDefault();
      // we want the balloon's spawn in WORLD coords. Dispatch a request to world.
      window.dispatchEvent(new CustomEvent("frgmt:balloon", { detail:{ x: e.clientX, y: e.clientY } }));
    };
    window.addEventListener("contextmenu", onContext);
    return () => window.removeEventListener("contextmenu", onContext);
  }, []);

  // listen for balloon-spawn from outside; world translates viewport coords to world coords
  // (we don't have direct access here, so we listen to an event that supplies world coords)
  aUseEffect(() => {
    const onBalloon = (e) => {
      const colors = ["var(--cherry)","var(--sun)","var(--sky)","var(--grass)","var(--gum)","var(--plum)"];
      setBalloons((b) => [...b, {
        id: balloonId.current++,
        x: e.detail.x, y: e.detail.y,
        born: performance.now(),
        color: choose(colors),
      }].slice(-30));
    };
    window.addEventListener("frgmt:balloon-world", onBalloon);
    return () => window.removeEventListener("frgmt:balloon-world", onBalloon);
  }, []);

  // home/jump-xy listeners must be wired inside World; we re-emit
  // (already handled via "frgmt:goto" by World; "frgmt:goto-home" we handle here)
  aUseEffect(() => {
    const onHome = () => {
      const vw = window.innerWidth, vh = window.innerHeight;
      window.dispatchEvent(new CustomEvent("frgmt:goto-xy", {
        detail: { x: -(1300 - vw/2), y: -(420 - vh/2) }
      }));
    };
    window.addEventListener("frgmt:goto-home", onHome);
    return () => window.removeEventListener("frgmt:goto-home", onHome);
  }, []);

  return (
    <>
      <World wild={wild} onEgg={triggerEgg} balloons={balloons} fireworkSeed={fireworkSeed} />

      {/* HUD: brand corner */}
      <div style={{
        position:"fixed", left:24, top:18, zIndex:60,
        fontFamily:"var(--mono)", fontSize:11, letterSpacing:".08em", textTransform:"uppercase",
        display:"inline-flex", alignItems:"center", gap:10,
      }}>
        <button data-cursor="hot"
          onClick={() => window.dispatchEvent(new CustomEvent("frgmt:goto-home"))}
          style={{ display:"inline-flex", alignItems:"center", gap:8 }}>
          <FrgmtMark size={18} />
          <span style={{ fontFamily:"var(--display)", fontWeight:900, fontSize:18, letterSpacing:"-.02em" }}>frgmt</span>
          <span style={{ opacity:.5 }}>/ a tiny park</span>
        </button>
      </div>

      {/* HUD: zone chips center top */}
      <div style={{
        position:"fixed", left:"50%", top:18, transform:"translateX(-50%)",
        zIndex:60, display:"flex", gap:6,
        fontFamily:"var(--mono)", fontSize:11, letterSpacing:".06em", textTransform:"uppercase",
      }}>
        {["slide","sandbox","swings"].map((id) => (
          <button key={id} data-cursor="hot"
            onClick={() => window.dispatchEvent(new CustomEvent("frgmt:goto", { detail:{ zone: id } }))}
            style={{
              padding:"6px 12px", borderRadius:99,
              border:"1px solid rgba(14,14,14,.18)",
              background:"rgba(242,235,220,.6)",
              backdropFilter:"blur(4px)",
            }}>{id}</button>
        ))}
      </div>

      {/* HUD: status / palette / wildness */}
      <div style={{
        position:"fixed", right:24, top:18, zIndex:60, display:"flex", gap:10, alignItems:"center",
        fontFamily:"var(--mono)", fontSize:11, letterSpacing:".06em", textTransform:"uppercase",
      }}>
        <span style={{ display:"inline-flex", alignItems:"center", gap:6 }}>
          <span style={{ width:6, height:6, borderRadius:99, background:"var(--cherry)", boxShadow:"0 0 0 4px rgba(232,85,58,.18)" }} />
          live
        </span>

        {/* palette dots */}
        <span style={{ display:"inline-flex", gap:4, padding:"4px 8px", border:"1px solid rgba(14,14,14,.2)", borderRadius:99, background:"rgba(242,235,220,.6)", backdropFilter:"blur(4px)" }}>
          {Object.entries(PALETTES).map(([id, p]) => paletteUnlocked[id] ? (
            <button key={id} data-cursor="hot"
              title={p.label}
              onClick={() => setPaletteId(id)}
              style={{
                width:14, height:14, borderRadius:"50%",
                background: p.cherry,
                border: id === paletteId ? "2px solid var(--ink)" : "1px solid rgba(14,14,14,.2)",
              }}/>
          ) : null)}
        </span>

        {/* wildness slider */}
        <label data-cursor="hot" style={{ display:"inline-flex", alignItems:"center", gap:6, padding:"4px 8px", border:"1px solid rgba(14,14,14,.2)", borderRadius:99, background:"rgba(242,235,220,.6)", backdropFilter:"blur(4px)" }}>
          wild
          <input type="range" min="0.4" max="2.4" step="0.1"
            value={wild} onChange={(e) => setWild(+e.target.value)}
            onMouseDown={(e) => e.stopPropagation()}
            style={{ width: 70 }} />
        </label>
      </div>

      <Ticker items={[
        "frgmt is a park",
        "drag the ground to wander",
        "type letters · drop FRGMT",
        "drag shapes onto the sand",
        "push a swing · paint the air",
        "find the pebbles",
        "right-click to let a balloon go",
        "↑↑↓↓←→←→ b a",
      ]} />

      {/* welcome flash */}
      {welcome && (
        <div style={{
          position:"fixed", inset:0, zIndex:9100, pointerEvents:"none",
          display:"flex", alignItems:"center", justifyContent:"center",
          animation:"welcomeFade 1.5s cubic-bezier(.2,.8,.2,1) forwards",
        }}>
          <div style={{
            display:"flex", alignItems:"center", gap:14, color:"var(--paper)",
            animation:"welcomeMark 1.5s cubic-bezier(.2,.8,.2,1) forwards",
          }}>
            <FrgmtMark size={48} color="var(--paper)" />
            <span style={{ fontFamily:"var(--display)", fontWeight:900, fontSize:54, letterSpacing:"-.04em" }}>
              frgmt
            </span>
          </div>
        </div>
      )}

      {/* full screen flash for special moments */}
      <div className={"full-flash" + (flashOn ? " on" : "")} />

      {/* egg toast */}
      {eggToast && (
        <div style={{
          position:"fixed", left:"50%", bottom: 60, transform:"translateX(-50%)",
          zIndex:9200,
          padding:"8px 14px",
          background:"var(--ink)", color: eggToast.color || "var(--paper)",
          fontFamily:"var(--mono)", fontSize:11, letterSpacing:".1em", textTransform:"uppercase",
          border:"1.5px solid var(--ink)", borderRadius:99,
          boxShadow:"3px 3px 0 var(--cherry)",
          animation:"flashin .4s var(--ease-out) both",
          pointerEvents:"none",
        }}>{eggToast.text}</div>
      )}
    </>
  );
}

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