import * as scene from '../../../core/scene.js';
import * as audio from '../../../core/audio.js';
import * as bus from '../../../core/bus.js';
import * as store from '../../../core/store.js';
import * as net from '../../../core/net.js';
import * as matchSession from '../../../core/match-session.js';
import { emoji } from '../../../core/theme.js';
import { createGame, rollDice, getValidMoves, applyMove, nextTurn, hasWon, getPipCount, WHITE, BLACK, serializeState } from '../logic/rules.js';
import { getBotMove } from '../logic/bot.js';
import { createMatch, startNewGame, endGame, canUseCube, getMatchState } from '../logic/match.js';
import { createCube, canDouble, offerDouble, acceptDouble, declineDouble, shouldBotDouble, shouldBotAccept, getStake } from '../logic/doubling.js';
import { drawBoard, hitTest } from '../canvas/board-renderer.js';
import { drawDice, createRollAnimation } from '../canvas/dice-renderer.js';
import { createMoveAnimation } from '../canvas/move-animator.js';

let canvas, ctx, layout;
let game, match;
let selectedPiece = null;
let validMoves = [];
let highlights = [];
let isRolling = false;
let isAnimating = false;
let myColor = WHITE;
let params = {};
let emotePanel = null;
let turnTimer = null;
let turnTimeLeft = 30;

export function mountGame(el, p) {
  params = p || {};
  const { mode = 'bot', variant = 'sheshbesh', matchLength = 3, difficulty = 'medium', useCube = true } = params;

  myColor = mode === 'live' ? (params.color === 'black' ? BLACK : WHITE) : WHITE;

  // Create match
  match = createMatch(matchLength, variant);
  if (!useCube) match.cube = null;

  el.innerHTML = `
    <div class="bgg-container">
      <div class="bgg-top-bar">
        <div class="bgg-player-card bgg-player-top" id="player-top">
          <div class="bgg-avatar">🎯</div>
          <div class="bgg-player-info">
            <div class="bgg-name" id="name-top">${mode === 'bot' ? 'بوت' : 'خصم'}</div>
            <div class="bgg-pips" id="pips-top">167 نقطة</div>
          </div>
          <div class="bgg-score" id="score-top">0</div>
        </div>
      </div>

      <div class="bgg-board-area">
        <canvas id="bg-canvas" width="360" height="400"></canvas>
        <div class="bgg-dice-area" id="dice-area">
          <button class="bgg-roll-btn" id="btn-roll">${emoji('game_die', '🎲', 24)} ارمي النرد</button>
        </div>
        <div class="bgg-cube-area" id="cube-area" style="display:none;">
          <button class="bgg-cube-btn" id="btn-double">×2 ضاعف</button>
        </div>
        <div class="bgg-double-offer" id="double-offer" style="display:none;">
          <p>الخصم يضاعف! القيمة: <span id="double-val">2</span></p>
          <button class="bgg-accept-btn" id="btn-accept-double">قبول</button>
          <button class="bgg-decline-btn" id="btn-decline-double">رفض</button>
        </div>
      </div>

      <div class="bgg-bottom-bar">
        <div class="bgg-player-card bgg-player-bottom" id="player-bottom">
          <div class="bgg-avatar">👤</div>
          <div class="bgg-player-info">
            <div class="bgg-name" id="name-bottom">أنت</div>
            <div class="bgg-pips" id="pips-bottom">167 نقطة</div>
          </div>
          <div class="bgg-score" id="score-bottom">0</div>
        </div>
        <div class="bgg-actions">
          <button class="bgg-action-btn" id="btn-emote">${emoji('sparkles', '✨', 18)}</button>
          <button class="bgg-action-btn" id="btn-undo">↩️</button>
          <button class="bgg-action-btn bgg-action-quit" id="btn-quit">✕</button>
        </div>
      </div>

      <div class="bgg-turn-indicator" id="turn-indicator"></div>
      <div class="bgg-emote-panel" id="emote-panel" style="display:none;"></div>
    </div>
    ${getGameStyles()}
  `;

  canvas = el.querySelector('#bg-canvas');
  ctx = canvas.getContext('2d');
  resizeCanvas();

  // Start first game
  startNewGameRound();

  // Event listeners
  canvas.addEventListener('click', onCanvasClick);
  canvas.addEventListener('touchstart', onCanvasTouch, { passive: false });
  el.querySelector('#btn-roll').onclick = onRollClick;
  el.querySelector('#btn-double').onclick = onDoubleClick;
  el.querySelector('#btn-accept-double').onclick = onAcceptDouble;
  el.querySelector('#btn-decline-double').onclick = onDeclineDouble;
  el.querySelector('#btn-emote').onclick = toggleEmotePanel;
  el.querySelector('#btn-quit').onclick = onQuit;
  window.addEventListener('resize', resizeCanvas);

  // Multiplayer session
  if (mode === 'live') {
    matchSession.create(params.matchId, 'backgammon', {
      onOpponentMove: handleServerState,
      onOpponentDisconnect: () => bus.emit('toast', { text: 'الخصم انقطع...' }),
      onOpponentAbandon: () => endMatchWithWin()
    });
  }

  setupEmotePanel(el);
}

