/** Validações de conta (compartilhadas por web, app e backend). Mensagens em português, prontas para exibir. */
export type Errors<K extends string> = Partial<Record<K, string>>;
export const isEmail = (s: string) => /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(s.trim());

export interface Strength { score: 0 | 1 | 2 | 3 | 4; label: string; ok: boolean }
export function passwordStrength(p: string): Strength {
  let score = 0;
  if (p.length >= 8) score++;
  if (/[a-z]/.test(p) && /[A-Z]/.test(p)) score++;
  if (/\d/.test(p)) score++;
  if (/[^A-Za-z0-9]/.test(p) || p.length >= 12) score++;
  const s = (p.length < 8 ? Math.min(score, 1) : score) as Strength["score"];
  return { score: s, label: ["Muito fraca", "Fraca", "Razoável", "Boa", "Forte"][s]!, ok: p.length >= 8 && s >= 2 };
}
export function validateLogin(v: { email: string; senha: string }): Errors<"email" | "senha"> {
  const e: Errors<"email" | "senha"> = {};
  if (!v.email.trim()) e.email = "Informe seu e-mail."; else if (!isEmail(v.email)) e.email = "Informe um e-mail válido, como nome@email.com.";
  if (!v.senha) e.senha = "Informe sua senha.";
  return e;
}
export function validateRegister(v: { nome: string; email: string; senha: string; confirmar: string; aceite: boolean }): Errors<"nome" | "email" | "senha" | "confirmar" | "aceite"> {
  const e: Errors<"nome" | "email" | "senha" | "confirmar" | "aceite"> = {};
  if (v.nome.trim().split(/\s+/).filter(Boolean).length < 2) e.nome = "Informe nome e sobrenome.";
  if (!v.email.trim()) e.email = "Informe seu e-mail."; else if (!isEmail(v.email)) e.email = "Informe um e-mail válido, como nome@email.com.";
  if (!passwordStrength(v.senha).ok) e.senha = "Use pelo menos 8 caracteres, com letras maiúsculas e minúsculas ou números.";
  if (v.confirmar !== v.senha) e.confirmar = "As senhas não são iguais.";
  if (!v.aceite) e.aceite = "Aceite os Termos de Uso e a Política de Privacidade para continuar.";
  return e;
}
export const hasErrors = (e: object) => Object.keys(e).length > 0;
export function isCPF(raw: string): boolean {
  const d = raw.replace(/\D/g, ""); if (d.length !== 11 || /^(\d)\1+$/.test(d)) return false;
  const dv = (n: number) => { let s = 0; for (let i = 0; i < n; i++) s += Number(d[i]) * (n + 1 - i); const r = (s * 10) % 11; return r === 10 ? 0 : r; };
  return dv(9) === Number(d[9]) && dv(10) === Number(d[10]);
}
export function isCNPJ(raw: string): boolean {
  const d = raw.replace(/\D/g, ""); if (d.length !== 14 || /^(\d)\1+$/.test(d)) return false;
  const dv = (n: number) => { const w = n === 12 ? [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2] : [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; let s = 0; for (let i = 0; i < n; i++) s += Number(d[i]) * w[i]!; const r = s % 11; return r < 2 ? 0 : 11 - r; };
  return dv(12) === Number(d[12]) && dv(13) === Number(d[13]);
}
export const isCEP = (s: string) => /^\d{5}-?\d{3}$/.test(s.trim());
