import { getValidMoves, isDouble, countPips, getEnds } from './rules.js';

const PERSONALITIES = {
  beginner: { thinkMin: 1200, thinkMax: 2500, strategy: 'random', emoteChance: 0.1 },
  intermediate: { thinkMin: 800, thinkMax: 1800, strategy: 'pip_priority', emoteChance: 0.15 },
  expert: { thinkMin: 500, thinkMax: 1200, strategy: 'strategic', emoteChance: 0.08 }
};

export function getPersonality(level = 'intermediate') {
  return PERSONALITIES[level] || PERSONALITIES.intermediate;
}

export function getThinkDelay(personality) {
  const { thinkMin, thinkMax } = personality;
  return thinkMin + Math.random() * (thinkMax - thinkMin);
}

export function pickMove(hand, leftEnd, rightEnd, chain, opponentCount, personality) {
  const moves = getValidMoves(hand, leftEnd, rightEnd);
  if (moves.length === 0) return null;
  if (moves.length === 1) return moves[0];

  switch (personality.strategy) {
    case 'random':
      return moves[Math.floor(Math.random() * moves.length)];

    case 'pip_priority':
      return pickByPipPriority(moves);

    case 'strategic':
      return pickStrategic(moves, hand, leftEnd, rightEnd, chain, opponentCount);

    default:
      return moves[0];
  }
}

function pickByPipPriority(moves) {
  moves.sort((a, b) => {
    const aVal = a.tile.left + a.tile.right;
    const bVal = b.tile.left + b.tile.right;
    return bVal - aVal;
  });
  return moves[0];
}

function pickStrategic(moves, hand, leftEnd, rightEnd, chain, opponentCount) {
  const scored = moves.map(move => {
    let score = 0;

    if (isDouble(move.tile)) score += 4;

    score += (move.tile.left + move.tile.right) * 0.6;

    const remaining = hand.filter(t => t.id !== move.tile.id);
    const simResult = simulateEnds(chain, move);
    const futureCount = countFuturePlays(remaining, simResult.leftEnd, simResult.rightEnd);
    score += futureCount * 2.5;

    if (opponentCount <= 2) {
      const valueCounts = countValueInHand(remaining);
      const endValues = [simResult.leftEnd, simResult.rightEnd];
      for (const v of endValues) {
        if (v !== null && (valueCounts[v] || 0) >= 2) {
          score += 1;
        }
      }
    }

    return { move, score };
  });

  scored.sort((a, b) => b.score - a.score);
  return scored[0].move;
}

function simulateEnds(chain, move) {
  const { tile, end } = move;

  if (chain.length === 0) {
    return { leftEnd: tile.left, rightEnd: tile.right };
  }

  const currentEnds = getEnds(chain);
  let { leftEnd, rightEnd } = currentEnds;

  if (end === 'left') {
    if (tile.right === leftEnd) leftEnd = tile.left;
    else if (tile.left === leftEnd) leftEnd = tile.right;
  } else {
    if (tile.left === rightEnd) rightEnd = tile.right;
    else if (tile.right === rightEnd) rightEnd = tile.left;
  }

  return { leftEnd, rightEnd };
}

function countFuturePlays(hand, leftEnd, rightEnd) {
  let count = 0;
  for (const t of hand) {
    if (t.left === leftEnd || t.right === leftEnd ||
        t.left === rightEnd || t.right === rightEnd) {
      count++;
    }
  }
  return count;
}

function countValueInHand(hand) {
  const counts = {};
  for (const t of hand) {
    counts[t.left] = (counts[t.left] || 0) + 1;
    counts[t.right] = (counts[t.right] || 0) + 1;
  }
  return counts;
}

export function shouldEmote(personality) {
  return Math.random() < personality.emoteChance;
}

export function getRandomEmote() {
  const emotes = ['laugh', 'think', 'wow', 'angry', 'gg'];
  return emotes[Math.floor(Math.random() * emotes.length)];
}
