// peper-zegt.jsx, Simon-spel voor het geheugen. Vier knoppen (peper, pet,
// vuur, wasknijper) lichten op in een steeds langere volgorde, speel ze na.
// Werkt met touch, toetsenbord (pijltjes of 1 t/m 4) en gamepad (D-pad via
// de keyboard-bridge in gamepad.jsx). Elke knop heeft een eigen toon.
//
// Pit:
//   mild     = traag tempo, kleuren zichtbaar
//   pittig   = normaal tempo, kleuren zichtbaar
//   vlammend = snel tempo en de knoppen zijn grijs: alleen icoon + toon helpen

const ZEGT_PADS = [
  { id: 0, naam: "Peper",    emoji: "🌶️", kleur: "#E63946", toets: "ArrowUp",    pijl: "↑", freq: 392 },
  { id: 1, naam: "Pet",      emoji: "🧢", kleur: "#3FA34D", toets: "ArrowRight", pijl: "→", freq: 494 },
  { id: 2, naam: "Knijper",  emoji: "🧷", kleur: "#2D9CDB", toets: "ArrowLeft",  pijl: "←", freq: 330 },
  { id: 3, naam: "Vuur",     emoji: "🔥", kleur: "#FF8C1A", toets: "ArrowDown",  pijl: "↓", freq: 587 },
];

const ZEGT_DIFF = {
  mild:     { aan: 650, uit: 300, minAan: 420, start: 1, grijs: false },
  pittig:   { aan: 480, uit: 210, minAan: 270, start: 1, grijs: false },
  vlammend: { aan: 380, uit: 160, minAan: 200, start: 2, grijs: true },
};

const ZEGT_MIJLPALEN = { 5: "STRAF! 🔥", 10: "SUPER! ⚡", 15: "VLAMMEND! 🌶️", 20: "LEGENDE! 🏆" };

function zegtBestKey(level) { return `hp_best_peper-zegt_${level}`; }
function zegtLoadBest(level) {
  try { return Number(window.localStorage.getItem(zegtBestKey(level)) || 0) || 0; } catch { return 0; }
}
function zegtSaveBest(level, n) {
  try { window.localStorage.setItem(zegtBestKey(level), String(n)); } catch {}
}

// Korte tonen via WebAudio. Context wordt pas aangemaakt bij de eerste
// gebruikersactie (autoplay-regels). Faalt stil als audio niet kan.
function useZegtBeep() {
  const ctxRef = React.useRef(null);
  return React.useCallback((freq, ms = 180, type = "triangle") => {
    try {
      if (!ctxRef.current) {
        const AC = window.AudioContext || window.webkitAudioContext;
        if (!AC) return;
        ctxRef.current = new AC();
      }
      const ctx = ctxRef.current;
      if (ctx.state === "suspended") ctx.resume().catch(() => {});
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      osc.type = type;
      osc.frequency.value = freq;
      gain.gain.setValueAtTime(0.0001, ctx.currentTime);
      gain.gain.exponentialRampToValueAtTime(0.25, ctx.currentTime + 0.02);
      gain.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + ms / 1000);
      osc.connect(gain).connect(ctx.destination);
      osc.start();
      osc.stop(ctx.currentTime + ms / 1000 + 0.05);
    } catch {}
  }, []);
}