export function unmountGame() {
  window.removeEventListener('resize', resizeCanvas);
  matchSession.destroy();
  clearInterval(turnTimer);
}

function startNewGameRound() {
  game = startNewGame(match);
  selectedPiece = null;
  validMoves = [];
  highlights = [];
  isRolling = false;
  isAnimating = false;
  render();
  updateUI();
  updateTurnIndicator();

  if (game.turn !== myColor && params.mode === 'bot') {
    setTimeout(doBotTurn, 800);
  }
}

// ===== RENDERING =====

function resizeCanvas() {
  if (!canvas) return;
  const container = canvas.parentElement;
  const w = Math.min(container.clientWidth, 400);
  const h = Math.min(w * 1.1, 440);
  canvas.width = w;
  canvas.height = h;
  canvas.style.width = w + 'px';
  canvas.style.height = h + 'px';
  render();
}

function render() {
  if (!ctx || !game) return;
  layout = drawBoard(ctx, canvas.width, canvas.height, game.state, {
    highlights,
    selectedPoint: selectedPiece !== null ? selectedPiece.from : null
  });

  // Draw dice if rolled
  if (game.dice && !isRolling) {
    const diceX = canvas.width / 2 - 45;
    const diceY = canvas.height / 2 - 18;
    const usedIndices = [];
    // Mark dice as used based on movesPlayed
    for (let i = 0; i < game.movesPlayed.length; i++) {
      for (let j = 0; j < game.dice.length; j++) {
        if (!usedIndices.includes(j) && game.dice[j] === game.movesPlayed[i]) {
          usedIndices.push(j);
          break;
        }
      }
    }
    const allMoves = game.dice[0] === game.dice[1] ? [game.dice[0], game.dice[0], game.dice[0], game.dice[0]] : game.dice;
    drawDice(ctx, diceX, diceY, allMoves, { used: usedIndices });
  }
}

function updateUI() {
  if (!game) return;
  const topColor = myColor === WHITE ? BLACK : WHITE;
  const doc = canvas?.closest('.bgg-container');
  if (!doc) return;

  doc.querySelector('#pips-top').textContent = getPipCount(game.state, topColor) + ' نقطة';
  doc.querySelector('#pips-bottom').textContent = getPipCount(game.state, myColor) + ' نقطة';
  doc.querySelector('#score-top').textContent = match.scores[topColor];
  doc.querySelector('#score-bottom').textContent = match.scores[myColor];

  // Show/hide roll button
  const rollBtn = doc.querySelector('#btn-roll');
  const isMyTurn = game.turn === myColor;
  rollBtn.style.display = (isMyTurn && !game.dice && !isAnimating) ? '' : 'none';

  // Show/hide double button
  const cubeArea = doc.querySelector('#cube-area');
  if (match.cube && canUseCube(match) && isMyTurn && !game.dice && canDouble(match.cube, myColor)) {
    cubeArea.style.display = '';
  } else {
    cubeArea.style.display = 'none';
  }
}

