/**
 * Suggestion NON BLOQUANTE de correction d'email : on n'empêche jamais l'envoi,
 * on propose juste une correction quand le domaine ressemble à une faute de frappe
 * d'un domaine courant (gmial.com → gmail.com, .cm → .com, etc.).
 */

const POPULAR_DOMAINS = [
  'gmail.com',
  'googlemail.com',
  'outlook.com',
  'outlook.fr',
  'hotmail.com',
  'hotmail.fr',
  'live.fr',
  'live.com',
  'yahoo.com',
  'yahoo.fr',
  'icloud.com',
  'orange.fr',
  'wanadoo.fr',
  'free.fr',
  'sfr.fr',
  'laposte.net',
  'bbox.fr',
];

const TLD_FIXES: Record<string, string> = {
  con: 'com',
  cm: 'com',
  cmo: 'com',
  ocm: 'com',
  vom: 'com',
  xom: 'com',
  comm: 'com',
  co: 'com',
  net: 'net',
  fr: 'fr',
  frr: 'fr',
  ff: 'fr',
};

function levenshtein(a: string, b: string): number {
  const m = a.length;
  const n = b.length;
  const dp = Array.from({ length: m + 1 }, () => new Array<number>(n + 1).fill(0));
  for (let i = 0; i <= m; i++) dp[i][0] = i;
  for (let j = 0; j <= n; j++) dp[0][j] = j;
  for (let i = 1; i <= m; i++) {
    for (let j = 1; j <= n; j++) {
      const cost = a[i - 1] === b[j - 1] ? 0 : 1;
      dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost);
    }
  }
  return dp[m][n];
}

/**
 * Renvoie un email corrigé suggéré, ou null s'il n'y a rien à suggérer.
 */
export function suggestEmail(email: string): string | null {
  const value = email.trim().toLowerCase();
  const at = value.lastIndexOf('@');
  if (at < 1 || at === value.length - 1) return null;

  const local = value.slice(0, at);
  let domain = value.slice(at + 1);
  if (!domain.includes('.')) return null;

  // 1) Correction du TLD évident (gmail.con → gmail.com)
  const lastDot = domain.lastIndexOf('.');
  const base = domain.slice(0, lastDot);
  const tld = domain.slice(lastDot + 1);
  if (TLD_FIXES[tld] && TLD_FIXES[tld] !== tld) {
    domain = `${base}.${TLD_FIXES[tld]}`;
  }

  // 2) Domaine déjà correct ?
  if (POPULAR_DOMAINS.includes(domain)) {
    const suggested = `${local}@${domain}`;
    return suggested !== value ? suggested : null;
  }

  // 3) Plus proche domaine courant (distance ≤ 2)
  let best: string | null = null;
  let bestDist = Infinity;
  for (const candidate of POPULAR_DOMAINS) {
    const d = levenshtein(domain, candidate);
    if (d < bestDist) {
      bestDist = d;
      best = candidate;
    }
  }
  if (best && bestDist > 0 && bestDist <= 2) {
    return `${local}@${best}`;
  }

  // 4) Si seul le TLD a été corrigé en (2/3 non déclenchés)
  const corrected = `${local}@${domain}`;
  return corrected !== value ? corrected : null;
}
