// Sticker Catcher — a tiny, cute mini-game.
// Click stickers as they fall. Hits = score. Miss = lost sticker.
// 30-second round. Keeps with the scrapbook visual language.

function StickerGame({ T, F }) {
  const [running, setRunning] = React.useState(false);
  const [time, setTime] = React.useState(30);
  const [score, setScore] = React.useState(0);
  const [missed, setMissed] = React.useState(0);
  const [stickers, setStickers] = React.useState([]); // {id,x,vx,vy,y,rot,emoji,bg,popped}
  const [best, setBest] = React.useState(() => Number(localStorage.getItem('sp_best') || 0));
  const idRef = React.useRef(0);
  const fieldRef = React.useRef(null);

  const EMOJIS = ['★','♥','✦','◆','●','▲','✿','♪'];

  // game loop
  React.useEffect(() => {
    if (!running) return;
    let raf, last = performance.now();
    const W = () => fieldRef.current ? fieldRef.current.clientWidth : 800;
    const H = () => fieldRef.current ? fieldRef.current.clientHeight : 360;
    let spawnTimer = 0;

    const loop = (now) => {
      const dt = Math.min(0.05, (now - last) / 1000);
      last = now;
      spawnTimer -= dt;
      if (spawnTimer <= 0) {
        spawnTimer = 0.45 + Math.random() * 0.4;
        const w = W();
        const newSticker = {
          id: idRef.current++,
          x: 30 + Math.random() * (w - 100),
          y: -50,
          vx: (Math.random() - 0.5) * 60,
          vy: 80 + Math.random() * 60,
          rot: Math.random() * 360,
          vrot: (Math.random() - 0.5) * 240,
          emoji: EMOJIS[Math.floor(Math.random() * EMOJIS.length)],
          bg: [T.accent, T.accent2, T.bg, T.tape][Math.floor(Math.random() * 4)],
          popped: false,
        };
        setStickers(s => [...s, newSticker]);
      }
      const h = H();
      setStickers(s => {
        const next = [];
        let extraMissed = 0;
        for (const p of s) {
          if (p.popped) { if (now - p.poppedAt < 350) next.push(p); continue; }
          const ny = p.y + p.vy * dt;
          const nx = p.x + p.vx * dt;
          if (ny > h + 60) { extraMissed++; continue; }
          next.push({ ...p, x: nx, y: ny, rot: p.rot + p.vrot * dt });
        }
        if (extraMissed) setMissed(m => m + extraMissed);
        return next;
      });
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [running, T]);

  // timer
  React.useEffect(() => {
    if (!running) return;
    if (time <= 0) {
      setRunning(false);
      setStickers([]);
      if (score > best) {
        localStorage.setItem('sp_best', String(score));
        setBest(score);
      }
      return;
    }
    const t = setTimeout(() => setTime(s => s - 1), 1000);
    return () => clearTimeout(t);
  }, [running, time]);

  const start = () => {
    setScore(0); setMissed(0); setStickers([]); setTime(30); setRunning(true);
  };

  const popSticker = (p, e) => {
    e.stopPropagation();
    setStickers(s => s.map(q => q.id === p.id ? { ...q, popped: true, poppedAt: performance.now() } : q));
    setScore(n => n + 1);
    if (window.__sp_playSound) window.__sp_playSound('pop');
    if (window.__sp_burstConfetti) {
      const r = e.currentTarget.getBoundingClientRect();
      window.__sp_burstConfetti(r.left + r.width/2, r.top + r.height/2, p.bg);
    }
  };

  return (
    <div style={{margin:'0 32px 56px'}}>
      <div style={{display:'flex', alignItems:'baseline', gap:14, marginBottom: 24, flexWrap:'wrap'}}>
        <h2 style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:72, margin:0, letterSpacing:'-0.04em'}}>STICKER CATCHER</h2>
        <PeelSticker t={T} bg={T.accent2} color="#fff" rotate={-4} fontSize={11}>♥ MINI-GAME</PeelSticker>
        <PeelSticker t={T} bg={T.accent} rotate={3} fontSize={11}>30 SEC</PeelSticker>
      </div>

      <ScrapBox t={T} bg={T.bg} rotate={-0.5} hoverable={false} style={{padding: 0, position:'relative', overflow:'hidden'}}>
        <Tape rotate={-3} color={T.tape} w={120} style={{top:-12, left:'40%'}}/>

        {/* Scoreboard */}
        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr 1fr auto', gap:14, padding:'18px 22px', borderBottom:`2.5px solid ${T.ink}`, alignItems:'center'}}>
          <Stat T={T} F={F} label="TIME" value={time + 's'} c={time<=10?T.accent2:T.ink}/>
          <Stat T={T} F={F} label="SCORE" value={score} c={T.accent}/>
          <Stat T={T} F={F} label="MISSED" value={missed} c={T.accent2}/>
          <Stat T={T} F={F} label="BEST" value={best} c={T.ink}/>
          <button onClick={start} style={{
            padding:'12px 22px', background: running?T.bg:T.accent, color:T.ink,
            border:`2.5px solid ${T.ink}`, boxShadow:`4px 4px 0 0 ${T.ink}`,
            fontFamily:F.display, fontWeight:F.dispWt, fontSize:14, letterSpacing:'0.06em', textTransform:'uppercase', cursor:'pointer',
            transform: running ? 'translate(-1px,-1px)' : 'none',
          }}>{running ? '↻ RESTART' : (time === 0 || score === 0) ? '▶ PLAY' : '▶ PLAY AGAIN'}</button>
        </div>

        {/* Field */}
        <div ref={fieldRef} style={{position:'relative', height: 380, background: `${T.ink}06`, overflow:'hidden', cursor:'crosshair'}}>
          {/* idle/end overlay */}
          {!running && (
            <div style={{position:'absolute', inset:0, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', textAlign:'center', padding:20}}>
              {time === 0 ? (
                <>
                  <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:64, letterSpacing:'-0.04em', lineHeight:0.95}}>
                    {score >= best && score > 0 ? 'NEW BEST!' : 'TIME!'}
                  </div>
                  <div style={{fontFamily:F.hand, fontSize: 30, color: T.accent2, marginTop:8}}>you caught {score} sticker{score===1?'':'s'} ✿</div>
                  <div style={{fontFamily:F.body, fontSize:13, opacity:0.6, marginTop:6}}>missed {missed}, best {Math.max(best, score)}</div>
                </>
              ) : (
                <>
                  <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:64, letterSpacing:'-0.04em', lineHeight:0.95}}>CATCH THE STICKERS</div>
                  <div style={{fontFamily:F.hand, fontSize: 26, color: T.accent2, marginTop:6}}>↳ click them before they fall off ◌</div>
                </>
              )}
            </div>
          )}

          {/* falling stickers */}
          {stickers.map(p => (
            <button
              key={p.id}
              onClick={(e) => !p.popped && popSticker(p, e)}
              style={{
                position:'absolute', left: p.x, top: p.y,
                transform: `translate(-50%, -50%) rotate(${p.rot}deg) scale(${p.popped?1.6:1})`,
                opacity: p.popped ? 0 : 1,
                width: 48, height: 48, padding: 0,
                background: p.bg,
                color: T.ink,
                border:`2.5px solid ${T.ink}`,
                borderRadius: '50%',
                boxShadow:`3px 3px 0 0 ${T.ink}`,
                fontFamily: F.display, fontWeight: F.dispWt, fontSize: 22,
                cursor: 'pointer', display:'flex', alignItems:'center', justifyContent:'center',
                transition: p.popped ? 'transform .35s ease-out, opacity .35s' : 'none',
              }}>{p.emoji}</button>
          ))}
        </div>
      </ScrapBox>
    </div>
  );
}

function Stat({ T, F, label, value, c }) {
  return (
    <div>
      <div style={{fontSize:10, fontWeight:800, letterSpacing:'0.18em', textTransform:'uppercase', opacity:0.55}}>{label}</div>
      <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:30, letterSpacing:'-0.02em', color: c, marginTop:2}}>{value}</div>
    </div>
  );
}

window.StickerGame = StickerGame;