function updateTurnIndicator() {
  const indicator = canvas?.closest('.bgg-container')?.querySelector('#turn-indicator');
  if (!indicator) return;
  const isMyTurn = game.turn === myColor;
  indicator.textContent = isMyTurn ? 'دورك' : 'دور الخصم';
  indicator.className = `bgg-turn-indicator ${isMyTurn ? 'bgg-my-turn' : 'bgg-opp-turn'}`;
}

// ===== INPUT HANDLING =====

function onCanvasClick(e) {
  if (isAnimating || isRolling) return;
  if (game.turn !== myColor && params.mode !== 'local-multi') return;
  if (!game.dice || game.movesLeft.length === 0) return;

  const rect = canvas.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  handleBoardTap(x, y);
}

function onCanvasTouch(e) {
  if (isAnimating || isRolling) return;
  if (game.turn !== myColor && params.mode !== 'local-multi') return;
  if (!game.dice || game.movesLeft.length === 0) return;

  e.preventDefault();
  const touch = e.touches[0];
  const rect = canvas.getBoundingClientRect();
  const x = touch.clientX - rect.left;
  const y = touch.clientY - rect.top;
  handleBoardTap(x, y);
}

function handleBoardTap(x, y) {
  const hit = hitTest(x, y, layout, game.state);
  if (!hit) {
    clearSelection();
    return;
  }

  // If tapping a highlighted destination
  if (selectedPiece && hit.type === 'point' && highlights.includes(hit.index)) {
    executeMove(hit.index);
    return;
  }
  if (selectedPiece && hit.type === 'bearoff' && highlights.includes('off')) {
    executeMove('off');
    return;
  }

  // Select a piece
  if (hit.type === 'point') {
    selectPoint(hit.index);
  } else if (hit.type === 'bar' && hit.player === game.turn) {
    selectBar();
  } else {
    clearSelection();
  }
}

function selectPoint(pointIndex) {
  const pieces = game.state.points[pointIndex];
  if (pieces.length === 0 || pieces[pieces.length - 1].type !== game.turn) {
    clearSelection();
    return;
  }

  const piece = pieces[pieces.length - 1];
  const moves = getValidMoves(game).filter(m => m.piece.id === piece.id);

  if (moves.length === 0) {
    clearSelection();
    return;
  }

  selectedPiece = { id: piece.id, from: pointIndex, moves };
  highlights = moves.map(m => m.to === 'off' ? 'off' : m.to);
  audio.play('click');
  render();
}

function selectBar() {
  const moves = getValidMoves(game).filter(m => m.from === 'bar' || m.from === null);
  if (moves.length === 0) return;

  selectedPiece = { id: moves[0].piece.id, from: 'bar', moves };
  highlights = moves.map(m => m.to);
  audio.play('click');
  render();
}

function clearSelection() {
  selectedPiece = null;
  highlights = [];
  render();
}

function executeMove(destination) {
  if (!selectedPiece) return;

  const move = selectedPiece.moves.find(m => m.to === destination);
  if (!move) return;

  isAnimating = true;
  audio.play('sfx_bg_piece_move', 'game');

  const actions = applyMove(game, move.piece.id, move.steps);
  if (!actions) { isAnimating = false; return; }

  // Check for hit sound
  if (actions.some(a => a.type === 'hit')) {
    audio.play('sfx_bg_piece_hit', 'game');
  }
  if (actions.some(a => a.type === 'bear')) {
    audio.play('sfx_bg_bear_off', 'game');
  }

  clearSelection();
  isAnimating = false;
  render();
  updateUI();

  // Check if game over
  if (game.isOver) {
    handleGameOver();
    return;
  }

  // Check if more moves available
  if (game.movesLeft.length === 0) {
    endTurn();
  } else {
    // Auto-select if only one move possible
    const remaining = getValidMoves(game);
    if (remaining.length === 0) endTurn();
  }
}

