// Two more mini-games — Coin Maze + Tower Stack
// Both styled to match the scrapbook aesthetic.

// ===== COIN MAZE =====
function CoinMaze({ T, F }) {
  const COLS = 15, ROWS = 11, CELL = 32;
  const W = COLS * CELL, H = ROWS * CELL;

  // Hand-built mazes (1 = wall, 0 = path)
  const mazes = [
    [
      "111111111111111",
      "100000010000001",
      "101110010111101",
      "100010000100001",
      "111010111101111",
      "100000000000001",
      "101111101011101",
      "100000101000001",
      "101110101110101",
      "100010000010001",
      "111111111111111",
    ],
    [
      "111111111111111",
      "100010000100001",
      "101010111101101",
      "100000100000101",
      "111011101110101",
      "100000000010001",
      "101111111011111",
      "100000001000001",
      "101110101110101",
      "100010000010001",
      "111111111111111",
    ],
    [
      "111111111111111",
      "100000000000001",
      "101111101111101",
      "100000101000001",
      "111110101011111",
      "100000000000001",
      "111010111010111",
      "100010000010001",
      "101110111011101",
      "100000000000001",
      "111111111111111",
    ],
  ];

  const [level, setLevel] = React.useState(0);
  const [player, setPlayer] = React.useState({ x: 1, y: 1 });
  const [coins, setCoins] = React.useState([]);
  const [moves, setMoves] = React.useState(0);
  const [won, setWon] = React.useState(false);

  function buildLevel(idx) {
    const m = mazes[idx % mazes.length];
    const cs = [];
    for (let r = 0; r < ROWS; r++) for (let c = 0; c < COLS; c++) {
      if (m[r][c] === '0' && !(r === 1 && c === 1)) cs.push({ x: c, y: r });
    }
    setCoins(cs);
    setPlayer({ x: 1, y: 1 });
    setMoves(0);
    setWon(false);
  }

  React.useEffect(() => { buildLevel(level); }, [level]);

  const grid = mazes[level % mazes.length];

  // swipe to move on touch
  const touchRef = React.useRef(null);
  const onTouchStart = (e) => { const t = e.touches[0]; touchRef.current = { x: t.clientX, y: t.clientY }; };
  const onTouchEnd = (e) => {
    if (!touchRef.current) return;
    const t = e.changedTouches[0];
    const dx = t.clientX - touchRef.current.x, dy = t.clientY - touchRef.current.y;
    if (Math.max(Math.abs(dx), Math.abs(dy)) < 22) return;
    const key = Math.abs(dx) > Math.abs(dy) ? (dx > 0 ? 'ArrowRight' : 'ArrowLeft') : (dy > 0 ? 'ArrowDown' : 'ArrowUp');
    window.dispatchEvent(new KeyboardEvent('keydown', { key }));
  };

  React.useEffect(() => {
    const onKey = (e) => {
      if (won) return;
      const map = { ArrowUp:[0,-1], ArrowDown:[0,1], ArrowLeft:[-1,0], ArrowRight:[1,0], w:[0,-1], s:[0,1], a:[-1,0], d:[1,0] };
      const m = map[e.key];
      if (!m) return;
      e.preventDefault();
      setPlayer(p => {
        const nx = p.x + m[0], ny = p.y + m[1];
        if (nx < 0 || ny < 0 || nx >= COLS || ny >= ROWS) return p;
        if (grid[ny][nx] === '1') return p;
        setMoves(mv => mv + 1);
        setCoins(cs => {
          const next = cs.filter(c => !(c.x === nx && c.y === ny));
          if (next.length === 0) {
            setTimeout(() => {
              if (window.__sp_burstConfetti) window.__sp_burstConfetti();
              if (level + 1 >= mazes.length) setWon(true);
              else setLevel(l => l + 1);
            }, 100);
          }
          return next;
        });
        return { x: nx, y: ny };
      });
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [grid, level, won]);

  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'}}>coin maze</h2>
        <PeelSticker t={T} bg={T.accent} rotate={-3} fontSize={11}>♥ EAT EVERY COIN</PeelSticker>
        <PeelSticker t={T} bg={T.accent2} color="#fff" rotate={4} fontSize={11}>3 LEVELS</PeelSticker>
      </div>

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

        <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:12, flexWrap:'wrap', gap:8}}>
          <div style={{fontFamily:F.mono, fontSize:11, fontWeight:800, letterSpacing:'0.18em', textTransform:'uppercase', opacity:0.7}}>
            LEVEL {level + 1} / {mazes.length} · {coins.length} coins left · {moves} moves
          </div>
          <button onClick={() => buildLevel(level)} style={{
            padding:'6px 14px', background:T.accent, color:T.ink,
            border:`2.5px solid ${T.ink}`, boxShadow:`3px 3px 0 0 ${T.ink}`,
            fontFamily:F.display, fontWeight:F.dispWt, fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer',
          }}>↻ RESET</button>
        </div>

        <div onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} style={{
          display:'grid', placeItems:'center',
          background: T.tape, padding: 12, border:`2.5px solid ${T.ink}`,
          position:'relative', touchAction:'none',
        }}>
          <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{maxWidth: W, display:'block'}}>
            {/* walls */}
            {grid.map((row, r) => row.split('').map((cell, c) => cell === '1' ? (
              <rect key={`w${r}${c}`} x={c*CELL} y={r*CELL} width={CELL} height={CELL}
                fill={T.ink} stroke={T.bg} strokeWidth="1.5"/>
            ) : null))}
            {/* coins */}
            {coins.map((co, i) => (
              <g key={i} transform={`translate(${co.x*CELL + CELL/2}, ${co.y*CELL + CELL/2})`}>
                <circle r="6" fill={T.accent} stroke={T.ink} strokeWidth="2"/>
                <text x="0" y="3" textAnchor="middle" fontSize="8" fontWeight="900" fill={T.ink}>$</text>
              </g>
            ))}
            {/* player */}
            <g transform={`translate(${player.x*CELL + CELL/2}, ${player.y*CELL + CELL/2})`}
              style={{transition:'transform 0.1s'}}>
              <circle r="11" fill={T.accent2} stroke={T.ink} strokeWidth="2.5"/>
              <circle cx="-3" cy="-3" r="1.8" fill={T.bg}/>
              <circle cx="3" cy="-3" r="1.8" fill={T.bg}/>
              <path d="M -4 3 Q 0 6 4 3" stroke={T.bg} strokeWidth="1.5" fill="none" strokeLinecap="round"/>
            </g>
          </svg>

          {won && (
            <div style={{position:'absolute', inset:0, background:`${T.ink}f0`, color:T.bg, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:10}}>
              <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:60, letterSpacing:'-0.04em', color:T.accent}}>YOU WIN!</div>
              <div style={{fontFamily:F.hand, fontSize:24}}>all coins collected in {moves} moves ★</div>
              <button onClick={() => { setLevel(0); }} style={{
                marginTop:6, padding:'10px 20px', background:T.accent, color:T.ink,
                border:`2.5px solid ${T.bg}`, boxShadow:`4px 4px 0 0 ${T.bg}`,
                fontFamily:F.display, fontWeight:F.dispWt, fontSize:13, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer',
              }}>↻ PLAY AGAIN</button>
            </div>
          )}
        </div>

        <div style={{textAlign:'center', marginTop:14, fontFamily:F.hand, fontSize:20, color:T.accent2}}>
          ↳ arrow keys / WASD — eat every coin to clear the level ★
        </div>
      </ScrapBox>
    </div>
  );
}

