// Family Computer — scrapbook-styled handheld with 3 mini-games.
// Original games (no ROMs): Brick Smash, Snake, Space Defender.

function FamilyComputer({ T, F }) {
  const [game, setGame] = React.useState('brick'); // brick | snake | space
  const [paused, setPaused] = React.useState(false);

  const games = [
    { id: 'brick', label: 'BRICK SMASH' },
    { id: 'snake', label: 'SNAKE' },
    { id: 'space', label: 'SPACE DEF.' },
  ];

  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'}}>family computer</h2>
        <PeelSticker t={T} bg={T.accent} rotate={-3} fontSize={11}>♥ 8-BIT VIBES</PeelSticker>
        <PeelSticker t={T} bg={T.accent2} color="#fff" rotate={4} fontSize={11}>3 GAMES</PeelSticker>
      </div>

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

        {/* Console body */}
        <div className="sp-fc-body" style={{
          background: T.ink, color: T.bg,
          border:`3px solid ${T.ink}`,
          boxShadow:`6px 6px 0 0 ${T.accent2}`,
          padding: 22,
          display:'grid',
          gridTemplateColumns: '160px 1fr 160px',
          gap: 22,
          alignItems:'center',
          maxWidth: 920, margin:'0 auto',
        }}>
          {/* LEFT — d-pad + cart selector */}
          <div style={{display:'flex', flexDirection:'column', alignItems:'center', gap:14}}>
            <DPad T={T} game={game}/>
            <div style={{fontFamily:F.mono, fontSize:9, fontWeight:700, letterSpacing:'0.18em', opacity:0.6}}>D-PAD / WASD</div>
          </div>

          {/* CENTER — screen */}
          <div className="sp-fc-screen">
            <div style={{
              background:'#000',
              border:`3px solid ${T.tape}`,
              padding: 8,
              boxShadow:`inset 0 0 0 2px ${T.ink}`,
              position:'relative',
            }}>
              <Screen T={T} F={F} game={game} paused={paused}/>
              {/* scanlines */}
              <div style={{
                position:'absolute', inset: 8, pointerEvents:'none',
                backgroundImage:`repeating-linear-gradient(0deg, rgba(0,0,0,0.18) 0 2px, transparent 2px 4px)`,
                mixBlendMode:'multiply',
              }}/>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', marginTop:10, gap:8, alignItems:'center'}}>
              <div style={{display:'flex', gap:6}}>
                {games.map(g => (
                  <button key={g.id} onClick={() => { setGame(g.id); setPaused(false); }}
                    style={{
                      padding:'6px 10px',
                      background: game === g.id ? T.accent : 'transparent',
                      color: game === g.id ? T.ink : T.bg,
                      border:`2px solid ${T.bg}`,
                      fontFamily: F.mono, fontSize:10, fontWeight:700, letterSpacing:'0.08em', cursor:'pointer',
                    }}>
                    {g.label}
                  </button>
                ))}
              </div>
              <button onClick={() => setPaused(p => !p)} style={{
                padding:'6px 14px', background: T.tape, color:T.ink,
                border:`2px solid ${T.bg}`, fontFamily:F.mono, fontSize:10, fontWeight:700, letterSpacing:'0.1em', cursor:'pointer',
              }}>{paused ? '▶ START' : '⏸ PAUSE'}</button>
            </div>
          </div>

          {/* RIGHT — A/B buttons */}
          <div style={{display:'flex', flexDirection:'column', alignItems:'center', gap:14}}>
            <div style={{display:'flex', gap:14, transform:'rotate(-15deg)'}}>
              <ABButton T={T} label="B" color={T.accent2} keyName="Shift"/>
              <ABButton T={T} label="A" color={T.accent} keyName=" "/>
            </div>
            <div style={{fontFamily:F.mono, fontSize:9, fontWeight:700, letterSpacing:'0.18em', opacity:0.6, textAlign:'center'}}>SPACE = A<br/>SHIFT = B</div>
          </div>

          {/* bottom logo */}
          <div style={{gridColumn:'1 / -1', display:'flex', justifyContent:'space-between', alignItems:'center', marginTop:6, paddingTop:14, borderTop:`2px dashed ${T.bg}33`}}>
            <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:14, letterSpacing:'0.18em', color:T.tape}}>FAMILY COMPUTER</div>
            <div style={{fontFamily:F.mono, fontSize:10, fontWeight:700, letterSpacing:'0.12em', color:T.bg, opacity:0.5}}>HAND-MADE · NOT NINTENDO</div>
          </div>
        </div>

        <div style={{textAlign:'center', marginTop:14, fontFamily:F.hand, fontSize:20, color:T.ink}}>
          ↳ original 8-bit minis · click START to play, switch carts above ★
        </div>
      </ScrapBox>
    </div>
  );
}

