import crypto from "crypto";

// AES-256-GCM für hochsensible personenbezogene Mitarbeiterdaten (IBAN,
// Sozialversicherungsnummer, Steuer-ID - Personalsystem, 24.09.2026), NICHT
// für alles andere im Projekt gedacht (die allermeisten Felder brauchen das
// nicht, siehe z. B. address/billingStreet auf Client, bewusst Klartext).
//
// SENSITIVE_DATA_ENCRYPTION_KEY (.env.local) MUSS auf live und preview
// identisch sein - beide teilen sich dieselbe MongoDB, mit unterschiedlichen
// Schlüsseln verschlüsselte Werte wären auf der jeweils anderen Seite nicht
// entschlüsselbar. Einmal gesetzt nie mehr ändern, sonst werden bestehende
// gespeicherte Werte unlesbar (kein automatisches Re-Encryption vorgesehen).
const ALGORITHM = "aes-256-gcm";

function getKey(): Buffer {
  const secret = process.env.SENSITIVE_DATA_ENCRYPTION_KEY;
  if (!secret) throw new Error("SENSITIVE_DATA_ENCRYPTION_KEY fehlt in .env.local");
  // sha256 liefert immer genau 32 Byte, unabhängig von der Eingabelänge -
  // der Secret selbst ist bereits ein langer Zufallswert (kein von Menschen
  // gewähltes Passwort), ein einfacher Hash reicht hier als Schlüsselableitung.
  return crypto.createHash("sha256").update(secret).digest();
}

// Format: "<iv base64>:<authTag base64>:<ciphertext base64>" - leerer String
// bleibt leerer String (kein Feld gepflegt), verschlüsselt nichts umsonst.
export function encryptSensitive(plaintext: string): string {
  if (!plaintext) return "";
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv(ALGORITHM, getKey(), iv);
  const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
  const authTag = cipher.getAuthTag();
  return `${iv.toString("base64")}:${authTag.toString("base64")}:${encrypted.toString("base64")}`;
}

// Gibt "" zurück statt zu werfen, wenn der Wert leer oder (z. B. durch einen
// falschen Schlüssel) nicht entschlüsselbar ist - eine kaputte Anzeige ist
// hier schlimmer als ein leeres Feld, das zum Neu-Eintragen einlädt.
export function decryptSensitive(stored: string): string {
  if (!stored) return "";
  try {
    const [ivB64, authTagB64, dataB64] = stored.split(":");
    if (!ivB64 || !authTagB64 || !dataB64) return "";
    const decipher = crypto.createDecipheriv(ALGORITHM, getKey(), Buffer.from(ivB64, "base64"));
    decipher.setAuthTag(Buffer.from(authTagB64, "base64"));
    const decrypted = Buffer.concat([decipher.update(Buffer.from(dataB64, "base64")), decipher.final()]);
    return decrypted.toString("utf8");
  } catch {
    return "";
  }
}