function endTurn() {
  nextTurn(game);
  render();
  updateUI();
  updateTurnIndicator();

  if (params.mode === 'bot' && game.turn !== myColor) {
    setTimeout(doBotTurn, 600);
  } else if (params.mode === 'live') {
    syncToServer();
  }
}

// ===== DICE ROLLING =====

function onRollClick() {
  if (game.dice || isRolling || isAnimating) return;
  if (game.turn !== myColor && params.mode !== 'local-multi') return;

  isRolling = true;
  audio.play('sfx_bg_dice_roll', 'game');

  createRollAnimation(
    () => render(),
    () => {
      isRolling = false;
      const result = rollDice(game);

      // If no playable moves, skip turn
      if (game.movesLeft.length === 0) {
        render();
        bus.emit('toast', { text: 'لا حركات متاحة!' });
        setTimeout(endTurn, 1000);
        return;
      }

      render();
      updateUI();

      // Auto-play if only one possible move sequence
      const moves = getValidMoves(game);
      if (moves.length === 1 && game.movesLeft.length === 1) {
        setTimeout(() => {
          selectedPiece = { id: moves[0].piece.id, from: moves[0].from, moves };
          executeMove(moves[0].to);
        }, 400);
      }
    }
  );
}

// ===== DOUBLING CUBE =====

function onDoubleClick() {
  if (!match.cube || !canDouble(match.cube, myColor)) return;
  if (game.dice) return;

  if (params.mode === 'bot') {
    offerDouble(match.cube, myColor);
    const myPips = getPipCount(game.state, myColor);
    const oppPips = getPipCount(game.state, myColor === WHITE ? BLACK : WHITE);

    if (shouldBotAccept(match.cube, oppPips, myPips, params.difficulty)) {
      acceptDouble(match.cube);
      bus.emit('toast', { text: 'البوت قبل المضاعفة!' });
    } else {
      const loser = declineDouble(match.cube);
      bus.emit('toast', { text: 'البوت رفض! فزت بالجولة' });
      const result = endGame(match, myColor, 1);
      showGameResult(result);
      return;
    }
    updateUI();
  } else if (params.mode === 'live') {
    offerDouble(match.cube, myColor);
    syncToServer();
  }
}

function onAcceptDouble() {
  if (!match.cube) return;
  acceptDouble(match.cube);
  const offerUI = canvas?.closest('.bgg-container')?.querySelector('#double-offer');
  if (offerUI) offerUI.style.display = 'none';
  updateUI();
  if (params.mode === 'live') syncToServer();
}

function onDeclineDouble() {
  if (!match.cube) return;
  declineDouble(match.cube);
  const offerUI = canvas?.closest('.bgg-container')?.querySelector('#double-offer');
  if (offerUI) offerUI.style.display = 'none';
  const result = endGame(match, game.turn, 1);
  showGameResult(result);
}

// ===== BOT =====

function doBotTurn() {
  if (game.turn === myColor || game.isOver) return;

  // Bot considers doubling
  if (match.cube && canUseCube(match) && canDouble(match.cube, game.turn) && !game.dice) {
    const botPips = getPipCount(game.state, game.turn);
    const myPips = getPipCount(game.state, myColor);
    if (shouldBotDouble(match.cube, botPips, myPips, params.difficulty)) {
      offerDouble(match.cube, game.turn);
      const offerUI = canvas?.closest('.bgg-container')?.querySelector('#double-offer');
      const valEl = canvas?.closest('.bgg-container')?.querySelector('#double-val');
      if (offerUI) offerUI.style.display = '';
      if (valEl) valEl.textContent = match.cube.value * 2;
      audio.play('sfx_bg_double', 'game');
      return;
    }
  }

  // Roll dice
  audio.play('sfx_bg_dice_roll', 'game');
  isRolling = true;

  setTimeout(() => {
    isRolling = false;
    rollDice(game);
    render();

    if (game.movesLeft.length === 0) {
      setTimeout(endTurn, 600);
      return;
    }

    // Make moves one by one
    makeBotMoves(0);
  }, 500);
}

