const BOARD_SIZE = 52;
const HOME_STRETCH = 6;
// Must match board-map.js START_SQUARES exactly
const START_POSITIONS = [0, 13, 26, 39];
const SAFE_SQUARES = [0, 8, 13, 21, 26, 34, 39, 47];

// Player order: 0=Red(BL), 1=Green(TL), 2=Yellow(TR), 3=Blue(BR)
export const COLORS = ['red', 'green', 'yellow', 'blue'];
export const COLOR_CSS = ['#E53935', '#43A047', '#FDD835', '#1E88E5'];

export function createGame(numPlayers = 4) {
  const players = [];
  for (let i = 0; i < numPlayers; i++) {
    players.push({
      color: COLORS[i],
      pieces: [
        { id: `${i}-0`, pos: -1, finished: false },
        { id: `${i}-1`, pos: -1, finished: false },
        { id: `${i}-2`, pos: -1, finished: false },
        { id: `${i}-3`, pos: -1, finished: false }
      ],
      finished: false,
      consecutiveSixes: 0
    });
  }
  return {
    players,
    currentPlayer: 0,
    diceValue: null,
    rolled: false,
    numPlayers,
    winners: [],
    gameOver: false,
    extraTurn: false
  };
}

export function rollDice() {
  return Math.floor(Math.random() * 6) + 1;
}

export function getValidMoves(game, playerIdx, dice) {
  const player = game.players[playerIdx];
  const moves = [];

  for (const piece of player.pieces) {
    if (piece.finished) continue;

    if (piece.pos === -1) {
      // Can only enter board on a 6
      if (dice === 6) {
        moves.push({ pieceId: piece.id, from: -1, to: 0, type: 'enter' });
      }
    } else {
      const newPos = piece.pos + dice;

      // Exact finish: must land exactly on position 52+6=58
      if (newPos === BOARD_SIZE + HOME_STRETCH) {
        moves.push({ pieceId: piece.id, from: piece.pos, to: newPos, type: 'finish' });
      } else if (newPos < BOARD_SIZE + HOME_STRETCH) {
        if (newPos >= BOARD_SIZE) {
          // Entering home column — always safe, can't be captured
          moves.push({ pieceId: piece.id, from: piece.pos, to: newPos, type: 'home' });
        } else {
          // Moving on shared path
          const globalPos = (newPos + START_POSITIONS[playerIdx]) % BOARD_SIZE;
          const captured = checkCapture(game, playerIdx, globalPos);
          moves.push({ pieceId: piece.id, from: piece.pos, to: newPos, type: captured ? 'capture' : 'move' });
        }
      }
      // If newPos > 58, move is invalid (overshoot) — not added
    }
  }

  return moves;
}

export function applyMove(game, playerIdx, move) {
  const player = game.players[playerIdx];
  const piece = player.pieces.find(p => p.id === move.pieceId);
  if (!piece) return game;

  game.extraTurn = false;

  if (move.type === 'enter') {
    piece.pos = 0;
    // Check for capture at start position
    const globalPos = START_POSITIONS[playerIdx];
    captureAt(game, playerIdx, globalPos);
    game.extraTurn = true; // 6 gives extra turn
  } else if (move.type === 'finish') {
    piece.pos = move.to;
    piece.finished = true;
    game.extraTurn = true; // Finishing gives extra turn
    // Check if player won
    if (player.pieces.every(p => p.finished)) {
      player.finished = true;
      game.winners.push(playerIdx);
      if (game.winners.length >= game.numPlayers - 1) {
        game.gameOver = true;
      }
    }
  } else if (move.type === 'capture') {
    piece.pos = move.to;
    const globalPos = (move.to + START_POSITIONS[playerIdx]) % BOARD_SIZE;
    captureAt(game, playerIdx, globalPos);
    game.extraTurn = true; // Capture gives extra turn
  } else if (move.type === 'home') {
    piece.pos = move.to;
  } else {
    piece.pos = move.to;
  }

  // Rolling 6 always gives extra turn
  if (game.diceValue === 6) {
    game.extraTurn = true;
    player.consecutiveSixes = (player.consecutiveSixes || 0) + 1;
    // Three consecutive 6s = lose turn (piece that last moved goes back home)
    if (player.consecutiveSixes >= 3) {
      piece.pos = -1;
      piece.finished = false;
      player.consecutiveSixes = 0;
      game.extraTurn = false;
    }
  } else {
    player.consecutiveSixes = 0;
  }

  return game;
}

export function nextTurn(game) {
  if (game.extraTurn) {
    game.extraTurn = false;
    return;
  }
  do {
    game.currentPlayer = (game.currentPlayer + 1) % game.numPlayers;
  } while (game.players[game.currentPlayer].finished && !game.gameOver);
}

function checkCapture(game, playerIdx, globalPos) {
  // Can't capture on safe squares
  if (SAFE_SQUARES.includes(globalPos)) return false;

  for (let i = 0; i < game.numPlayers; i++) {
    if (i === playerIdx) continue;
    for (const piece of game.players[i].pieces) {
      if (piece.pos === -1 || piece.finished) continue;
      // Only check pieces on the shared path (pos < 52)
      if (piece.pos >= BOARD_SIZE) continue;
      const theirGlobal = (piece.pos + START_POSITIONS[i]) % BOARD_SIZE;
      if (theirGlobal === globalPos) return true;
    }
  }
  return false;
}

function captureAt(game, playerIdx, globalPos) {
  if (SAFE_SQUARES.includes(globalPos)) return;

  for (let i = 0; i < game.numPlayers; i++) {
    if (i === playerIdx) continue;
    for (const piece of game.players[i].pieces) {
      if (piece.pos === -1 || piece.finished) continue;
      if (piece.pos >= BOARD_SIZE) continue; // Can't capture in home column
      const theirGlobal = (piece.pos + START_POSITIONS[i]) % BOARD_SIZE;
      if (theirGlobal === globalPos) {
        piece.pos = -1; // Send back to home
      }
    }
  }
}

export function getBotMove(game, playerIdx, dice) {
  const moves = getValidMoves(game, playerIdx, dice);
  if (moves.length === 0) return null;

  // Priority: finish > capture > enter > advance furthest
  const finishes = moves.filter(m => m.type === 'finish');
  if (finishes.length > 0) return finishes[0];

  const captures = moves.filter(m => m.type === 'capture');
  if (captures.length > 0) return captures[0];

  const enters = moves.filter(m => m.type === 'enter');
  if (enters.length > 0) return enters[0];

  // Advance the piece that's furthest along (closest to home)
  const sorted = moves.sort((a, b) => b.to - a.to);
  return sorted[0];
}
