import type { TargetWord, CachedResult } from '@wordle/shared';

/**
 * Select a target word weighted by proximity to the player's skill level.
 *
 * Algorithm:
 * 1. Compute a weight for each target based on how close its difficulty
 *    is to the player's skill (Gaussian-like: 1 / (1 + (diff - skill)^2))
 * 2. Pick randomly, weighted by those weights.
 *
 * Uncached words get default difficulty 3.0 — they converge to real values
 * as words get played and cached.
 */
export function selectPlayAgainWord(
  targets: TargetWord[],
  skillMetric: number,
  cache: Map<number, CachedResult>,
): TargetWord {
  if (targets.length === 0) {
    throw new Error('No target words available');
  }

  // Compute weights: closer difficulty = higher weight
  const weights = targets.map((t) => {
    const diff = cache.get(t.id)?.difficulty ?? 3.0;
    const delta = diff - skillMetric;
    return 1 / (1 + delta * delta);
  });

  // Weighted random selection
  const totalWeight = weights.reduce((sum, w) => sum + w, 0);
  let r = Math.random() * totalWeight;

  for (let i = 0; i < targets.length; i++) {
    r -= weights[i];
    if (r <= 0) {
      return targets[i];
    }
  }

  // Fallback (floating point edge case)
  return targets[targets.length - 1];
}
