import type { SolverStep } from '@wordle/shared';

function getFeedback(target: string, guess: string): string {
  const tu = target.toLowerCase(), gu = guess.toLowerCase();
  const counts: Record<string, number> = {};
  for (const ch of tu) counts[ch] = (counts[ch] ?? 0) + 1;
  const r: string[] = Array(5).fill('x');
  for (let i = 0; i < 5; i++) { if (gu[i] === tu[i]) { r[i] = 'g'; counts[gu[i]]--; } }
  for (let i = 0; i < 5; i++) { if (r[i] === 'g') continue; if ((counts[gu[i]] ?? 0) > 0) { r[i] = 'y'; counts[gu[i]]--; } }
  return r.join('');
}

function matchesFeedback(c: string, g: string, fb: string): boolean { return getFeedback(c, g) === fb; }

export function solveGreedy(target: string, allWords: string[], maxAttempts = 6): { attempts: number; steps: SolverStep[] } {
  let candidates = [...allWords];
  const STARTERS = ['crane','slate','arise','stare'];
  const steps: SolverStep[] = [];

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const guess = attempt === 1 ? (STARTERS.find((w) => allWords.includes(w)) ?? allWords[0]) : candidates[0];
    const fb = getFeedback(target, guess);
    steps.push({ guess, colors: fb.split('') });
    if (fb === 'ggggg') return { attempts: attempt, steps };

    candidates = candidates.filter((c) => matchesFeedback(c, guess, fb));
    if (candidates.length === 0) return { attempts: maxAttempts + 1, steps };

    if (attempt < maxAttempts) {
      const greens: number[] = [];
      for (let i = 0; i < 5; i++) if (fb[i] === 'g') greens.push(i);
      if (greens.length > 0) {
        candidates.sort((a, b) => {
          let am = 0, bm = 0;
          for (const p of greens) { if (a[p] === guess[p]) am++; if (b[p] === guess[p]) bm++; }
          return bm - am;
        });
      }
    }
  }

  return { attempts: maxAttempts + 1, steps };
}
