export function createDominoSet() {
  const tiles = [];
  for (let i = 0; i <= 6; i++) {
    for (let j = i; j <= 6; j++) {
      tiles.push({ left: i, right: j, id: `${i}-${j}` });
    }
  }
  return tiles;
}

export function shuffle(tiles) {
  const arr = [...tiles];
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
}

export function dealHands(tiles, numPlayers, handSize = 7) {
  const hands = [];
  let idx = 0;
  for (let p = 0; p < numPlayers; p++) {
    hands.push(tiles.slice(idx, idx + handSize));
    idx += handSize;
  }
  const boneyard = tiles.slice(idx);
  return { hands, boneyard };
}

export function canPlay(tile, leftEnd, rightEnd) {
  if (leftEnd === null) return true;
  return tile.left === leftEnd || tile.right === leftEnd ||
         tile.left === rightEnd || tile.right === rightEnd;
}

export function getValidMoves(hand, leftEnd, rightEnd) {
  if (leftEnd === null) return hand.map(t => ({ tile: t, end: 'first' }));
  const moves = [];
  for (const tile of hand) {
    if (tile.left === leftEnd || tile.right === leftEnd) {
      moves.push({ tile, end: 'left' });
    }
    if (tile.left === rightEnd || tile.right === rightEnd) {
      if (!moves.some(m => m.tile.id === tile.id && m.end !== 'left')) {
        moves.push({ tile, end: 'right' });
      }
    }
  }
  return moves;
}

export function placeTile(chain, tile, end) {
  if (chain.length === 0) {
    return { chain: [tile], leftEnd: tile.left, rightEnd: tile.right };
  }

  const newChain = [...chain];
  let { leftEnd, rightEnd } = getEnds(chain);

  if (end === 'left') {
    if (tile.right === leftEnd) {
      newChain.unshift(tile);
      leftEnd = tile.left;
    } else if (tile.left === leftEnd) {
      newChain.unshift({ left: tile.right, right: tile.left, id: tile.id });
      leftEnd = tile.right;
    }
  } else {
    if (tile.left === rightEnd) {
      newChain.push(tile);
      rightEnd = tile.right;
    } else if (tile.right === rightEnd) {
      newChain.push({ left: tile.right, right: tile.left, id: tile.id });
      rightEnd = tile.left;
    }
  }

  return { chain: newChain, leftEnd, rightEnd };
}

export function getEnds(chain) {
  if (chain.length === 0) return { leftEnd: null, rightEnd: null };
  return { leftEnd: chain[0].left, rightEnd: chain[chain.length - 1].right };
}

export function countPips(hand) {
  return hand.reduce((sum, t) => sum + t.left + t.right, 0);
}

export function isDouble(tile) {
  return tile.left === tile.right;
}

export function checkRoundEnd(hands, boneyard, chain) {
  if (hands.some(h => h.length === 0)) return true;
  if (boneyard.length > 0) return false;
  const { leftEnd, rightEnd } = getEnds(chain);
  return hands.every(h => getValidMoves(h, leftEnd, rightEnd).length === 0);
}

export function getRoundWinner(hands) {
  let minPips = Infinity;
  let winner = -1;
  hands.forEach((hand, i) => {
    const pips = countPips(hand);
    if (pips < minPips) { minPips = pips; winner = i; }
  });
  return { winner, scores: hands.map(countPips) };
}

export function scoreRound(hands, winnerIdx) {
  let total = 0;
  hands.forEach((hand, i) => {
    if (i !== winnerIdx) total += countPips(hand);
  });
  return total;
}

export function hasValidMove(hand, leftEnd, rightEnd) {
  if (leftEnd === null) return hand.length > 0;
  return hand.some(t =>
    t.left === leftEnd || t.right === leftEnd ||
    t.left === rightEnd || t.right === rightEnd
  );
}

export function determinePlayEnd(tile, leftEnd, rightEnd) {
  if (leftEnd === null) return 'right';
  const playsLeft = tile.left === leftEnd || tile.right === leftEnd;
  const playsRight = tile.left === rightEnd || tile.right === rightEnd;
  if (playsLeft && playsRight) return 'both';
  if (playsLeft) return 'left';
  if (playsRight) return 'right';
  return null;
}