// — synthetic key dispatch so on-screen controls drive the keyboard games
function fcFireKey(type, key) {
  window.dispatchEvent(new KeyboardEvent(type, { key, code: key === ' ' ? 'Space' : key, bubbles: true }));
}

// — D-pad: touch + mouse drive games via synthetic key events; also shows live key state
function DPad({ T, game }) {
  const [held, setHeld] = React.useState({});
  React.useEffect(() => {
    const map = {ArrowUp:'up',ArrowDown:'down',ArrowLeft:'left',ArrowRight:'right',w:'up',s:'down',a:'left',d:'right',W:'up',S:'down',A:'left',D:'right'};
    const dn = e => { if (map[e.key]) setHeld(h => ({...h, [map[e.key]]: true})); };
    const up = e => { if (map[e.key]) setHeld(h => ({...h, [map[e.key]]: false})); };
    window.addEventListener('keydown', dn); window.addEventListener('keyup', up);
    return () => { window.removeEventListener('keydown', dn); window.removeEventListener('keyup', up); };
  }, []);
  const seg = (active) => ({
    width: 40, height: 40, padding: 0, background: active ? T.accent : '#222',
    border:`2px solid #000`, boxShadow: active ? `inset 0 0 0 2px ${T.ink}` : 'none',
    touchAction:'none', cursor:'pointer',
  });
  const press = (dir, key) => (e) => { e.preventDefault(); setHeld(h => ({...h, [dir]: true})); fcFireKey('keydown', key); };
  const release = (dir, key) => (e) => { e.preventDefault(); setHeld(h => ({...h, [dir]: false})); fcFireKey('keyup', key); };
  const Cell = ({ dir, k }) => (
    <button
      onPointerDown={press(dir, k)} onPointerUp={release(dir, k)} onPointerLeave={release(dir, k)} onPointerCancel={release(dir, k)}
      onContextMenu={e => e.preventDefault()}
      style={seg(held[dir])} aria-label={dir}/>
  );
  const blank = { width:40, height:40, background:'#222', border:'2px solid #000' };
  return (
    <div style={{display:'grid', gridTemplateColumns:'repeat(3, 40px)', gridTemplateRows:'repeat(3, 40px)', gap:2}}>
      <div/><Cell dir="up" k="ArrowUp"/><div/>
      <Cell dir="left" k="ArrowLeft"/><div style={blank}/><Cell dir="right" k="ArrowRight"/>
      <div/><Cell dir="down" k="ArrowDown"/><div/>
    </div>
  );
}

function ABButton({ T, label, color, keyName }) {
  const [down, setDown] = React.useState(false);
  const press = (e) => { e.preventDefault(); setDown(true); fcFireKey('keydown', keyName); };
  const release = (e) => { e.preventDefault(); setDown(false); fcFireKey('keyup', keyName); };
  return (
    <button
      onPointerDown={press} onPointerUp={release} onPointerLeave={release} onPointerCancel={release}
      onContextMenu={e => e.preventDefault()}
      style={{
        width:54, height:54, borderRadius:'50%', padding:0,
        background: color, border:'3px solid #000',
        boxShadow: down ? `inset 0 2px 4px 0 rgba(0,0,0,0.4)` : `inset 0 -4px 0 0 rgba(0,0,0,0.25), 3px 3px 0 0 ${T.tape}`,
        transform: down ? 'translateY(2px)' : 'none',
        display:'flex', alignItems:'center', justifyContent:'center',
        fontFamily:'system-ui', fontWeight:900, fontSize:22, color:'#000',
        touchAction:'none', cursor:'pointer',
      }}>{label}</button>
  );
}

