// React overlay: HUD with character portraits, XP bar, level, and touch controls.

const { useState, useEffect, useRef } = React;

// Game listens on window keydown/keyup. Synthetic KeyboardEvents flow through the
// existing input pipeline (keys[], keyOnce) unchanged.
function fireKey(key, type) {
  window.dispatchEvent(new KeyboardEvent(type, { key, bubbles: true }));
}
function tapKey(key) {
  fireKey(key, 'keydown');
  requestAnimationFrame(() => fireKey(key, 'keyup'));
}

function Portrait({ who, active, locked }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current;
    if (!c) return;
    const cx = c.getContext('2d');
    cx.imageSmoothingEnabled = false;
    cx.clearRect(0, 0, c.width, c.height);
    const src = window.BAKED?.[who]?.down?.[0];
    if (src) {
      cx.drawImage(src, 0, 0, 16, 10, 0, 0, c.width, c.height * (10/16));
    }
    if (locked) {
      cx.fillStyle = 'rgba(0,0,0,0.55)';
      cx.fillRect(0, 0, c.width, c.height);
      cx.fillStyle = '#fff';
      cx.font = 'bold 14px monospace';
      cx.textAlign = 'center';
      cx.fillText('🔒', c.width/2, c.height/2 + 5);
    }
  });

  return (
    <div style={{
      width: 56, height: 56,
      background: active ? '#ffd86b' : '#1a2640',
      border: '2px solid #000',
      boxShadow: active ? '0 0 0 2px #fff, 0 4px 0 #000' : '0 4px 0 #000',
      imageRendering: 'pixelated',
      position: 'relative',
      cursor: locked ? 'not-allowed' : 'pointer',
      transition: 'transform 80ms',
      transform: active ? 'translateY(-2px)' : 'none',
    }}>
      <canvas ref={ref} width={48} height={48} style={{
        width: 48, height: 48, margin: 4, display: 'block',
        imageRendering: 'pixelated',
      }} />
      <div style={{
        position: 'absolute', bottom: -14, left: 0, right: 0,
        textAlign: 'center', fontSize: 7, color: active ? '#ffd86b' : '#a9b4c9',
        textShadow: '1px 1px 0 #000',
      }}>{who.toUpperCase()}</div>
    </div>
  );
}

function DPadButton({ dirKey, label, style }) {
  const held = useRef(false);
  const onDown = (e) => {
    e.preventDefault();
    if (held.current) return;
    held.current = true;
    fireKey(dirKey, 'keydown');
  };
  const onUp = (e) => {
    e.preventDefault();
    if (!held.current) return;
    held.current = false;
    fireKey(dirKey, 'keyup');
  };
  return (
    <button
      onPointerDown={onDown}
      onPointerUp={onUp}
      onPointerCancel={onUp}
      onPointerLeave={onUp}
      onContextMenu={(e) => e.preventDefault()}
      style={{
        position: 'absolute',
        width: 56, height: 56,
        background: '#1a2640',
        color: '#ffd86b',
        border: '2px solid #000',
        boxShadow: '0 4px 0 #000',
        fontFamily: "'Press Start 2P', monospace",
        fontSize: 14,
        padding: 0,
        cursor: 'pointer',
        touchAction: 'none',
        userSelect: 'none',
        WebkitUserSelect: 'none',
        WebkitTouchCallout: 'none',
        WebkitTapHighlightColor: 'transparent',
        ...style,
      }}
    >{label}</button>
  );
}

function DPad() {
  return (
    <div style={{
      position: 'fixed',
      left: 20, bottom: 20,
      width: 176, height: 176,
      pointerEvents: 'none',
    }}>
      <div style={{ position: 'relative', width: '100%', height: '100%', pointerEvents: 'auto' }}>
        <DPadButton dirKey="ArrowUp"    label="▲" style={{ top: 0,   left: 60 }} />
        <DPadButton dirKey="ArrowLeft"  label="◀" style={{ top: 60,  left: 0 }} />
        <DPadButton dirKey="ArrowRight" label="▶" style={{ top: 60,  left: 120 }} />
        <DPadButton dirKey="ArrowDown"  label="▼" style={{ top: 120, left: 60 }} />
      </div>
    </div>
  );
}