function makeBotMoves(moveIndex) {
  if (game.movesLeft.length === 0 || game.isOver) {
    if (!game.isOver) endTurn();
    else handleGameOver();
    return;
  }

  const move = getBotMove(game, params.difficulty);
  if (!move) {
    endTurn();
    return;
  }

  setTimeout(() => {
    audio.play('sfx_bg_piece_move', 'game');
    const actions = applyMove(game, move.piece.id, move.steps);
    if (actions && actions.some(a => a.type === 'hit')) {
      audio.play('sfx_bg_piece_hit', 'game');
    }
    render();
    updateUI();

    if (game.isOver) {
      handleGameOver();
    } else {
      makeBotMoves(moveIndex + 1);
    }
  }, 400);
}

// ===== GAME OVER =====

function handleGameOver() {
  const result = endGame(match, game.winner, game.score);
  audio.play(game.winner === myColor ? 'sfx_bg_win_game' : 'lose', 'game');
  showGameResult(result);
}

function showGameResult(result) {
  updateUI();

  if (result.matchOver) {
    setTimeout(() => {
      if (params.mode === 'live') syncComplete(result);
      scene.replace('backgammon-result', {
        winner: result.winner === myColor ? 'you' : 'opponent',
        scores: result.scores,
        matchLength: match.length,
        mode: params.mode
      });
    }, 1500);
  } else {
    const who = result.winner === myColor ? 'فزت' : 'البوت فاز';
    const scoreLabel = result.gameScore === 3 ? 'باكگمون!' : result.gameScore === 2 ? 'گامون!' : '';
    bus.emit('toast', { text: `${who} بالجولة ${scoreLabel} (+${result.stake})` });
    setTimeout(startNewGameRound, 2000);
  }
}

function endMatchWithWin() {
  scene.replace('backgammon-result', {
    winner: 'you',
    scores: match.scores,
    matchLength: match.length,
    mode: params.mode,
    reason: 'abandon'
  });
}

// ===== MULTIPLAYER SYNC =====

function syncToServer() {
  if (params.mode !== 'live') return;
  net.post('backgammon-match.php', {
    action: 'move',
    match_id: params.matchId,
    game_state: serializeState(game),
    match_state: getMatchState(match),
    cube: match.cube
  }).catch(() => {});
}

function syncComplete(result) {
  net.post('backgammon-match.php', {
    action: 'complete',
    match_id: params.matchId,
    winner: result.winner === myColor ? store.get('auth.userId') : 'opponent',
    reason: 'normal'
  }).catch(() => {});
}

function handleServerState(data) {
  if (!data || data.error) return;
  matchSession.markOpponentActive();

  if (data.game_state) {
    Object.assign(game, data.game_state);
    if (data.match_state) {
      match.scores = data.match_state.scores || match.scores;
    }
    if (data.cube) match.cube = data.cube;
    render();
    updateUI();
    updateTurnIndicator();
  }
}

// ===== EMOTE PANEL =====

