/* ------------------------
   5. GAME LOGIC
   ------------------------ */
function addNewTile() {
  const empty = [];
  for (let r = 0; r < 4; r++) {
    for (let c = 0; c < 4; c++) {
      if (board[r][c] === 0) empty.push({ r, c });
    }
  }

  if (empty.length === 0) return false;

  const spot = empty[Math.floor(Math.random() * empty.length)];
  board[spot.r][spot.c] = 2;

  const tile = document.getElementById(`${spot.r}-${spot.c}`);
  if (tile) {
    tile.classList.add("new");
    playSound(audio.pop);
    setTimeout(() => tile.classList.remove("new"), 300);
  }
  updateTile(spot.r, spot.c, 2);
  return true;
}

function filterZero(row) {
  return row.filter(n => n !== 0);
}

function slide(row) {
  row = filterZero(row);
  let mergedThisMove = false;
  let mergedPositions = [];
  let mergeCount = 0;

  for (let i = 0; i < row.length - 1; i++) {
    if (row[i] === row[i + 1]) {
      row[i] = row[i] * 2;
      
      playSound(audio.merge);
      
      if (navigator.vibrate) {
        navigator.vibrate([80, 20, 80]);
      }

      currentScore += row[i];
      row[i + 1] = 0;
      mergedThisMove = true;
      mergedPositions.push(i);
      mergeCount++;
    }
  }

  row = filterZero(row);
  while (row.length < 4) row.push(0);
  return { row, merged: mergedThisMove, mergedPositions, mergeCount };
}

function arraysEqual(a, b) {
  return a.length === b.length && a.every((v, i) => v === b[i]);
}

/* Move functions */
function moveLeft() {
  let moved = false;
  let mergedCells = [];
  mergesInCurrentMove = 0;
  
  for (let r = 0; r < 4; r++) {
    const { row: newRow, mergedPositions, mergeCount } = slide(board[r]);
    if (!arraysEqual(newRow, board[r])) moved = true;
    board[r] = newRow;
    
    mergesInCurrentMove += mergeCount;
    
    if (mergedPositions && mergedPositions.length > 0) {
      mergedPositions.forEach(c => {
        mergedCells.push({ r, c });
      });
    }
  }
  
  if (moved) {
    refreshBoard();
    triggerComboEffect(mergedCells, mergesInCurrentMove);
  }
  return moved;
}

function moveRight() {
  let moved = false;
  let mergedCells = [];
  mergesInCurrentMove = 0;
  
  for (let r = 0; r < 4; r++) {
    let reversed = [...board[r]].reverse();
    const { row: slid, mergedPositions, mergeCount } = slide(reversed);
    let newRow = slid.reverse();
    if (!arraysEqual(newRow, board[r])) moved = true;
    board[r] = newRow;
    
    mergesInCurrentMove += mergeCount;
    
    if (mergedPositions && mergedPositions.length > 0) {
      mergedPositions.forEach(pos => {
        const c = 3 - pos;
        mergedCells.push({ r, c });
      });
    }
  }
  
  if (moved) {
    refreshBoard();
    triggerComboEffect(mergedCells, mergesInCurrentMove);
  }
  return moved;
}

function moveUp() {
  let moved = false;
  let mergedCells = [];
  mergesInCurrentMove = 0;
  
  for (let c = 0; c < 4; c++) {
    const col = [board[0][c], board[1][c], board[2][c], board[3][c]];
    const { row: newCol, mergedPositions, mergeCount } = slide(col);
    for (let r = 0; r < 4; r++) {
      if (board[r][c] !== newCol[r]) moved = true;
      board[r][c] = newCol[r];
    }
    
    mergesInCurrentMove += mergeCount;
    
    if (mergedPositions && mergedPositions.length > 0) {
      mergedPositions.forEach(r => {
        mergedCells.push({ r, c });
      });
    }
  }
  
  if (moved) {
    refreshBoard();
    triggerComboEffect(mergedCells, mergesInCurrentMove);
  }
  return moved;
}

function moveDown() {
  let moved = false;
  let mergedCells = [];
  mergesInCurrentMove = 0;
  
  for (let c = 0; c < 4; c++) {
    const col = [board[3][c], board[2][c], board[1][c], board[0][c]];
    const { row: slid, mergedPositions, mergeCount } = slide(col);
    const newCol = slid.reverse();
    for (let r = 0; r < 4; r++) {
      if (board[r][c] !== newCol[r]) moved = true;
      board[r][c] = newCol[r];
    }
    
    mergesInCurrentMove += mergeCount;
    
    if (mergedPositions && mergedPositions.length > 0) {
      mergedPositions.forEach(pos => {
        const r = 3 - pos;
        mergedCells.push({ r, c });
      });
    }
  }
  
  if (moved) {
    refreshBoard();
    triggerComboEffect(mergedCells, mergesInCurrentMove);
  }
  return moved;
}

function canMove() {
  for (let r = 0; r < 4; r++) {
    for (let c = 0; c < 4; c++) {
      if (board[r][c] === 0) return true;
    }
  }
  
  for (let r = 0; r < 4; r++) {
    for (let c = 0; c < 4; c++) {
      const current = board[r][c];
      if (c < 3 && board[r][c + 1] === current) return true;
      if (r < 3 && board[r + 1][c] === current) return true;
    }
  }
  return false;
}