export type EncryptedVault = { version: 1; salt: number[]; iv: number[]; ciphertext: number[] };
async function derive(passphrase: string, salt: Uint8Array) {
  const material = await crypto.subtle.importKey("raw", new TextEncoder().encode(passphrase), "PBKDF2", false, ["deriveKey"]);
  return crypto.subtle.deriveKey({ name: "PBKDF2", salt: salt as BufferSource, iterations: 310000, hash: "SHA-256" }, material, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
}
export async function encryptVault(text: string, passphrase: string): Promise<EncryptedVault> {
  if (passphrase.length < 12) throw new Error("Use a passphrase of at least 12 characters.");
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const key = await derive(passphrase, salt);
  const ciphertext = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, new TextEncoder().encode(text));
  return { version: 1, salt: [...salt], iv: [...iv], ciphertext: [...new Uint8Array(ciphertext)] };
}
export async function decryptVault(vault: EncryptedVault, passphrase: string) {
  if (vault.version !== 1 || !Array.isArray(vault.salt) || !Array.isArray(vault.iv) || !Array.isArray(vault.ciphertext) || vault.salt.length !== 16 || vault.iv.length !== 12) throw new Error("Invalid vault file.");
  const key = await derive(passphrase, new Uint8Array(vault.salt));
  const result = await crypto.subtle.decrypt({ name: "AES-GCM", iv: new Uint8Array(vault.iv) }, key, new Uint8Array(vault.ciphertext));
  return new TextDecoder().decode(result);
}