function setupEmotePanel(el) {
  const panel = el.querySelector('#emote-panel');
  const emotes = ['🎲', '😤', '🤔', '👏', '😂', '🔥', '💀', '🫡'];
  const phrases = ['!لعبة حلوة', '!حركة ممتازة', '!حظ', '...فكّر أسرع', '?ريماتش', 'gg wp'];

  panel.innerHTML = `
    <div class="bgg-emotes">${emotes.map(e => `<button class="bgg-emote-btn">${e}</button>`).join('')}</div>
    <div class="bgg-phrases">${phrases.map(p => `<button class="bgg-phrase-btn">${p}</button>`).join('')}</div>
  `;

  panel.querySelectorAll('.bgg-emote-btn').forEach(btn => {
    btn.onclick = () => {
      audio.play('sfx_emote');
      showEmoteBubble(btn.textContent, 'bottom');
      panel.style.display = 'none';
      if (params.mode === 'live') {
        net.post('backgammon-match.php', { action: 'emote', match_id: params.matchId, emote: btn.textContent }).catch(() => {});
      }
    };
  });

  panel.querySelectorAll('.bgg-phrase-btn').forEach(btn => {
    btn.onclick = () => {
      audio.play('sfx_emote');
      showPhraseBubble(btn.textContent, 'bottom');
      panel.style.display = 'none';
    };
  });
}

function toggleEmotePanel() {
  const panel = canvas?.closest('.bgg-container')?.querySelector('#emote-panel');
  if (panel) panel.style.display = panel.style.display === 'none' ? '' : 'none';
}

function showEmoteBubble(emoteText, position) {
  const container = canvas?.closest('.bgg-container');
  if (!container) return;
  const bubble = document.createElement('div');
  bubble.className = `bgg-emote-bubble bgg-emote-${position}`;
  bubble.textContent = emoteText;
  container.appendChild(bubble);
  setTimeout(() => bubble.remove(), 2000);
}

function showPhraseBubble(text, position) {
  const container = canvas?.closest('.bgg-container');
  if (!container) return;
  const bubble = document.createElement('div');
  bubble.className = `bgg-phrase-bubble bgg-phrase-${position}`;
  bubble.textContent = text;
  container.appendChild(bubble);
  setTimeout(() => bubble.remove(), 3000);
}

function onQuit() {
  audio.play('click');
  if (params.mode === 'live') {
    net.post('backgammon-match.php', { action: 'leave', match_id: params.matchId }).catch(() => {});
    matchSession.destroy();
  }
  scene.exitGameMode();
  scene.replace('backgammon-room', { mode: 'menu' });
}