function ActionBtn({ keyCode, label, sub, color }) {
  const onDown = (e) => { e.preventDefault(); tapKey(keyCode); };
  return (
    <button
      onPointerDown={onDown}
      onContextMenu={(e) => e.preventDefault()}
      style={{
        width: 64, height: 64,
        background: color,
        color: '#000',
        border: '2px solid #000',
        boxShadow: '0 4px 0 #000',
        fontFamily: "'Press Start 2P', monospace",
        padding: 0,
        cursor: 'pointer',
        touchAction: 'none',
        userSelect: 'none',
        WebkitUserSelect: 'none',
        WebkitTouchCallout: 'none',
        WebkitTapHighlightColor: 'transparent',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 4,
      }}
    >
      <span style={{ fontSize: 14 }}>{label}</span>
      <span style={{ fontSize: 6, letterSpacing: 1 }}>{sub}</span>
    </button>
  );
}

function ActionPad({ inv, skating }) {
  return (
    <div style={{
      position: 'fixed',
      right: 14, bottom: 14,
      display: 'grid',
      gridTemplateColumns: 'repeat(3, 56px)',
      gridAutoRows: '56px',
      gap: 6,
    }}>
      <ActionBtn keyCode="j"   label="J" sub="PUNCH" color="#ffd86b" />
      <ActionBtn keyCode="k"   label="K" sub="FCKR"  color="#ff9a2a" />
      <ActionBtn keyCode="l"   label="L" sub="SLING" color="#b3dfff" />
      <ActionBtn keyCode="u"   label="U" sub="BELL"  color="#2dbfa0" />
      <ActionBtn keyCode="b"   label="B" sub="BALL"  color="#f4f4f4" />
      <ActionBtn keyCode="Tab" label="↔" sub="SWAP"  color="#e24848" />
      <ActionBtn keyCode="m"   label="M" sub={`H2O${(inv && inv.waterBalloons) ? ' '+inv.waterBalloons : ''}`}  color="#3a6fd8" />
      <ActionBtn keyCode="c"   label="C" sub={`PFFT${(inv && inv.whoopee) ? ' '+inv.whoopee : ''}`} color="#e24848" />
      <ActionBtn keyCode="v"   label="V" sub={`MRBL${(inv && inv.marbles) ? ' '+inv.marbles : ''}`} color="#9a9a9a" />
      <ActionBtn keyCode="g"   label="G" sub={`PNT${(inv && inv.paint) ? ' '+inv.paint : ''}`} color="#c44a2a" />
      <ActionBtn keyCode="o"   label="O" sub={skating ? 'OFF' : 'SKATE'} color={skating ? '#ffd86b' : '#a9b4c9'} />
    </div>
  );
}

// Coin icon — drawn from baked sprite
function CoinIcon({ size = 14 }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current; if (!c) return;
    const cx = c.getContext('2d'); cx.imageSmoothingEnabled = false;
    cx.clearRect(0, 0, c.width, c.height);
    const src = window.BAKED && window.BAKED.coin && window.BAKED.coin[0];
    if (src) cx.drawImage(src, 0, 0, 6, 6, 0, 0, c.width, c.height);
  });
  return <canvas ref={ref} width={6} height={6} style={{ width: size, height: size, imageRendering: 'pixelated' }} />;
}

