// Pure spelregels staan boven de React-weergave, zodat timing en bestellingen
// ook zonder browser getest kunnen worden. Alle tijden zijn in seconden.
const PIZZA_TOPPINGS = [
  { id: 'kaas', naam: 'Kaas', icon: '🧀' },
  { id: 'champignon', naam: 'Champignon', icon: '🍄' },
  { id: 'peper', naam: 'Peper', icon: '🌶️' },
  { id: 'olijf', naam: 'Olijf', icon: '🫒' },
];
const PIZZA_CONFIG = {
  mild: { patience: 65, bake: 6, window: 8, arrival: 20, trouble: false },
  pittig: { patience: 50, bake: 7, window: 6, arrival: 16, trouble: true },
  vlammend: { patience: 38, bake: 8, window: 4, arrival: 12, trouble: true },
};
function pizzaOrder(id, cfg, elapsed, seed) {
  // Kleine lokale PRNG: recepten veranderen per ronde, de reducer blijft puur.
  let n = (seed + id * 2654435761) >>> 0;
  const random = () => { n = (Math.imul(n, 1664525) + 1013904223) >>> 0; return n / 4294967296; };
  const pool = PIZZA_TOPPINGS.map(t => t.id);
  for (let i = pool.length - 1; i > 0; i--) {
    const j = Math.floor(random() * (i + 1));
    [pool[i], pool[j]] = [pool[j], pool[i]];
  }
  const count = elapsed < 30 ? 2 : 2 + (random() > 0.45 ? 1 : 0);
  return { id, toppings: pool.slice(0, count), left: cfg.patience, total: cfg.patience };
}
function pizzaInitial(level = 'pittig', seed = 1) {
  const cfg = PIZZA_CONFIG[level] || PIZZA_CONFIG.pittig;
  return { level, seed, phase: 'idle', elapsed: 0, score: 0, served: 0, lives: 3,
    orders: [pizzaOrder(1, cfg, 0, seed)], nextId: 2, arrival: cfg.arrival,
    toppings: [], stage: 'prep', heat: 0, streak: 0, superLeft: 0,
    frozen: 0, troubleAt: 28, troubleCount: 0, notice: 'De eerste klant is er. Beleg je pizza!', noticeLeft: 5 };
}
function pizzaReducer(s, a) {
  if (a.type === 'RESET') return pizzaInitial(a.level, 1);
  if (a.type === 'START') return { ...pizzaInitial(a.level, a.seed), phase: 'play' };
  if (a.type === 'PAUSE' && s.phase === 'play') return { ...s, phase: 'paused' };
  if (a.type === 'RESUME' && s.phase === 'paused') return { ...s, phase: 'play' };
  if (s.phase !== 'play') return s;
  const cfg = PIZZA_CONFIG[s.level] || PIZZA_CONFIG.pittig;
  const say = (text, changes = {}) => ({ ...s, ...changes, notice: text, noticeLeft: 5 });
  if (a.type === 'TOPPING' && s.stage === 'prep' && PIZZA_TOPPINGS.some(t => t.id === a.id)) {
    return { ...s, toppings: s.toppings.includes(a.id) ? s.toppings.filter(t => t !== a.id) : [...s.toppings, a.id] };
  }
  if (a.type === 'OVEN') {
    if (s.stage === 'prep' && s.toppings.length) return say('Haal de pizza uit de oven zodra de meter groen is.', { stage: 'baking', heat: 0 });
    if (s.stage === 'baking' && s.heat >= cfg.bake) return say('Mooi gebakken! Serveer je pizza.', { stage: 'plate' });
    if (s.stage === 'baking') return say('Nog even bakken! Wacht op het groene deel.');
  }
  if (a.type === 'DISCARD') return say('Een verse bodem. Probeer opnieuw!', { stage: 'prep', toppings: [], heat: 0, streak: 0 });
  if (a.type === 'SERVE' && s.stage === 'plate') {
    const match = s.orders.find(o => o.toppings.length === s.toppings.length && o.toppings.every(t => s.toppings.includes(t)));
    if (!match) return say('Niemand bestelde deze combinatie. Wacht op een klant of pak een nieuwe bodem.');
    const streak = s.streak + 1;
    const bonus = 100 + Math.ceil(match.left / match.total * 50);
    let orders = s.orders.filter(o => o.id !== match.id);
    let nextId = s.nextId;
    if (!orders.length) orders = [pizzaOrder(nextId++, cfg, s.elapsed, s.seed)];
    return say(streak === 3 ? 'VUURADEM! 12 seconden sneller bakken!' : `Mamma mia! +${bonus} punten.`, {
      score: s.score + bonus, served: s.served + 1, orders, nextId, stage: 'prep', toppings: [], heat: 0,
      streak: streak === 3 ? 0 : streak, superLeft: streak === 3 ? 12 : s.superLeft,
    });
  }
  if (a.type !== 'TICK') return s;
  const dt = Math.max(0, Math.min(0.25, a.dt || 0));
  let n = { ...s, elapsed: Math.min(120, s.elapsed + dt), noticeLeft: Math.max(0, s.noticeLeft - dt),
    superLeft: Math.max(0, s.superLeft - dt), frozen: Math.max(0, s.frozen - dt) };
  n.orders = s.orders.map(o => ({ ...o, left: Math.max(0, o.left - dt) }));
  const lost = n.orders.filter(o => o.left <= 0).length;
  if (lost) {
    n.orders = n.orders.filter(o => o.left > 0);
    n.lives = Math.max(0, n.lives - lost); n.streak = 0;
    n.notice = 'Een klant moest vertrekken. De volgende lukt vast!'; n.noticeLeft = 5;
  }
  if (s.stage === 'baking') {
    // Vuuradem versnelt alleen het garen, niet de tijd om de pizza te redden.
    const speed = s.heat < cfg.bake && s.superLeft > 0 ? 2.5 : 1;
    const frozenTime = s.superLeft > 0 ? 0 : Math.min(dt, s.frozen);
    n.heat = s.heat + (dt - frozenTime) * speed;
    if (n.heat >= cfg.bake + cfg.window) {
      n.stage = 'burnt'; n.streak = 0;
      n.notice = 'Oeps, aangebrand! Pak een nieuwe bodem.'; n.noticeLeft = 5;
    }
  }
  n.arrival -= dt;
  const capacity = n.elapsed < 30 ? 1 : n.elapsed < 65 ? 2 : 3;
  if (!n.orders.length || (n.arrival <= 0 && n.orders.length < capacity)) {
    n.orders.push(pizzaOrder(n.nextId++, cfg, n.elapsed, n.seed));
    n.arrival = cfg.arrival;
  }
  if (cfg.trouble && n.elapsed >= n.troubleAt) {
    n.troubleAt += 28; n.troubleCount++;
    if (n.troubleCount % 2) {
      n.frozen = 4;
      n.notice = n.superLeft > 0 ? 'De IJsheks! Je vuuradem houdt de oven warm.' : 'De IJsheks bevriest de oven voor 4 seconden!';
    } else if (n.stage === 'prep' && n.toppings.length) {
      const stolen = n.toppings[n.toppings.length - 1];
      n.toppings = n.toppings.slice(0, -1);
      n.notice = `De Wasknijper stal je ${PIZZA_TOPPINGS.find(t => t.id === stolen).naam.toLowerCase()}! Leg die er opnieuw op.`;
    } else n.notice = 'De Wasknijper sluipt langs… Gelukkig zijn je toppings veilig!';
    n.noticeLeft = 6;
  }
  if (n.elapsed >= 120 || n.lives <= 0) n.phase = 'over';
  return n;
}

