/**
 * Client-side credential validation for the login, signup and modal auth forms.
 *
 * Messages are returned already localised: language is resolved client-side via
 * the i18n context, so passing the `isDe` flag keeps callers free of dictionary
 * plumbing and matches the pattern used across the rest of the UI.
 */

/** Pragmatic address check — deliberately permissive, the server is the authority. */
export const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[A-Za-z]{2,}$/;

export const MIN_PASSWORD_LENGTH = 8;

export function validateEmail(value: string, isDe: boolean): string | null {
  const trimmed = value.trim();
  if (!trimmed) {
    return isDe ? "Bitte E-Mail-Adresse eingeben." : "Please enter your email address.";
  }
  if (!EMAIL_PATTERN.test(trimmed)) {
    return isDe
      ? "Diese E-Mail-Adresse sieht nicht gültig aus."
      : "That email address doesn't look valid.";
  }
  return null;
}

export function validateName(value: string, isDe: boolean): string | null {
  const trimmed = value.trim();
  if (!trimmed) {
    return isDe ? "Bitte Name oder Firma eingeben." : "Please enter your name or company.";
  }
  if (trimmed.length < 2) {
    return isDe ? "Mindestens 2 Zeichen." : "At least 2 characters.";
  }
  return null;
}

/**
 * On login we only check that something was typed — rejecting an existing
 * password for failing today's rules would lock legitimate users out. Strength
 * rules apply on signup only (`requireStrength`).
 */
export function validatePassword(
  value: string,
  isDe: boolean,
  options: { requireStrength?: boolean } = {}
): string | null {
  if (!value) {
    return isDe ? "Bitte Passwort eingeben." : "Please enter your password.";
  }
  if (!options.requireStrength) return null;

  if (value.length < MIN_PASSWORD_LENGTH) {
    return isDe
      ? `Mindestens ${MIN_PASSWORD_LENGTH} Zeichen.`
      : `At least ${MIN_PASSWORD_LENGTH} characters.`;
  }
  if (scorePassword(value).score < 2) {
    return isDe
      ? "Zu schwach — kombiniere Groß-/Kleinschreibung, Ziffern oder Sonderzeichen."
      : "Too weak — mix upper/lowercase letters, digits or symbols.";
  }
  return null;
}

export interface PasswordChecks {
  length: boolean;
  mixedCase: boolean;
  digit: boolean;
  symbol: boolean;
}

export interface PasswordScore {
  /** 0 = empty/too short, 4 = every criterion met. */
  score: 0 | 1 | 2 | 3 | 4;
  checks: PasswordChecks;
}

export function scorePassword(value: string): PasswordScore {
  const checks: PasswordChecks = {
    length: value.length >= MIN_PASSWORD_LENGTH,
    mixedCase: /[a-z]/.test(value) && /[A-Z]/.test(value),
    digit: /\d/.test(value),
    symbol: /[^A-Za-z0-9]/.test(value),
  };

  // Length is the gate: without it nothing else counts as strength.
  if (!checks.length) {
    return { score: value.length > 0 ? 1 : 0, checks };
  }

  const extras = [checks.mixedCase, checks.digit, checks.symbol].filter(Boolean).length;
  const score = Math.min(4, 1 + extras) as PasswordScore["score"];
  return { score, checks };
}

export function passwordScoreLabel(score: PasswordScore["score"], isDe: boolean): string {
  const de = ["", "Zu schwach", "Ausreichend", "Stark", "Sehr stark"];
  const en = ["", "Too weak", "Fair", "Strong", "Very strong"];
  return (isDe ? de : en)[score] ?? "";
}
