import React, { useEffect, useRef, useState } from 'react';

// High-res 2D RPG tavern — 32px LPC "Base Assets" tiles (CC-BY-SA) + animated 64px characters.
const T = 32, W = 512, H = 352;
const L = '/scene2d/lpc/';
const SRC = {
  inside: L + 'inside.png', floors: L + 'castlefloors.png', vic: L + 'victoria.png', barrel: L + 'barrel.png',
  princess: L + 'princess.png', soldier: L + 'soldier.png', soldier2: L + 'soldier_altcolor.png', bartender: L + 'bartender.png',
};
// tile picks [col,row] (32px)
const WALL = [0, 4], FLOOR = [0, 7], DOOR = [[8, 1], [9, 1]];
const RUG = { tl: [1, 6], t: [2, 6], tr: [3, 6], l: [1, 7], c: [2, 7], r: [3, 7], bl: [1, 8], b: [2, 8], br: [3, 8] };
const TABLE = [4, 3], CHAIR = [6, 0], CHAIR_R = [7, 0], PLANT = [2, 3], LAMP = [0, 3], VASE = [3, 3], CURTAIN = [8, 0], CURTAIN2 = [9, 0];

function tile(ctx, s, c, r, dx, dy, tw = T, th = T) { ctx.drawImage(s, c * T, r * T, tw, th, dx, dy, tw, th); }
// LPC character: down-facing row=2 (64px frames), frameCol 0=idle, 1..8 walk
function chr(ctx, sheet, frameCol, dx, dy) { ctx.drawImage(sheet, frameCol * 64, 2 * 64, 64, 64, dx, dy, 64, 64); }

function buildStatic(buf, S) {
  const ctx = buf.getContext('2d'); ctx.imageSmoothingEnabled = false;
  const cols = W / T, rows = H / T;
  // floor
  for (let y = 2; y < rows; y++) for (let x = 0; x < cols; x++) tile(ctx, S.floors, FLOOR[0], FLOOR[1], x * T, y * T);
  // brick wall (rows 0-1)
  for (let y = 0; y < 2; y++) for (let x = 0; x < cols; x++) tile(ctx, S.inside, WALL[0], WALL[1], x * T, y * T);
  // wood beam trim at wall/floor seam
  ctx.fillStyle = '#6b4326'; ctx.fillRect(0, 2 * T - 5, W, 7); ctx.fillStyle = '#8a5a32'; ctx.fillRect(0, 2 * T - 5, W, 2); ctx.fillStyle = '#2a1810'; ctx.fillRect(0, 2 * T + 2, W, 2);
  // windows + curtains on the wall
  for (const wx of [40, 432]) {
    ctx.fillStyle = '#13233f'; ctx.fillRect(wx, 8, 40, 44); ctx.fillStyle = '#cfe0ff';
    for (let i = 0; i < 8; i++) ctx.fillRect(wx + 4 + (i * 11) % 36, 10 + (i * 7) % 40, 2, 2);
    ctx.fillStyle = '#5a3a1c'; ctx.fillRect(wx - 3, 6, 46, 3); ctx.fillRect(wx + 18, 8, 3, 44);
    tile(ctx, S.vic, CURTAIN[0], CURTAIN[1], wx - 18, 2); tile(ctx, S.vic, CURTAIN2[0], CURTAIN2[1], wx + 28, 2);
  }
  // red rug (9-slice), center
  const rx = 176, ry = 160, rcols = 5, rrows = 4;
  for (let j = 0; j < rrows; j++) for (let i = 0; i < rcols; i++) {
    const k = i === 0 ? 'l' : i === rcols - 1 ? 'r' : 'c'; const kk = j === 0 ? (k === 'l' ? 'tl' : k === 'r' ? 'tr' : 't') : j === rrows - 1 ? (k === 'l' ? 'bl' : k === 'r' ? 'br' : 'b') : k;
    tile(ctx, S.floors, RUG[kk][0], RUG[kk][1], rx + i * T, ry + j * T);
  }
  // round tables + chairs (sides)
  for (const tx of [96, 400]) {
    tile(ctx, S.vic, CHAIR[0], CHAIR[1], tx - 30, 232); tile(ctx, S.vic, CHAIR_R[0], CHAIR_R[1], tx + 18, 232);
    tile(ctx, S.vic, TABLE[0], TABLE[1], tx - 16, 244);
  }
  // barrels (corner) + plants + lamps
  tile(ctx, S.barrel, 0, 0, 444, 286); tile(ctx, S.barrel, 1, 0, 470, 292); tile(ctx, S.barrel, 2, 0, 452, 312);
  tile(ctx, S.vic, PLANT[0], PLANT[1], 8, 286); tile(ctx, S.vic, PLANT[0], PLANT[1], 484, 252);
  tile(ctx, S.vic, LAMP[0], LAMP[1], 8, 250);
  // screen frame (cyan) on the wall
  ctx.fillStyle = '#0c2030'; ctx.fillRect(198, 6, 116, 50); ctx.strokeStyle = '#46c8e0'; ctx.lineWidth = 2; ctx.strokeRect(199, 7, 114, 48); ctx.fillStyle = '#16415e'; ctx.fillRect(202, 10, 108, 42);
}