// ===== TOWER STACK =====
function TowerStack({ T, F }) {
  const W = 480, H = 360;
  const cvs = React.useRef(null);
  const stateRef = React.useRef({});
  const [score, setScore] = React.useState(0);
  const [best, setBest] = React.useState(() => Number(localStorage.getItem('sp_tower_best') || 0));
  const [over, setOver] = React.useState(false);
  const [started, setStarted] = React.useState(false);

  function reset() {
    stateRef.current = {
      blocks: [{ x: W/2 - 90, y: H - 30, w: 180, color: T.accent }],
      current: { x: 0, y: H - 60, w: 180, dir: 1, speed: 2.4, color: T.accent2 },
    };
    setScore(0); setOver(false); setStarted(true);
  }

  React.useEffect(() => { reset(); }, []); // eslint-disable-line

  function drop() {
    const s = stateRef.current;
    if (!s.current || over) return;
    const top = s.blocks[s.blocks.length - 1];
    const cur = s.current;
    const overlapStart = Math.max(cur.x, top.x);
    const overlapEnd = Math.min(cur.x + cur.w, top.x + top.w);
    const overlap = overlapEnd - overlapStart;
    if (overlap <= 0) {
      setOver(true);
      const newBest = Math.max(best, score);
      setBest(newBest); localStorage.setItem('sp_tower_best', String(newBest));
      if (window.__sp_playSound) window.__sp_playSound('pop');
      return;
    }
    s.blocks.push({ x: overlapStart, y: cur.y, w: overlap, color: cur.color });
    setScore(sc => sc + 1);
    if (window.__sp_playSound) window.__sp_playSound('pop');
    // shift camera up (blocks move down visually)
    if (s.blocks.length > 4) {
      for (const b of s.blocks) b.y += 30;
    }
    // next block
    const palette = [T.accent, T.accent2, T.tape, T.ink];
    s.current = {
      x: Math.random() < 0.5 ? -overlap : W,
      y: Math.min(s.blocks[s.blocks.length-1].y - 30, H - 60),
      w: overlap,
      dir: Math.random() < 0.5 ? 1 : -1,
      speed: 2.4 + score * 0.1,
      color: palette[s.blocks.length % palette.length],
    };
  }

  React.useEffect(() => {
    const onKey = (e) => {
      if (e.code === 'Space') { e.preventDefault(); over ? reset() : drop(); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  });

  React.useEffect(() => {
    if (!started || over) return;
    let raf;
    const ctx = cvs.current.getContext('2d');
    const tick = () => {
      const s = stateRef.current;
      // move current block
      if (s.current) {
        s.current.x += s.current.dir * s.current.speed;
        if (s.current.x < -s.current.w/2) s.current.dir = 1;
        if (s.current.x + s.current.w/2 > W) s.current.dir = -1;
      }
      // draw
      ctx.fillStyle = T.bg; ctx.fillRect(0,0,W,H);
      // grain
      ctx.fillStyle = `${T.ink}10`;
      for (let i = 0; i < 40; i++) ctx.fillRect((i*53)%W, (i*73)%H, 1, 1);
      // shadows under each block
      for (const b of s.blocks) {
        ctx.fillStyle = `${T.ink}20`;
        ctx.fillRect(b.x + 4, b.y + 4, b.w, 26);
        ctx.fillStyle = b.color;
        ctx.fillRect(b.x, b.y, b.w, 26);
        ctx.strokeStyle = T.ink; ctx.lineWidth = 2.5;
        ctx.strokeRect(b.x, b.y, b.w, 26);
      }
      // current
      if (s.current) {
        ctx.fillStyle = `${T.ink}20`;
        ctx.fillRect(s.current.x + 4, s.current.y + 4, s.current.w, 26);
        ctx.fillStyle = s.current.color;
        ctx.fillRect(s.current.x, s.current.y, s.current.w, 26);
        ctx.strokeStyle = T.ink; ctx.lineWidth = 2.5;
        ctx.strokeRect(s.current.x, s.current.y, s.current.w, 26);
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [started, over, T]);

  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'}}>tower stack</h2>
        <PeelSticker t={T} bg={T.accent2} color="#fff" rotate={-4} fontSize={11}>♥ TAP TO STACK</PeelSticker>
        <PeelSticker t={T} bg={T.accent} rotate={3} fontSize={11}>BUILD HIGHER</PeelSticker>
      </div>

      <ScrapBox t={T} bg={T.bg} rotate={-0.4} hoverable={false} style={{padding:'24px 28px', position:'relative'}}>
        <Tape rotate={3} color={T.tape} w={120} style={{top:-12, right:'30%'}}/>

        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr auto', gap:16, alignItems:'end', marginBottom: 14}}>
          <div>
            <div style={{fontSize:10, fontWeight:800, letterSpacing:'0.18em', textTransform:'uppercase', opacity:0.55}}>HEIGHT</div>
            <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:36, color:T.accent}}>{score}</div>
          </div>
          <div>
            <div style={{fontSize:10, fontWeight:800, letterSpacing:'0.18em', textTransform:'uppercase', opacity:0.55}}>BEST</div>
            <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:36, color:T.ink}}>{best}</div>
          </div>
          <button onClick={reset} style={{
            padding:'10px 18px', background: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:13, letterSpacing:'0.06em', textTransform:'uppercase', cursor:'pointer',
          }}>↻ RESTART</button>
        </div>

        <div style={{position:'relative', maxWidth: W, margin:'0 auto'}} onClick={() => over ? reset() : drop()}>
          <canvas ref={cvs} width={W} height={H}
            style={{display:'block', width:'100%', border:`2.5px solid ${T.ink}`, cursor:'pointer'}}/>
          {over && (
            <div style={{position:'absolute', inset:0, background:`${T.ink}ee`, color:T.bg, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:10}}>
              <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:54, letterSpacing:'-0.04em'}}>GAME OVER</div>
              <div style={{fontFamily:F.hand, fontSize:24, color:T.accent}}>height: {score} · best: {best}</div>
              <button onClick={(e) => { e.stopPropagation(); reset(); }} style={{
                padding:'10px 20px', background:T.accent, color:T.ink,
                border:`2.5px solid ${T.bg}`, boxShadow:`4px 4px 0 0 ${T.bg}`,
                fontFamily:F.display, fontWeight:F.dispWt, fontSize:13, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer',
              }}>↻ TRY AGAIN</button>
            </div>
          )}
        </div>

        <div style={{textAlign:'center', marginTop:14, fontFamily:F.hand, fontSize:20, color:T.accent2}}>
          ↳ click or press SPACE to drop the block — line them up ★
        </div>
      </ScrapBox>
    </div>
  );
}

window.CoinMaze = CoinMaze;
window.TowerStack = TowerStack;