function PeperZegt({ onClose }) {
  const isMobile = useIsMobile();
  const diff = useDifficulty("peper-zegt", "pittig");
  const cfg = ZEGT_DIFF[diff.level] || ZEGT_DIFF.pittig;

  // fase: idle (startscherm) → kijk (volgorde wordt getoond) → jij (invoer) → over
  const [fase, setFase] = React.useState("idle");
  const [reeks, setReeks] = React.useState([]);
  const [stap, setStap] = React.useState(0);
  const [lit, setLit] = React.useState(null);
  const [fout, setFout] = React.useState(null);
  const [score, setScore] = React.useState(0);
  const [best, setBest] = React.useState(() => zegtLoadBest(diff.level));
  const [nieuwRecord, setNieuwRecord] = React.useState(false);
  const [confetti, setConfetti] = React.useState(0);
  const floaters = useFloaters();
  const beep = useZegtBeep();
  const timers = React.useRef([]);

  const later = React.useCallback((fn, ms) => {
    const t = setTimeout(fn, ms);
    timers.current.push(t);
    return t;
  }, []);
  const stopTimers = React.useCallback(() => {
    timers.current.forEach(clearTimeout);
    timers.current = [];
  }, []);
  React.useEffect(() => stopTimers, [stopTimers]);

  React.useEffect(() => { setBest(zegtLoadBest(diff.level)); }, [diff.level]);

  const start = React.useCallback(() => {
    stopTimers();
    const eerste = Array.from({ length: cfg.start }, () => Math.floor(Math.random() * 4));
    setReeks(eerste); setStap(0); setLit(null); setFout(null);
    setScore(0); setNieuwRecord(false);
    setFase("kijk");
  }, [cfg.start, stopTimers]);

  // Volgorde afspelen. Tempo loopt op met de lengte van de reeks.
  React.useEffect(() => {
    if (fase !== "kijk") return;
    stopTimers();
    const aan = Math.max(cfg.minAan, cfg.aan - reeks.length * 22);
    const uit = Math.max(120, cfg.uit - reeks.length * 8);
    let t = 600;
    reeks.forEach((padId) => {
      later(() => { setLit(padId); beep(ZEGT_PADS[padId].freq, aan * 0.9); }, t);
      later(() => setLit(null), t + aan);
      t += aan + uit;
    });
    later(() => { setStap(0); setFase("jij"); }, t + 100);
  }, [fase, reeks, cfg, later, stopTimers, beep]);

  const druk = React.useCallback((padId) => {
    if (fase !== "jij") return;
    const pad = ZEGT_PADS[padId];
    setLit(padId);
    later(() => setLit(null), 220);
    if (padId === reeks[stap]) {
      beep(pad.freq, 200);
      if (stap + 1 >= reeks.length) {
        const nieuw = score + 1;
        setScore(nieuw);
        setFase("wacht");
        const mijlpaal = ZEGT_MIJLPALEN[nieuw];
        if (mijlpaal) { floaters.pop(mijlpaal, { y: 30, color: "#FFD23F" }); setConfetti(c => c + 1); }
        else floaters.pop("+1", { y: 30, color: "#5BB85B" });
        if (nieuw > best) { setBest(nieuw); setNieuwRecord(true); zegtSaveBest(diff.level, nieuw); }
        later(() => {
          setReeks(r => [...r, Math.floor(Math.random() * 4)]);
          setFase("kijk");
        }, 800);
      } else {
        setStap(s => s + 1);
      }
    } else {
      beep(110, 500, "sawtooth");
      setFout({ gedrukt: padId, juist: reeks[stap] });
      setFase("over");
    }
  }, [fase, reeks, stap, score, best, diff.level, later, beep, floaters]);

  // Toetsenbord + gamepad (bridge stuurt pijltjes/Enter/spatie als KeyboardEvent).
  React.useEffect(() => {
    if (!diff.chosen) return;
    function onKey(e) {
      const idx = ZEGT_PADS.findIndex(p => p.toets === e.key);
      const num = ["1", "2", "3", "4"].indexOf(e.key);
      if (idx >= 0 || num >= 0) {
        e.preventDefault();
        druk(idx >= 0 ? idx : num);
        return;
      }
      if ((e.key === "Enter" || e.key === " ") && (fase === "idle" || fase === "over")) {
        e.preventDefault();
        start();
      }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [diff.chosen, druk, start, fase]);

  if (!diff.chosen) {
    return (
      <div style={gameShellStyle(isMobile, "paars")}>
        <CloseBtn onClose={onClose} isMobile={isMobile} />
        <GameTitle icon="🗣️" kleur="#8E44D1" sub="Onthoud de volgorde en speel ze na">
          PEPER ZEGT
        </GameTitle>
        <DifficultyPicker
          onChoose={(id) => diff.choose(id)}
          currentLevel={diff.level}
          sub="Mild = traag. Pittig = normaal tempo. Vlammend = snel én de knoppen zijn grijs, alleen icoon en toon helpen."
        />
      </div>
    );
  }

  const status =
    fase === "kijk" ? "👀 KIJK EN LUISTER…" :
    fase === "jij" ? `👉 JOUW BEURT! (${stap} / ${reeks.length})` :
    fase === "wacht" ? "✅ JUIST!" :
    fase === "over" ? "💥 OEPS!" : "Druk op START";

  const padSize = isMobile ? "min(38vw, 150px)" : 150;

  return (
    <div style={gameShellStyle(isMobile, "paars")}>
      <CloseBtn onClose={onClose} isMobile={isMobile} />
      <ShellDecor theme="paars" />
      <Confetti trigger={confetti} />
      {floaters.node}
      <GameTitle icon="🗣️" kleur="#8E44D1" sub="Onthoud de volgorde en speel ze na">
        PEPER ZEGT
      </GameTitle>
      <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", position: "relative", zIndex: 1 }}>
        <ScoreBadge score={score} />
        <span style={{
          display: "inline-block", background: nieuwRecord ? "#FFD23F" : "#FFF8EC",
          border: "3px solid #1A1A1A", boxShadow: "3px 3px 0 #1A1A1A",
          padding: "6px 12px", fontFamily: "'Bangers', sans-serif", fontSize: 18, letterSpacing: "0.04em",
        }}>🏆 RECORD {best}{nieuwRecord ? " ✨" : ""}</span>
        <DifficultyBadge level={diff.level} />
      </div>

      <div style={{
        marginTop: 14, textAlign: "center", position: "relative", zIndex: 1,
        fontFamily: "'Bangers', sans-serif", fontSize: isMobile ? 22 : 26,
        letterSpacing: "0.04em", color: fase === "over" ? "#B23A2E" : "#1A1A1A",
        minHeight: 34,
      }}>{status}</div>

      <div style={{
        display: "grid", gridTemplateColumns: "1fr 1fr", gap: isMobile ? 12 : 16,
        justifyContent: "center", margin: "14px auto 0",
        width: "fit-content", position: "relative", zIndex: 1,
      }}>
        {ZEGT_PADS.map(p => {
          const isLit = lit === p.id;
          const isFout = fout && fout.gedrukt === p.id;
          const isJuist = fout && fout.juist === p.id;
          const grijs = cfg.grijs && !isLit && !isJuist;
          const kleur = grijs ? "#9A9A9A" : p.kleur;
          return (
            <button key={p.id} onPointerDown={(e) => { e.preventDefault(); druk(p.id); }}
              aria-label={p.naam}
              style={{
                width: padSize, height: padSize,
                background: isLit
                  ? `radial-gradient(circle at 50% 40%, #FFFFFF 0%, ${tint(kleur, 40)} 35%, ${kleur} 100%)`
                  : `linear-gradient(180deg, ${tint(kleur, 14)} 0%, ${kleur} 60%, ${tint(kleur, -18)} 100%)`,
                border: isFout ? "5px solid #B23A2E" : "4px solid #1A1A1A",
                boxShadow: isLit
                  ? `0 0 0 6px rgba(255,255,255,0.6), 0 0 28px ${kleur}, 2px 2px 0 #1A1A1A`
                  : "5px 5px 0 #1A1A1A",
                borderRadius: 22, cursor: fase === "jij" ? "pointer" : "default",
                fontSize: isMobile ? 48 : 64, lineHeight: 1,
                transform: isLit ? "scale(1.08)" : isFout ? "rotate(-4deg) scale(0.96)" : "scale(1)",
                transition: "transform 0.12s, box-shadow 0.12s, background 0.12s",
                opacity: fase === "kijk" && !isLit ? 0.8 : 1,
                position: "relative", touchAction: "manipulation",
                WebkitTapHighlightColor: "transparent",
                display: "flex", alignItems: "center", justifyContent: "center",
                animation: isJuist ? "pz-juist 0.6s ease-in-out 3" : "none",
              }}>
              <span style={{ filter: isLit ? "drop-shadow(0 0 6px #FFF)" : "none" }}>{p.emoji}</span>
              <span style={{
                position: "absolute", top: 6, left: 10,
                fontFamily: "'Bangers', sans-serif", fontSize: 18,
                color: "#FFF", WebkitTextStroke: "0.8px #1A1A1A", textShadow: "1px 1px 0 #1A1A1A",
                opacity: 0.85,
              }}>{p.pijl}</span>
            </button>
          );
        })}
      </div>

      {(fase === "idle") && (
        <div style={{ marginTop: 18, display: "flex", justifyContent: "center", position: "relative", zIndex: 1 }}>
          <BigButton onClick={start} color="#8E44D1" style={{ color: "#FFF", fontSize: 30 }}>▶ START</BigButton>
        </div>
      )}

      {fase === "over" && (
        <GameDoneScreen
          score={score}
          onReplay={start}
          onClose={onClose}
          onChangeDifficulty={() => { stopTimers(); setFase("idle"); diff.reopen(); }}
          message={
            score === 0
              ? "Nog geen reeks gehaald. Kijk goed en probeer nog eens!"
              : `Je haalde ${score} ${score === 1 ? "reeks" : "reeksen"} op rij${nieuwRecord ? ", een nieuw record!" : `. Je record is ${best}.`}`
          }
        />
      )}

      <div style={{
        marginTop: 14, fontSize: 14, color: "#6B5A3D", textAlign: "center",
        position: "relative", zIndex: 1,
      }}>
        Tik op de knoppen, of gebruik de pijltjes / 1 2 3 4 op je toetsenbord of controller.
      </div>
      <style>{`
        @keyframes pz-juist {
          0%, 100% { box-shadow: 5px 5px 0 #1A1A1A; }
          50% { box-shadow: 0 0 0 8px rgba(91,184,91,0.75), 5px 5px 0 #1A1A1A; }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, { PeperZegt });