// Shop modal — opened when player walks into corner store
function ShopModal({ onClose }) {
  const [coins, setCoins] = useState(() => (window.__getGameState && window.__getGameState().coins) || 0);
  const [inv, setInv] = useState(() => (window.__getGameState && window.__getGameState().inventory) || {});
  const items = window.__leviShopItems || [];

  useEffect(() => {
    const u = (e) => { setCoins(e.detail.coins); setInv(e.detail.inventory); };
    window.addEventListener('shopUpdate', u);
    return () => window.removeEventListener('shopUpdate', u);
  }, []);
  useEffect(() => {
    const k = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', k);
    return () => window.removeEventListener('keydown', k);
  }, []);

  function buy(it){
    const ok = window.__leviBuy && window.__leviBuy(it.key);
    if (!ok) {
      // visual nudge could go here
    }
  }

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(11,15,26,0.85)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 100,
      fontFamily: "'Press Start 2P', monospace",
    }}>
      <div style={{
        background: '#fff8e8',
        border: '4px solid #000',
        boxShadow: '0 8px 0 #000',
        padding: 18,
        width: 'min(560px, 92vw)',
        maxHeight: '90vh',
        overflowY: 'auto',
        color: '#0b0f1a',
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
          <div style={{ fontSize: 20, color: '#e24848', textShadow: '2px 2px 0 #ffd86b' }}>CORNER SHOP</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: '#c99a2c', fontSize: 14 }}>
            <CoinIcon size={20} />
            <span>{coins}</span>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 10 }}>
          {items.map(it => {
            const owned = it.kind === 'flag' ? !!inv[it.target] : (inv[it.target] || 0);
            const canAfford = coins >= it.price;
            const disabled = (it.kind === 'flag' && owned) || !canAfford;
            return (
              <button key={it.key} disabled={disabled} onPointerDown={(e) => { e.preventDefault(); if (!disabled) buy(it); }}
                style={{
                  background: disabled ? '#d8d2c0' : '#fff',
                  border: '2px solid #000',
                  boxShadow: disabled ? 'none' : '0 4px 0 #000',
                  padding: '10px 8px',
                  fontFamily: 'inherit',
                  fontSize: 8,
                  textAlign: 'left',
                  cursor: disabled ? 'not-allowed' : 'pointer',
                  color: '#0b0f1a',
                  letterSpacing: 1,
                }}>
                <div style={{ fontSize: 9, marginBottom: 6, color: '#0b0f1a' }}>{it.label}</div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span style={{ color: canAfford ? '#0a6b0a' : '#8a1d1d' }}>
                    {it.kind === 'flag' && owned ? 'OWNED' : `${it.price}c`}
                  </span>
                  {it.kind === 'inventory' && (
                    <span style={{ fontSize: 7, color: '#485c80' }}>have: {owned}</span>
                  )}
                </div>
              </button>
            );
          })}
        </div>
        <div style={{ marginTop: 18, display: 'flex', justifyContent: 'flex-end' }}>
          <button onPointerDown={(e) => { e.preventDefault(); onClose(); }}
            style={{
              background: '#0b0f1a', color: '#ffd86b',
              border: '2px solid #000', boxShadow: '0 4px 0 #000',
              padding: '10px 16px', fontFamily: 'inherit', fontSize: 9,
              cursor: 'pointer', letterSpacing: 2,
            }}>LEAVE [ESC]</button>
        </div>
      </div>
    </div>
  );
}