// — Screen dispatcher
function Screen({ T, F, game, paused }) {
  const W = 320, H = 240;
  if (game === 'brick') return <BrickSmash T={T} F={F} W={W} H={H} paused={paused}/>;
  if (game === 'snake') return <SnakeGame T={T} F={F} W={W} H={H} paused={paused}/>;
  if (game === 'space') return <SpaceGame T={T} F={F} W={W} H={H} paused={paused}/>;
  return null;
}

// === BRICK SMASH ===
function BrickSmash({ T, F, W, H, paused }) {
  const cvs = React.useRef(null);
  const stateRef = React.useRef({});
  const [score, setScore] = React.useState(0);
  const [lives, setLives] = React.useState(3);
  const [over, setOver] = React.useState(null);

  React.useEffect(() => {
    const c = cvs.current.getContext('2d');
    const cols = 10, rows = 5, bw = 28, bh = 12, padX = 20, padY = 24;
    const bricks = [];
    for (let r = 0; r < rows; r++) for (let col = 0; col < cols; col++)
      bricks.push({ x: padX + col*(bw+2), y: padY + r*(bh+4), alive: true, row: r });
    stateRef.current = {
      paddle: { x: W/2 - 32, y: H - 18, w: 64, h: 6 },
      ball: { x: W/2, y: H - 36, vx: 1.6, vy: -1.6, r: 4 },
      bricks, keys: {},
    };
    setScore(0); setLives(3); setOver(null);
  }, [game_key()]);

  function game_key() { return 'brick'; }

  React.useEffect(() => {
    const dn = e => { stateRef.current.keys[e.key] = true; };
    const up = e => { stateRef.current.keys[e.key] = false; };
    window.addEventListener('keydown', dn); window.addEventListener('keyup', up);
    return () => { window.removeEventListener('keydown', dn); window.removeEventListener('keyup', up); };
  }, []);

  React.useEffect(() => {
    if (paused || over) return;
    let raf;
    const c = cvs.current.getContext('2d');
    const tick = () => {
      const s = stateRef.current;
      // input
      const sp = 4;
      if (s.keys['ArrowLeft'] || s.keys['a'] || s.keys['A']) s.paddle.x -= sp;
      if (s.keys['ArrowRight'] || s.keys['d'] || s.keys['D']) s.paddle.x += sp;
      s.paddle.x = Math.max(4, Math.min(W - s.paddle.w - 4, s.paddle.x));
      // ball
      s.ball.x += s.ball.vx; s.ball.y += s.ball.vy;
      if (s.ball.x < 4 || s.ball.x > W-4) s.ball.vx *= -1;
      if (s.ball.y < 4) s.ball.vy *= -1;
      // paddle collide
      if (s.ball.y + s.ball.r >= s.paddle.y && s.ball.y < s.paddle.y + s.paddle.h
        && s.ball.x >= s.paddle.x && s.ball.x <= s.paddle.x + s.paddle.w) {
        s.ball.vy = -Math.abs(s.ball.vy);
        s.ball.vx += ((s.ball.x - (s.paddle.x + s.paddle.w/2)) / (s.paddle.w/2)) * 1.4;
        s.ball.vx = Math.max(-3, Math.min(3, s.ball.vx));
      }
      // brick collide
      for (const b of s.bricks) {
        if (!b.alive) continue;
        if (s.ball.x > b.x && s.ball.x < b.x + 28 && s.ball.y > b.y && s.ball.y < b.y + 12) {
          b.alive = false; s.ball.vy *= -1;
          setScore(sc => sc + (5 - b.row) * 10);
        }
      }
      // lose life
      if (s.ball.y > H) {
        setLives(l => {
          if (l <= 1) { setOver('lose'); return 0; }
          return l - 1;
        });
        s.ball.x = W/2; s.ball.y = H - 36; s.ball.vx = 1.6; s.ball.vy = -1.6;
      }
      // win
      if (s.bricks.every(b => !b.alive)) setOver('win');
      // draw
      c.fillStyle = '#0d1414'; c.fillRect(0,0,W,H);
      // bricks
      const colors = [T.accent2, T.accent, T.tape, T.accent, T.accent2];
      for (const b of s.bricks) if (b.alive) {
        c.fillStyle = colors[b.row]; c.fillRect(b.x, b.y, 28, 12);
        c.fillStyle = 'rgba(255,255,255,0.25)'; c.fillRect(b.x, b.y, 28, 2);
      }
      // paddle
      c.fillStyle = T.bg; c.fillRect(s.paddle.x, s.paddle.y, s.paddle.w, s.paddle.h);
      // ball
      c.fillStyle = T.bg; c.fillRect(s.ball.x-4, s.ball.y-4, 8, 8);
      // HUD
      c.fillStyle = T.tape; c.font = 'bold 11px monospace';
      c.fillText(`SCORE ${score}`, 6, 12);
      c.fillText(`♥ ${lives}`, W - 36, 12);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [paused, over, score, lives]);

  return (
    <div style={{position:'relative'}}>
      <canvas ref={cvs} width={W} height={H} style={{display:'block', width: '100%', imageRendering:'pixelated'}}/>
      <Overlay T={T} F={F} state={over ? (over==='win'?'WIN!':'GAME OVER') : (paused ? 'PRESS START' : null)}
        sub={over ? `Final: ${score}` : (paused ? 'BRICK SMASH · ←/→ to move' : null)}/>
    </div>
  );
}

// === SNAKE ===
function SnakeGame({ T, F, W, H, paused }) {
  const cvs = React.useRef(null);
  const stateRef = React.useRef({});
  const [score, setScore] = React.useState(0);
  const [over, setOver] = React.useState(false);

  const CELL = 10, COLS = 32, ROWS = 24;
  React.useEffect(() => {
    stateRef.current = {
      snake: [{x:8,y:12},{x:7,y:12},{x:6,y:12}],
      dir: {x:1,y:0},
      nextDir: {x:1,y:0},
      food: { x: 18, y: 12 },
      tickAcc: 0,
    };
    setScore(0); setOver(false);
  }, []);

  React.useEffect(() => {
    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],W:[0,-1],S:[0,1],A:[-1,0],D:[1,0]};
    const dn = e => {
      if (!map[e.key]) return;
      const [x,y] = map[e.key];
      const cur = stateRef.current.dir;
      if (cur.x === -x && cur.y === -y) return;
      stateRef.current.nextDir = {x,y};
    };
    window.addEventListener('keydown', dn);
    return () => window.removeEventListener('keydown', dn);
  }, []);

  React.useEffect(() => {
    if (paused || over) return;
    let raf, last = performance.now();
    const c = cvs.current.getContext('2d');
    const STEP = 110;
    const loop = (now) => {
      const s = stateRef.current;
      s.tickAcc += now - last; last = now;
      while (s.tickAcc > STEP) {
        s.tickAcc -= STEP;
        s.dir = s.nextDir;
        const head = { x: s.snake[0].x + s.dir.x, y: s.snake[0].y + s.dir.y };
        if (head.x < 0 || head.x >= COLS || head.y < 0 || head.y >= ROWS || s.snake.some(p => p.x===head.x && p.y===head.y)) {
          setOver(true); break;
        }
        s.snake.unshift(head);
        if (head.x === s.food.x && head.y === s.food.y) {
          setScore(sc => sc + 10);
          s.food = { x: Math.floor(Math.random()*COLS), y: Math.floor(Math.random()*ROWS) };
        } else s.snake.pop();
      }
      // draw
      c.fillStyle = '#0d1414'; c.fillRect(0,0,W,H);
      // grid dots
      c.fillStyle = 'rgba(255,255,255,0.04)';
      for (let i=0;i<COLS;i+=2) for (let j=0;j<ROWS;j+=2) c.fillRect(i*CELL+4, j*CELL+4, 2, 2);
      // food
      c.fillStyle = T.accent2;
      c.fillRect(s.food.x*CELL+1, s.food.y*CELL+1, CELL-2, CELL-2);
      // snake
      s.snake.forEach((p, i) => {
        c.fillStyle = i === 0 ? T.bg : T.accent;
        c.fillRect(p.x*CELL+1, p.y*CELL+1, CELL-2, CELL-2);
      });
      // HUD
      c.fillStyle = T.tape; c.font = 'bold 11px monospace';
      c.fillText(`SCORE ${score}`, 6, 12);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [paused, over, score]);

  return (
    <div style={{position:'relative'}}>
      <canvas ref={cvs} width={W} height={H} style={{display:'block', width:'100%', imageRendering:'pixelated'}}/>
      <Overlay T={T} F={F} state={over ? 'GAME OVER' : (paused ? 'PRESS START' : null)}
        sub={over ? `Final: ${score}` : (paused ? 'SNAKE · arrows or WASD' : null)}/>
    </div>
  );
}

// === SPACE DEFENDER ===
function SpaceGame({ T, F, W, H, paused }) {
  const cvs = React.useRef(null);
  const stateRef = React.useRef({});
  const [score, setScore] = React.useState(0);
  const [lives, setLives] = React.useState(3);
  const [over, setOver] = React.useState(null);

  React.useEffect(() => {
    stateRef.current = {
      ship: { x: W/2, y: H - 24, w: 18, h: 12 },
      bullets: [], enemies: [], particles: [], keys: {},
      lastShot: 0, lastSpawn: 0,
    };
    setScore(0); setLives(3); setOver(null);
  }, []);

  React.useEffect(() => {
    const dn = e => { stateRef.current.keys[e.key] = true; };
    const up = e => { stateRef.current.keys[e.key] = false; };
    window.addEventListener('keydown', dn); window.addEventListener('keyup', up);
    return () => { window.removeEventListener('keydown', dn); window.removeEventListener('keyup', up); };
  }, []);

  React.useEffect(() => {
    if (paused || over) return;
    let raf;
    const c = cvs.current.getContext('2d');
    const tick = () => {
      const s = stateRef.current; const now = performance.now();
      // input
      if (s.keys['ArrowLeft']||s.keys['a']||s.keys['A']) s.ship.x -= 3;
      if (s.keys['ArrowRight']||s.keys['d']||s.keys['D']) s.ship.x += 3;
      s.ship.x = Math.max(8, Math.min(W-8, s.ship.x));
      if ((s.keys[' ']||s.keys['Space']||s.keys['Shift']) && now - s.lastShot > 220) {
        s.bullets.push({ x: s.ship.x, y: s.ship.y - 6, vy: -4 });
        s.lastShot = now;
      }
      // spawn enemies
      if (now - s.lastSpawn > 700) {
        s.enemies.push({ x: 16 + Math.random()*(W-32), y: -10, vy: 0.6 + Math.random()*0.7, t: Math.random()*Math.PI*2 });
        s.lastSpawn = now;
      }
      // step
      s.bullets = s.bullets.filter(b => { b.y += b.vy; return b.y > -10; });
      s.enemies.forEach(e => { e.y += e.vy; e.t += 0.08; e.x += Math.sin(e.t) * 0.6; });
      s.particles = s.particles.filter(p => { p.x+=p.vx; p.y+=p.vy; p.life -= 1; return p.life > 0; });
      // collisions: bullets x enemies
      for (const b of s.bullets) {
        for (const e of s.enemies) {
          if (!e.dead && Math.abs(b.x - e.x) < 8 && Math.abs(b.y - e.y) < 8) {
            e.dead = true; b.dead = true;
            setScore(sc => sc + 10);
            for (let i=0;i<6;i++) s.particles.push({x:e.x,y:e.y,vx:(Math.random()-0.5)*3,vy:(Math.random()-0.5)*3,life:18});
          }
        }
      }
      s.bullets = s.bullets.filter(b => !b.dead);
      // enemy x ship / fall off
      let lost = 0;
      s.enemies = s.enemies.filter(e => {
        if (e.dead) return false;
        if (Math.abs(e.x - s.ship.x) < 12 && Math.abs(e.y - s.ship.y) < 10) { lost++; return false; }
        if (e.y > H + 10) { lost++; return false; }
        return true;
      });
      if (lost) {
        setLives(l => {
          const nl = l - lost;
          if (nl <= 0) { setOver('lose'); return 0; }
          return nl;
        });
      }
      // draw
      c.fillStyle = '#0d1414'; c.fillRect(0,0,W,H);
      // stars
      c.fillStyle = 'rgba(255,255,255,0.4)';
      for (let i=0;i<24;i++) {
        const sx = (i*53 + Math.floor(now/30)) % W;
        const sy = (i*37) % H;
        c.fillRect(sx, sy, 1, 1);
      }
      // ship
      c.fillStyle = T.bg;
      c.fillRect(s.ship.x-9, s.ship.y, 18, 4);
      c.fillRect(s.ship.x-3, s.ship.y-6, 6, 6);
      c.fillStyle = T.accent;
      c.fillRect(s.ship.x-1, s.ship.y-3, 2, 2);
      // thruster
      c.fillStyle = T.accent2;
      c.fillRect(s.ship.x-2, s.ship.y+4, 4, 3 + Math.floor(Math.random()*3));
      // bullets
      c.fillStyle = T.tape;
      for (const b of s.bullets) c.fillRect(b.x-1, b.y-3, 2, 6);
      // enemies
      for (const e of s.enemies) {
        c.fillStyle = T.accent2;
        c.fillRect(e.x-7, e.y-4, 14, 8);
        c.fillStyle = T.bg;
        c.fillRect(e.x-3, e.y-1, 2, 2); c.fillRect(e.x+1, e.y-1, 2, 2);
      }
      // particles
      for (const p of s.particles) {
        c.fillStyle = T.accent;
        c.fillRect(p.x, p.y, 2, 2);
      }
      // HUD
      c.fillStyle = T.tape; c.font = 'bold 11px monospace';
      c.fillText(`SCORE ${score}`, 6, 12);
      c.fillText(`♥ ${lives}`, W - 36, 12);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [paused, over, score, lives]);

  return (
    <div style={{position:'relative'}}>
      <canvas ref={cvs} width={W} height={H} style={{display:'block', width:'100%', imageRendering:'pixelated'}}/>
      <Overlay T={T} F={F} state={over ? 'GAME OVER' : (paused ? 'PRESS START' : null)}
        sub={over ? `Final: ${score}` : (paused ? 'SPACE DEF. · ←/→ move · SPACE fire' : null)}/>
    </div>
  );
}

function Overlay({ T, F, state, sub }) {
  if (!state) return null;
  return (
    <div style={{
      position:'absolute', inset:0, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center',
      background:'rgba(0,0,0,0.7)', color:T.bg, gap:6, pointerEvents:'none',
    }}>
      <div style={{fontFamily:F.display, fontWeight:F.dispWt, fontSize:32, letterSpacing:'-0.04em', color: T.accent}}>{state}</div>
      {sub && <div style={{fontFamily:'monospace', fontSize:11, fontWeight:700, letterSpacing:'0.1em', color:T.bg, opacity:0.85}}>{sub}</div>}
    </div>
  );
}

window.FamilyComputer = FamilyComputer;