export default function TavernGame({ onHotspot, stats }) {
  const canvasRef = useRef(null);
  const statsRef = useRef(stats);
  useEffect(() => { statsRef.current = stats; }, [stats]);
  const [ready, setReady] = useState(false);
  useEffect(() => {
    const keys = Object.keys(SRC); const S = {}; let loaded = 0, raf, f = 0, buf, paused = false, io;
    const start = () => {
      setReady(true);
      buf = document.createElement('canvas'); buf.width = W; buf.height = H; buildStatic(buf, S);
      const ctx = canvasRef.current.getContext('2d'); ctx.imageSmoothingEnabled = false;
      const render = () => {
        if (paused) return;
        f++;
        ctx.drawImage(buf, 0, 0);
        // bartender (a clothed guard tending bar) behind the bar (idle bob)
        const bb = Math.round(Math.sin(f * 0.06) * 1);
        chr(ctx, S.soldier, 0, 56, 18 + bb);
        // bar counter (drawn over bartender's lower half) + bottles
        ctx.fillStyle = '#5e3a22'; ctx.fillRect(24, 92, 168, 26); ctx.fillStyle = '#8a5a32'; ctx.fillRect(24, 92, 168, 4); ctx.fillStyle = '#c79155'; ctx.fillRect(24, 96, 168, 1); ctx.fillStyle = '#2a1810'; ctx.fillRect(24, 116, 168, 4);
        for (let i = 1; i < 6; i++) { ctx.fillStyle = '#3a2417'; ctx.fillRect(24 + i * 28, 98, 1, 18); }
        for (const bxp of [44, 96, 150]) { tile(ctx, S.vic, VASE[0], VASE[1], bxp, 76, 20, 20); }
        // patrons at the side tables (idle bob)
        chr(ctx, S.soldier, 0, 64, 188 + (Math.sin(f * 0.05) > 0.6 ? -2 : 0));
        chr(ctx, S.soldier2, 0, 368, 188 + (Math.sin(f * 0.05 + 2) > 0.6 ? -2 : 0));
        // DANCER (舞女): princess cycling walk frames = dancing, on the rug
        const dframe = 1 + (Math.floor(f / 7) % 8);
        const sway = Math.round(Math.sin(f * 0.12) * 4);
        // spotlight
        const g = ctx.createRadialGradient(256, 230, 6, 256, 236, 56); g.addColorStop(0, 'rgba(255,244,210,0.26)'); g.addColorStop(1, 'rgba(255,244,210,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.ellipse(256, 244, 40, 44, 0, 0, 7); ctx.fill();
        chr(ctx, S.princess, dframe, 224 + sway, 184);
        // screen content: LIVE platform stats, cycling, over a dim sparkline
        const st = statsRef.current;
        const items = st ? [['CLASSES', st.classes], ['ONLINE', st.online], ['SESSIONS', st.sessions]] : [['LIVE', '·']];
        const phase = Math.floor(f / 150) % items.length;
        const [label, val] = items[phase];
        for (let i = 0; i < 13; i++) { const bh = 3 + ((Math.sin(f * 0.09 + i) + 1) * 4 + (i % 3)) | 0; ctx.fillStyle = 'rgba(70,170,210,0.30)'; ctx.fillRect(206 + i * 8, 50 - bh, 5, bh); }
        const pf = (f % 150) / 150, fade = Math.min(1, Math.min(pf, 1 - pf) * 8 + 0.25);
        ctx.textAlign = 'center';
        ctx.fillStyle = `rgba(174,242,255,${fade})`; ctx.font = 'bold 18px Georgia, serif';
        ctx.fillText(String(val), 256, 33);
        ctx.fillStyle = `rgba(95,208,232,${fade})`; ctx.font = '7px Georgia, serif';
        ctx.fillText(label, 256, 45);
        ctx.textAlign = 'left'; ctx.font = '10px serif';
        ctx.fillStyle = 'rgba(127,233,255,0.4)'; ctx.fillRect(202, 10 + (f % 42), 108, 1);
        // warm lighting + screen glow
        ctx.globalCompositeOperation = 'lighter';
        for (const [lx, ly, lr, a] of [[256, 30, 64, 0.16], [40, 40, 30, 0.18], [432, 40, 30, 0.18]]) { const aa = a * (0.85 + 0.15 * Math.sin(f * 0.1 + lx)); const gg = ctx.createRadialGradient(lx, ly, 0, lx, ly, lr); gg.addColorStop(0, `rgba(255,180,90,${aa})`); gg.addColorStop(1, 'rgba(255,170,80,0)'); ctx.fillStyle = gg; ctx.beginPath(); ctx.arc(lx, ly, lr, 0, 7); ctx.fill(); }
        const cg = ctx.createRadialGradient(256, 30, 0, 256, 30, 56); cg.addColorStop(0, 'rgba(70,200,235,0.14)'); cg.addColorStop(1, 'rgba(70,200,235,0)'); ctx.fillStyle = cg; ctx.beginPath(); ctx.arc(256, 30, 56, 0, 7); ctx.fill();
        ctx.globalCompositeOperation = 'source-over';
        // vignette + dust
        const vg = ctx.createRadialGradient(W / 2, H * 0.52, H * 0.36, W / 2, H * 0.5, H * 0.82); vg.addColorStop(0, 'rgba(0,0,0,0)'); vg.addColorStop(1, 'rgba(8,4,10,0.5)'); ctx.fillStyle = vg; ctx.fillRect(0, 0, W, H);
        ctx.fillStyle = 'rgba(255,225,170,0.4)';
        for (let i = 0; i < 12; i++) { const dx = (i * 43 + f * 0.16) % W, dy = (i * 57 + Math.sin(f * 0.02 + i) * 8 + 64) % H; ctx.fillRect(dx | 0, dy | 0, 1, 1); }
        raf = requestAnimationFrame(render);
      };
      render();
      // pause the 60fps loop while the tavern is scrolled out of view (CPU/battery)
      io = new IntersectionObserver(([e]) => {
        if (e.isIntersecting) { if (paused) { paused = false; render(); } }
        else if (!paused) { paused = true; cancelAnimationFrame(raf); }
      }, { threshold: 0 });
      io.observe(canvasRef.current);
    };
    keys.forEach((k) => { const im = new Image(); im.onload = () => { if (++loaded === keys.length) start(); }; im.src = SRC[k]; S[k] = im; });
    return () => { cancelAnimationFrame(raf); if (io) io.disconnect(); };
  }, []);

  return (
    <div className="gm-room">
      <canvas ref={canvasRef} width={W} height={H} className="gm-canvas" role="img" aria-label="Animated tavern scene" />
      {!ready && <div className="gm-loading">loading tavern…</div>}
      <div className="gm-overlay">
        <button className="gm-hot" style={{ left: '38%', top: '1%', width: '24%', height: '16%' }} onClick={() => onHotspot?.('agents')} title="Browse Agents (screen)" />
        <button className="gm-label gm-label-screen" style={{ left: '50%', top: '18%' }} onClick={() => onHotspot?.('agents')}>▸ Browse Agents</button>
        <button className="gm-hot" style={{ left: '44%', top: '50%', width: '14%', height: '24%' }} onClick={() => onHotspot?.('booth')} title="My Booth" />
        <button className="gm-label gm-label-booth" style={{ left: '50%', top: '90%' }} onClick={() => onHotspot?.('booth')}>⌂ Enter My Booth</button>
        <Npc x="11%" y="4%" w="13%" h="20%" who="Barkeep" say="What'll it be? The staff roster is up on the board." onClick={() => onHotspot?.('agents')} />
        <Npc x="11%" y="52%" w="13%" h="22%" who="Patron" say="I run three mercenaries straight from my booth." onClick={() => onHotspot?.('booth')} />
        <Npc x="72%" y="52%" w="13%" h="22%" who="Patron" say="Showcase put my little app on the open internet!" onClick={() => onHotspot?.('mansion')} />
      </div>
    </div>
  );
}

function Npc({ x, y, w, h, who, say, onClick }) {
  const [hover, setHover] = useState(false);
  return (
    <button className="gm-npc" style={{ left: x, top: y, width: w, height: h }}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} onClick={onClick} aria-label={who}>
      {hover && <span className="gm-say"><strong>{who}</strong>{say}</span>}
    </button>
  );
}
