import type { SolverReplay } from '../word-bank.js';
import { solveEntropy } from './entropy.js';
import { solveFrequency } from './frequency.js';
import { solveVowelFirst } from './vowel-first.js';
import { solveGreedy } from './greedy.js';

export { solveEntropy, solveFrequency, solveVowelFirst, solveGreedy };

const MAX_ATTEMPTS = 6;

interface SolverResult {
  attempts: number;
  steps: string[];
}

/** 3 fast solvers used for immediate API response (~20ms per target). */
const FAST_SOLVERS: Array<{ name: string; fn: (t: string, w: string[], m: number) => SolverResult }> = [
  { name: 'Frequency', fn: solveFrequency },
  { name: 'Vowel First', fn: solveVowelFirst },
  { name: 'Greedy', fn: solveGreedy },
];

/** All 4 solvers including entropy — used for background pre-computation (~14s per target). */
const ALL_SOLVERS: Array<{ name: string; fn: (t: string, w: string[], m: number) => SolverResult }> = [
  { name: 'Entropy', fn: solveEntropy },
  ...FAST_SOLVERS,
];

/** A cached replay+difficulty result, keyed by word ID. */
export interface CachedResult {
  difficulty: number;
  replays: SolverReplay[];
}

function buildReplays(
  solvers: Array<{ name: string; fn: (t: string, w: string[], m: number) => SolverResult }>,
  target: string,
  allWords: string[],
): CachedResult {
  const results = solvers.map((s) => ({
    name: s.name,
    ...s.fn(target, allWords, MAX_ATTEMPTS),
  }));

  // Difficulty: solvers that fail (>6 attempts) count as 10 attempts.
  const weightedSum = results.reduce((sum, r) => sum + (r.attempts <= MAX_ATTEMPTS ? r.attempts : 10), 0);
  const difficulty = Math.round((weightedSum / results.length) * 100) / 100;

  // Show all solvers on the results page, even those that failed to solve.
  const replays: SolverReplay[] = results.map((r) => ({
    solver: r.name,
    steps: r.steps,
  }));

  return { difficulty, replays };
}

/** Fast 3-solver computation for immediate API response (~20ms). */
export function computeReplays(target: string, allWords: string[]): CachedResult {
  return buildReplays(FAST_SOLVERS, target, allWords);
}

/** Full 4-solver computation including entropy — slower (~14s) but richer replays. */
export function computeReplaysFull(target: string, allWords: string[]): CachedResult {
  return buildReplays(ALL_SOLVERS, target, allWords);
}