function getGameStyles() {
  return `<style>
    .bgg-container {
      position:relative;display:flex;flex-direction:column;
      height:100%;background:#0a0f14;color:#f8fafc;overflow:hidden;
    }
    .bgg-top-bar,.bgg-bottom-bar {
      display:flex;align-items:center;padding:8px 12px;gap:8px;
      background:rgba(0,0,0,0.3);
    }
    .bgg-bottom-bar { justify-content:space-between; }
    .bgg-player-card {
      display:flex;align-items:center;gap:8px;flex:1;
    }
    .bgg-avatar {
      width:36px;height:36px;border-radius:50%;
      display:flex;align-items:center;justify-content:center;
      background:rgba(255,255,255,0.06);font-size:18px;
      border:2px solid rgba(255,255,255,0.1);
    }
    .bgg-player-info { flex:1; }
    .bgg-name { font-size:13px;font-weight:700; }
    .bgg-pips { font-size:11px;color:#94a3b8; }
    .bgg-score {
      font-size:20px;font-weight:800;color:#d4940a;
      min-width:24px;text-align:center;
    }
    .bgg-board-area {
      flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
      position:relative;padding:4px;
    }
    #bg-canvas { border-radius:8px;touch-action:none; }
    .bgg-dice-area {
      position:absolute;bottom:12px;left:50%;transform:translateX(-50%);
    }
    .bgg-roll-btn {
      display:flex;align-items:center;gap:6px;
      padding:12px 24px;border-radius:14px;border:none;
      background:linear-gradient(135deg,#d4940a,#8B4513);
      color:#fff;font-size:15px;font-weight:700;cursor:pointer;
      box-shadow:0 4px 16px rgba(212,148,10,0.4);
      animation:bgRollPulse 2s ease-in-out infinite;
    }
    .bgg-roll-btn:active { transform:scale(0.93); }
    .bgg-cube-area { position:absolute;top:12px;right:12px; }
    .bgg-cube-btn {
      padding:8px 14px;border-radius:10px;border:none;
      background:rgba(139,92,246,0.2);border:1px solid rgba(139,92,246,0.5);
      color:#a78bfa;font-size:12px;font-weight:700;cursor:pointer;
    }
    .bgg-double-offer {
      position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
      background:rgba(0,0,0,0.9);border:1px solid #d4940a;border-radius:16px;
      padding:20px;text-align:center;z-index:10;
    }
    .bgg-double-offer p { margin:0 0 12px;font-size:14px; }
    .bgg-accept-btn,.bgg-decline-btn {
      padding:10px 20px;border-radius:10px;border:none;font-weight:700;cursor:pointer;margin:0 4px;
    }
    .bgg-accept-btn { background:#10b981;color:#fff; }
    .bgg-decline-btn { background:#ef4444;color:#fff; }
    .bgg-actions { display:flex;gap:6px; }
    .bgg-action-btn {
      width:36px;height:36px;border-radius:50%;border:none;
      background:rgba(255,255,255,0.06);color:#94a3b8;
      font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;
    }
    .bgg-action-btn:active { background:rgba(255,255,255,0.12); }
    .bgg-action-quit { color:#ef4444; }
    .bgg-turn-indicator {
      position:absolute;top:50%;left:4px;transform:translateY(-50%);
      writing-mode:vertical-rl;font-size:10px;font-weight:700;
      padding:6px 4px;border-radius:6px;
    }
    .bgg-my-turn { background:rgba(16,185,129,0.2);color:#10b981; }
    .bgg-opp-turn { background:rgba(239,68,68,0.15);color:#f87171; }

    .bgg-emote-panel {
      position:absolute;bottom:60px;right:12px;
      background:rgba(10,15,20,0.95);border:1px solid rgba(255,255,255,0.1);
      border-radius:14px;padding:12px;z-index:20;max-width:260px;
    }
    .bgg-emotes { display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px; }
    .bgg-emote-btn {
      width:36px;height:36px;border-radius:10px;border:none;
      background:rgba(255,255,255,0.06);font-size:20px;cursor:pointer;
    }
    .bgg-emote-btn:active { background:rgba(255,255,255,0.15); }
    .bgg-phrases { display:flex;flex-direction:column;gap:4px; }
    .bgg-phrase-btn {
      padding:6px 12px;border-radius:8px;border:none;
      background:rgba(255,255,255,0.04);color:#94a3b8;
      font-size:12px;cursor:pointer;text-align:right;
    }
    .bgg-phrase-btn:active { background:rgba(255,255,255,0.1); }

    .bgg-emote-bubble {
      position:absolute;font-size:40px;
      animation:bgEmoteFloat 2s ease-out forwards;pointer-events:none;
    }
    .bgg-emote-bottom { bottom:70px;right:50px; }
    .bgg-emote-top { top:70px;left:50px; }
    .bgg-phrase-bubble {
      position:absolute;padding:8px 14px;border-radius:12px;
      background:rgba(212,148,10,0.15);border:1px solid rgba(212,148,10,0.3);
      color:#d4940a;font-size:13px;font-weight:600;
      animation:bgPhraseFloat 3s ease-out forwards;pointer-events:none;
    }
    .bgg-phrase-bottom { bottom:70px;right:20px; }
    .bgg-phrase-top { top:70px;left:20px; }

    @keyframes bgRollPulse { 0%,100%{box-shadow:0 4px 16px rgba(212,148,10,0.4)} 50%{box-shadow:0 4px 24px rgba(212,148,10,0.7)} }
    @keyframes bgEmoteFloat { 0%{opacity:1;transform:translateY(0) scale(1)} 100%{opacity:0;transform:translateY(-60px) scale(1.3)} }
    @keyframes bgPhraseFloat { 0%{opacity:1;transform:translateY(0)} 80%{opacity:1} 100%{opacity:0;transform:translateY(-30px)} }
  </style>`;
}