function PizzeriaPizza({ toppings, burnt, baking }) {
  return <div className={`pp-pizza ${burnt ? 'pp-burnt' : ''} ${baking ? 'pp-baking' : ''}`} aria-label={burnt ? 'Aangebrande pizza' : `Pizza met ${toppings.map(id => PIZZA_TOPPINGS.find(t => t.id === id).naam).join(', ') || 'tomatensaus'}`} role="img">
    {toppings.flatMap((id, i) => [0, 1, 2].map(j => {
      const angle = (i * 90 + j * 27) * Math.PI / 180;
      const radius = 21 + j * 8;
      return <span key={`${id}-${j}`} style={{ left: `${50 + Math.cos(angle) * radius}%`, top: `${50 + Math.sin(angle) * radius}%`, transform: `translate(-50%, -50%) rotate(${i * 24 + j * 15}deg)` }}>{PIZZA_TOPPINGS.find(t => t.id === id).icon}</span>;
    }))}
  </div>;
}

function PeperPizzeria({ onClose }) {
  const isMobile = useIsMobile();
  const diff = useDifficulty('peper-pizzeria', 'pittig');
  const [s, dispatch] = React.useReducer(pizzaReducer, undefined, () => pizzaInitial());
  const [best, setBest] = React.useState(0);
  const cfg = PIZZA_CONFIG[s.level];
  const start = () => dispatch({ type: 'START', level: diff.level, seed: Math.floor(Math.random() * 4294967296) });
  React.useEffect(() => {
    try { setBest(Number(localStorage.getItem(`hp_best_peper-pizzeria_${diff.level}`)) || 0); } catch { setBest(0); }
  }, [diff.level]);
  React.useEffect(() => {
    if (s.phase !== 'over') return;
    setBest(previous => {
      const record = Math.max(previous, s.score);
      try { localStorage.setItem(`hp_best_peper-pizzeria_${s.level}`, String(record)); } catch {}
      return record;
    });
  }, [s.phase, s.score, s.level]);
  React.useEffect(() => {
    if (s.phase !== 'play') return;
    let last = performance.now();
    const timer = setInterval(() => {
      const now = performance.now();
      dispatch({ type: 'TICK', dt: (now - last) / 1000 }); last = now;
    }, 100);
    return () => clearInterval(timer);
  }, [s.phase]);
  React.useEffect(() => {
    const hide = () => { if (document.hidden) dispatch({ type: 'PAUSE' }); };
    document.addEventListener('visibilitychange', hide);
    return () => document.removeEventListener('visibilitychange', hide);
  }, []);
  React.useEffect(() => {
    function key(e) {
      if (e.repeat || e.altKey || e.ctrlKey || e.metaKey || /INPUT|TEXTAREA|SELECT/.test(e.target.tagName)) return;
      const k = e.key.toLowerCase();
      const idx = ['1', '2', '3', '4'].indexOf(k);
      const type = k === 'b' ? 'OVEN' : k === 's' ? 'SERVE' : k === 'x' ? 'DISCARD' : k === 'p' ? (s.phase === 'paused' ? 'RESUME' : 'PAUSE') : null;
      if (idx >= 0 || type) { e.preventDefault(); dispatch(idx >= 0 ? { type: 'TOPPING', id: PIZZA_TOPPINGS[idx].id } : { type }); }
    }
    window.addEventListener('keydown', key);
    return () => window.removeEventListener('keydown', key);
  }, [s.phase]);
  const active = s.phase === 'play';
  const ready = s.stage === 'baking' && s.heat >= cfg.bake;
  const matching = s.orders.some(o => o.toppings.length === s.toppings.length && o.toppings.every(t => s.toppings.includes(t)));
  const status = s.stage === 'burnt' ? 'Aangebrand… nieuwe bodem!' : s.stage === 'plate' ? 'Klaar om te serveren!' : ready ? 'GOUDEN KORST! Haal eruit!' : s.stage === 'baking' ? (s.frozen > 0 && !s.superLeft ? 'Brrr… oven bevroren!' : 'Even bakken…') : 'Beleg de bestelling';
  return <div className="pp-game" style={{ ...gameShellStyle(isMobile, 'oranje'), width: isMobile ? '100%' : 'min(850px, 94vw)', padding: isMobile ? '16px 12px 24px' : '24px', maxHeight: isMobile ? undefined : 'calc(100dvh - 40px)', overflowY:'auto' }}>
    <style>{`
      .pp-game { box-sizing:border-box; }
      .pp-game * { box-sizing:border-box; }
      .pp-game button { touch-action:manipulation; font-family:inherit; }
      .pp-game button:focus-visible { outline:4px solid #2165c2; outline-offset:3px; }
      .pp-game button:disabled { opacity:.5; cursor:default; }
      .pp-heading { margin:0; font:clamp(30px,6vw,48px)/1 'Bangers',sans-serif; letter-spacing:1px; }
      .pp-awning { height:15px; margin:16px -24px 14px; background:repeating-linear-gradient(90deg,#e63946 0 32px,#fff8ec 32px 64px); border-block:3px solid #241c19; }
      .pp-hud { display:flex; gap:8px; flex-wrap:wrap; align-items:center; font-weight:bold; }
      .pp-hud span { padding:5px 9px; background:#fff8ec; border:2px solid #241c19; border-radius:8px; }
      .pp-btn { border:3px solid #241c19; border-radius:10px; background:#fff8ec; color:#241c19; min-height:44px; padding:8px 12px; font-size:18px; font-weight:bold; cursor:pointer; box-shadow:2px 3px 0 #241c19; }
      .pp-orders { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; margin:12px 0; }
      .pp-order { background:#fff8ec; border:3px solid #241c19; border-radius:12px; padding:9px; min-height:118px; }
      .pp-order h3 { margin:0 0 5px; font-size:17px; }
      .pp-recipe { font-size:24px; min-height:34px; }
      .pp-meter { height:12px; background:#e4d5bc; border:2px solid #241c19; border-radius:9px; overflow:hidden; }
      .pp-meter > div { height:100%; background:#3c8b48; }
      .pp-kitchen { display:grid; grid-template-columns:1fr 1fr; gap:14px; background:#fff8ec; border:3px solid #241c19; border-radius:14px; padding:16px; }
      .pp-board { display:flex; align-items:center; justify-content:center; min-height:200px; background:repeating-linear-gradient(0deg,#e8bb7c 0 35px,#dba767 36px 38px); border-radius:10px; position:relative; }
      .pp-pizza { width:190px; height:190px; border:13px solid #e7a549; background:radial-gradient(circle,#e65235 0 65%,#b93120 100%); border-radius:50%; box-shadow:0 6px 0 #956032, inset 0 0 0 4px #ffcd74; position:relative; transition:filter .3s; }
      .pp-pizza span { position:absolute; font-size:27px; }
      .pp-baking { box-shadow:0 0 30px #fb7929,inset 0 0 0 4px #ffcd74; }
      .pp-burnt { filter:grayscale(1) brightness(.35); }
      .pp-toppings { display:grid; grid-template-columns:1fr 1fr; gap:9px; }
      .pp-toppings button { font-size:16px; padding:7px 4px; }
      .pp-toppings button[aria-pressed=true] { background:#ffe17b; box-shadow:inset 0 0 0 2px #c48119; }
      .pp-toppings b { display:block; font-size:28px; }
      .pp-oven { margin-top:14px; padding:12px; background:#2d2928; color:#fff8ec; border-radius:10px; }
      .pp-heat { height:20px; border:2px solid #fff8ec; border-radius:6px; position:relative; margin:8px 0; }
      .pp-heat i { position:absolute; top:-5px; bottom:-5px; width:5px; background:#fff; box-shadow:0 0 0 2px #241c19; }
      .pp-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:12px; }
      .pp-actions button { flex:1; }
      .pp-notice { min-height:50px; display:flex; align-items:center; justify-content:center; text-align:center; margin:10px 0; padding:8px; background:#ffe17b; border:2px solid #241c19; border-radius:9px; font-size:18px; }
      .pp-intro { text-align:center; padding:12px 0; }
      .pp-intro p { font-size:19px; max-width:530px; margin:14px auto; }
      .pp-intro img { height:135px; object-fit:contain; }
      @media(max-width:700px) { .pp-awning { margin-left:-12px; margin-right:-12px; } }
      @media(max-width:500px) {
        .pp-kitchen { gap:10px; padding:10px; grid-template-columns:1fr 1fr; }
        .pp-board { min-height:156px; }
        .pp-pizza { width:132px; height:132px; border-width:10px; }
        .pp-pizza span { font-size:20px; }
        .pp-order { padding:6px; min-height:108px; }
        .pp-order h3 { font-size:14px; }
        .pp-recipe { font-size:20px; }
        .pp-toppings button { font-size:13px; }
        .pp-toppings b { font-size:23px; }
        .pp-hud { gap:5px; font-size:14px; }
        .pp-notice { font-size:16px; }
      }
      @media(max-width:360px) {
        .pp-pizza { width:112px; height:112px; }
        .pp-pizza span { font-size:18px; }
        .pp-toppings button { font-size:12px; }
        .pp-actions button { font-size:16px; padding:8px 5px; }
      }
    `}</style>
    <button className="pp-btn" onClick={onClose} aria-label="Spel sluiten" style={{ position:'absolute', right:12, top:12, zIndex:2 }}>✕</button>
    <header style={{ paddingRight:48 }}><div style={{ fontSize:14, letterSpacing:2 }}>PEPPERONI CITY • VERS UIT DE OVEN</div><h2 className="pp-heading">🍕 Peper Pizzeria!</h2></header>
    <div className="pp-awning" />
    {!diff.chosen ? <DifficultyPicker currentLevel={diff.level} onChoose={diff.choose} sub="Mild: geduldige klanten, geen boeven. Pittig: drukte en kattenkwaad. Vlammend: sneller handelen!" /> : s.phase === 'idle' ? <div className="pp-intro">
      <img src="/assets/hete-peper-vuur.png" alt="Hete Peper staat klaar om te bakken" />
      <h3 style={{ fontFamily:"'Bangers',sans-serif", fontSize:30, margin:8 }}>Jouw pizzeria gaat open!</h3>
      <p>Bekijk de bestelling. Tik de juiste toppings aan, bak je pizza en haal hem uit de oven als de meter <strong>groen</strong> is. Serveer hem aan de klant met hetzelfde recept!</p>
      <p>Je hebt <strong>2 minuten en 3 hartjes</strong>. Een vertrekkende klant kost een hartje. Drie goede pizza’s op rij? Dan bak je 12 seconden sneller met vuuradem!</p>
      <p>Tomatensaus zit al op de bodem. Tik nog eens op een topping om hem te verwijderen.</p>
      <button className="pp-btn" style={{ background:'#ffd23f', fontSize:24 }} onClick={start}>OPEN DE PIZZERIA →</button>
    </div> : <React.Fragment>
      <div className="pp-hud">
        <span>⭐ {s.score}</span><span>⏱ {Math.ceil(120 - s.elapsed)}s</span><span aria-label={`${s.lives} hartjes over`}>{'❤️'.repeat(s.lives) || '♡'}</span><span>🏆 {best}</span>
        <button className="pp-btn" disabled={s.phase === 'over'} style={{ marginLeft:'auto', fontSize:15 }} onClick={() => dispatch({ type:s.phase === 'paused' ? 'RESUME' : 'PAUSE' })}>{s.phase === 'paused' ? '▶ Verder' : 'Ⅱ Pauze'}</button>
      </div>
      {s.phase === 'over' ? <GameDoneScreen score={s.score} onReplay={start} onClose={onClose} onChangeDifficulty={() => { dispatch({ type:'RESET', level:diff.level }); diff.reopen(); }} message={`${s.lives ? 'Sluitingstijd!' : 'De laatste klant is vertrokken.'} Je serveerde ${s.served} pizza’s en verdiende ${s.score} punten. Record: ${Math.max(best, s.score)}.`} /> : s.phase === 'paused' ? <div className="pp-intro"><h3>De keuken staat even stil.</h3><p>Je pizza en klanten wachten op je.</p><button className="pp-btn" onClick={() => dispatch({ type:'RESUME' })}>VERDER BAKKEN</button></div> : <React.Fragment>
        <div className="pp-orders" aria-label="Bestellingen">
          {s.orders.map((o) => <article className="pp-order" key={o.id}>
            <h3>{['👩‍🚒', '👨‍🎨', '👩‍🚀', '🧑‍🌾'][o.id % 4]} Klant {o.id}</h3>
            <div className="pp-recipe">{o.toppings.map(id => <span key={id} title={PIZZA_TOPPINGS.find(t => t.id === id).naam} aria-label={PIZZA_TOPPINGS.find(t => t.id === id).naam} role="img">{PIZZA_TOPPINGS.find(t => t.id === id).icon}</span>)}</div>
            <div className="pp-meter" role="progressbar" aria-label={`Geduld klant ${o.id}`} aria-valuemin={0} aria-valuemax={o.total} aria-valuenow={Math.ceil(o.left)}><div style={{ width:`${o.left/o.total*100}%`, background:o.left < 12 ? '#e63946' : '#3c8b48' }} /></div>
            <small>{Math.ceil(o.left)}s geduld</small>
          </article>)}
          {Array.from({ length:3-s.orders.length }, (_,i) => <div key={`empty-${i}`} className="pp-order" style={{ opacity:.55, borderStyle:'dashed', display:'grid', placeItems:'center', textAlign:'center' }}>Volgende<br />klant…</div>)}
        </div>
        <div className="pp-notice" role="status" aria-live="polite">{s.noticeLeft > 0 ? s.notice : s.superLeft > 0 ? '🔥 Vuuradem actief! Je pizza gaart extra snel.' : `🔥 ${s.streak}/3 pizza’s voor vuuradem • ${s.served} geserveerd`}</div>
        <div className="pp-kitchen">
          <div className="pp-board"><PizzeriaPizza toppings={s.toppings} burnt={s.stage === 'burnt'} baking={s.stage === 'baking'} /></div>
          <div><div style={{ fontWeight:'bold', marginBottom:8 }}>1. Kies je toppings</div><div className="pp-toppings">
            {PIZZA_TOPPINGS.map((t,i) => <button key={t.id} className="pp-btn" disabled={!active || s.stage !== 'prep'} aria-pressed={s.toppings.includes(t.id)} aria-label={t.naam} onClick={() => dispatch({ type:'TOPPING', id:t.id })}><b>{t.icon}</b>{t.naam} {s.toppings.includes(t.id) ? '✓' : ''}<small style={{ display:'block' }}>toets {i+1}</small></button>)}
          </div></div>
        </div>
        <div className="pp-oven">
          <div style={{ display:'flex', justifyContent:'space-between', gap:8 }}><strong>2. {status}</strong><span>{s.superLeft > 0 ? `🔥 ${Math.ceil(s.superLeft)}s` : s.frozen > 0 ? `❄️ ${Math.ceil(s.frozen)}s` : '♨ OVEN'}</span></div>
          <div className="pp-heat" role="progressbar" aria-label="Baktijd; groen is klaar" aria-valuemin={0} aria-valuemax={cfg.bake+cfg.window} aria-valuenow={Math.min(s.heat,cfg.bake+cfg.window)} style={{ background:`linear-gradient(to right,#d79839 0%,#d79839 ${cfg.bake/(cfg.bake+cfg.window)*100}%,#489653 ${cfg.bake/(cfg.bake+cfg.window)*100}%,#489653 96%,#e63946 96%)` }}><i style={{ left:`${Math.min(98,s.heat/(cfg.bake+cfg.window)*100)}%` }} /></div>
          <div style={{ display:'flex', justifyContent:'space-between', fontSize:13 }}><span>Nog rauw</span><span>Groen = eruit!</span><span>Verbrand</span></div>
        </div>
        <div className="pp-actions">
          <button className="pp-btn" style={{ background:ready ? '#b6e2a7' : '#ffd23f' }} disabled={!active || !['prep','baking'].includes(s.stage) || (s.stage === 'prep' && !s.toppings.length) || (s.stage === 'baking' && !ready)} onClick={() => dispatch({ type:'OVEN' })}>{s.stage === 'baking' ? '🍕 Haal eruit [B]' : '🔥 Bakken [B]'}</button>
          <button className="pp-btn" style={{ background:'#b6e2a7' }} disabled={!active || s.stage !== 'plate' || !matching} onClick={() => dispatch({ type:'SERVE' })}>3. Serveer [S]</button>
          <button className="pp-btn" disabled={!active} onClick={() => dispatch({ type:'DISCARD' })}>Nieuwe bodem [X]</button>
        </div>
        {s.stage === 'plate' && !matching && <p role="status">Dit recept past bij geen enkele klant. Pak een nieuwe bodem of wacht op een passende bestelling.</p>}
        <p style={{ fontSize:13, textAlign:'center', marginBottom:0 }}>Tik op de knoppen of gebruik 1–4 · B bakken/uithalen · S serveren · X nieuwe bodem · P pauze</p>
      </React.Fragment>}
    </React.Fragment>}
  </div>;
}
Object.assign(window, { PeperPizzeria });
