/**
 * Utilitários para autenticação e criptografia
 * Usando Web Crypto API para criptografia segura
 */

/**
 * Gera um hash seguro de senha usando PBKDF2
 */
export async function hashPassword(password: string): Promise<string> {
  const encoder = new TextEncoder();
  const data = encoder.encode(password);
  
  // Gerar salt aleatório
  const salt = crypto.getRandomValues(new Uint8Array(16));
  
  // Importar a senha como chave
  const keyMaterial = await crypto.subtle.importKey(
    "raw",
    data,
    "PBKDF2",
    false,
    ["deriveBits"]
  );
  
  // Derivar a chave usando PBKDF2
  const derivedBits = await crypto.subtle.deriveBits(
    {
      name: "PBKDF2",
      salt: salt,
      iterations: 100000,
      hash: "SHA-256",
    },
    keyMaterial,
    256
  );
  
  // Combinar salt + hash
  const hashArray = new Uint8Array(derivedBits);
  const combined = new Uint8Array(salt.length + hashArray.length);
  combined.set(salt);
  combined.set(hashArray, salt.length);
  
  // Converter para base64
  return btoa(String.fromCharCode(...combined));
}

/**
 * Verifica se uma senha corresponde ao hash
 */
export async function verifyPassword(
  password: string,
  hash: string
): Promise<boolean> {
  try {
    // Decodificar o hash de base64
    const combined = Uint8Array.from(atob(hash), (c) => c.charCodeAt(0));
    
    // Extrair salt e hash
    const salt = combined.slice(0, 16);
    const storedHash = combined.slice(16);
    
    // Gerar hash da senha fornecida
    const encoder = new TextEncoder();
    const data = encoder.encode(password);
    
    const keyMaterial = await crypto.subtle.importKey(
      "raw",
      data,
      "PBKDF2",
      false,
      ["deriveBits"]
    );
    
    const derivedBits = await crypto.subtle.deriveBits(
      {
        name: "PBKDF2",
        salt: salt,
        iterations: 100000,
        hash: "SHA-256",
      },
      keyMaterial,
      256
    );
    
    const newHash = new Uint8Array(derivedBits);
    
    // Comparar os hashes
    if (newHash.length !== storedHash.length) {
      return false;
    }
    
    for (let i = 0; i < newHash.length; i++) {
      if (newHash[i] !== storedHash[i]) {
        return false;
      }
    }
    
    return true;
  } catch (error) {
    console.error("Erro ao verificar senha:", error);
    return false;
  }
}

/**
 * Gera um token aleatório seguro
 */
export function generateToken(): string {
  const array = new Uint8Array(32);
  crypto.getRandomValues(array);
  return btoa(String.fromCharCode(...array))
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=/g, "");
}

/**
 * Valida formato de matrícula (apenas números)
 */
export function validarMatricula(matricula: string): boolean {
  return /^\d+$/.test(matricula) && matricula.length >= 3;
}

/**
 * Valida formato de senha (alfanuméricos e símbolos)
 */
export function validarSenha(senha: string): boolean {
  // Mínimo 8 caracteres, pelo menos uma letra, um número e um símbolo
  const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
  return regex.test(senha);
}