function HUD() {
  const [s, setS] = useState(() => window.__getGameState ? window.__getGameState() : {
    character: 'levi', unlocked: { levi: true }, xp: 0, level: 1, need: 30, coins: 0, heat: 0, combo: { count: 0, mult: 1, timer: 0, window: 5 }, muted: false,
  });
  const [shopOpen, setShopOpen] = useState(false);
  const [tapCount, setTapCount] = useState(0);
  const [tapTimer, setTapTimer] = useState(0);

  useEffect(() => {
    const h = (e) => setS(e.detail);
    window.addEventListener('gameState', h);
    return () => window.removeEventListener('gameState', h);
  }, []);
  useEffect(() => {
    const open = () => setShopOpen(true);
    window.addEventListener('shopOpen', open);
    return () => window.removeEventListener('shopOpen', open);
  }, []);
  function closeShop(){ setShopOpen(false); window.__leviCloseShop && window.__leviCloseShop(); }

  const pct = Math.min(1, s.xp / s.need);
  const heatPct = Math.min(1, (s.heat || 0) / 100);
  const comboTimerPct = s.combo && s.combo.count >= 2 && s.combo.window
    ? Math.max(0, 1 - s.combo.timer / s.combo.window) : 0;

  // 3-tap level number to wipe save
  function onLevelTap(){
    const now = Date.now();
    const t = tapTimer && now - tapTimer < 800 ? tapCount + 1 : 1;
    if (t >= 3) {
      if (confirm('Wipe save? You will lose all XP, coins, and unlocked characters.')) {
        window.__leviWipeSave && window.__leviWipeSave();
      }
      setTapCount(0); setTapTimer(0);
    } else {
      setTapCount(t); setTapTimer(now);
    }
  }

  return (
    <>
      {/* Top-right: XP + Level + Coins + Heat */}
      <div style={{
        position: 'fixed', top: 16, right: 16,
        background: '#0b0f1a', border: '2px solid #000',
        boxShadow: '0 4px 0 #000',
        padding: '10px 12px',
        fontFamily: "'Press Start 2P', monospace",
        color: '#fff', fontSize: 9, letterSpacing: 1,
        minWidth: 200,
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, gap: 10 }}>
          <span onClick={onLevelTap} style={{ cursor: 'pointer', userSelect: 'none' }}>LV <span style={{ color: '#ffd86b' }}>{s.level}</span></span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, color: '#ffd86b' }}>
            <CoinIcon size={12} />
            <span>{s.coins || 0}</span>
          </span>
          <span style={{ color: '#a9b4c9', fontSize: 8 }}>{s.xp}/{s.need}</span>
        </div>
        {/* XP bar */}
        <div style={{ height: 6, background: '#1a2640', border: '1px solid #000', position: 'relative', overflow: 'hidden' }}>
          <div style={{ position: 'absolute', inset: 0, width: `${pct * 100}%`, background: 'linear-gradient(#ffd86b, #c99a2c)', transition: 'width 240ms ease-out' }} />
        </div>
        {/* Heat bar */}
        <div style={{ marginTop: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ fontSize: 7, color: heatPct > 0.7 ? '#ff4a2a' : '#a9b4c9' }}>HEAT</span>
          <div style={{ flex: 1, height: 6, background: '#1a0a08', border: '1px solid #000', position: 'relative', overflow: 'hidden' }}>
            <div style={{ position: 'absolute', inset: 0, width: `${heatPct * 100}%`, background: heatPct >= 1 ? '#ff4a2a' : 'linear-gradient(#e24848, #8a1d1d)', transition: 'width 200ms linear', boxShadow: heatPct > 0.7 ? '0 0 6px rgba(255,80,80,0.7)' : 'none' }} />
          </div>
        </div>
        {/* Mute toggle */}
        <div style={{ marginTop: 6, display: 'flex', justifyContent: 'flex-end' }}>
          <button onPointerDown={(e) => { e.preventDefault(); window.__leviToggleMute && window.__leviToggleMute(); }}
            style={{ background: 'transparent', color: s.muted ? '#a9b4c9' : '#ffd86b', border: '1px solid currentColor', padding: '2px 6px', fontFamily: 'inherit', fontSize: 7, cursor: 'pointer', letterSpacing: 1 }}>
            {s.muted ? '♪ MUTED' : '♪ ON'}
          </button>
        </div>
      </div>

      {/* Combo badge — appears when chain ≥ 2 */}
      {s.combo && s.combo.count >= 2 && (
        <div style={{
          position: 'fixed', top: 100, right: 16,
          background: '#ff9a2a', color: '#0b0f1a',
          border: '2px solid #000', boxShadow: '0 4px 0 #000',
          padding: '6px 10px',
          fontFamily: "'Press Start 2P', monospace",
          fontSize: 11, letterSpacing: 1,
          minWidth: 90,
        }}>
          <div>COMBO x{s.combo.count}</div>
          <div style={{ height: 4, background: '#1a0a00', border: '1px solid #000', position: 'relative', overflow: 'hidden', marginTop: 4 }}>
            <div style={{ position: 'absolute', inset: 0, width: `${comboTimerPct * 100}%`, background: '#ffd86b', transition: 'width 100ms linear' }} />
          </div>
        </div>
      )}

      {/* Portraits */}
      <div style={{
        position: 'fixed', top: 70, left: 16,
        display: 'flex', gap: 14, alignItems: 'flex-end', flexWrap: 'wrap', maxWidth: 280,
      }}>
        <div onPointerDown={(e) => { e.preventDefault(); if (s.unlocked.levi) swap('levi'); }}>
          <Portrait who="levi" active={s.character === 'levi'} locked={!s.unlocked.levi} />
        </div>
        <div onPointerDown={(e) => { e.preventDefault(); if (s.unlocked.asher) swap('asher'); }}>
          <Portrait who="asher" active={s.character === 'asher'} locked={!s.unlocked.asher} />
        </div>
        {s.unlocked.maya !== undefined && (
          <div onPointerDown={(e) => { e.preventDefault(); if (s.unlocked.maya) swap('maya'); }}>
            <Portrait who="maya" active={s.character === 'maya'} locked={!s.unlocked.maya} />
          </div>
        )}
      </div>

      <DPad />
      <ActionPad inv={s.inventory || (window.__getGameState && window.__getGameState().inventory) || {}} skating={s.skating} />
      {shopOpen && <ShopModal onClose={closeShop} />}
    </>
  );
}

function swap(target) {
  const cur = window.__getGameState().character;
  if (cur === target) return;
  window.__gameTrySwap && window.__gameTrySwap();
}

const root = ReactDOM.createRoot(document.getElementById('overlay-root'));
root.render(<HUD />);
