import { FIELD_LIMITS } from '@/lib/validation/limits';

const EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;

/**
 * Strict single-recipient email. Rejects header injection, lists, and spaces.
 */
export function parseStrictEmail(value: unknown): string | null {
  if (typeof value !== 'string') return null;
  const trimmed = value.trim();
  if (!trimmed || trimmed.length > FIELD_LIMITS.email) return null;
  if (/[\s,;<>\r\n]/.test(trimmed)) return null;
  if (trimmed.includes('..')) return null;
  if ((trimmed.match(/@/g) ?? []).length !== 1) return null;
  if (!EMAIL_RE.test(trimmed)) return null;
  return trimmed;
}

/** Accept `user@x.com` or `Name <user@x.com>` (env SMTP_FROM / ADMIN_EMAIL). */
export function parseMailAddress(value: unknown): string | null {
  if (typeof value !== 'string') return null;
  const trimmed = value.trim();
  const angled = trimmed.match(/^[^<>]*<([^<>]+)>$/);
  if (angled) return parseStrictEmail(angled[1]);
  return parseStrictEmail(trimmed);
}

/** Split comma/semicolon lists then parse each address. */
export function parseRecipientList(values: string[]): string[] {
  const out: string[] = [];
  const seen = new Set<string>();
  for (const value of values) {
    for (const part of value.split(/[,;]/)) {
      const parsed = parseMailAddress(part);
      if (!parsed) continue;
      const key = parsed.toLowerCase();
      if (seen.has(key)) continue;
      seen.add(key);
      out.push(parsed);
    }
  }
  return out;
}

/** Strip CR/LF/commas from values that land in SMTP headers. */
export function sanitizeHeaderValue(value: string): string {
  return value
    .replace(/[\r\n,]/g, '')
    .trim()
    .slice(0, FIELD_LIMITS.header);
}
