/**
 * ${BRAND.companyName} Secure Vault
 * 
 * AES-256-GCM encryption for sensitive data storage.
 * The encryption key is derived from a master secret in environment variables.
 */

import * as crypto from 'crypto';
import { BRAND } from '@/lib/white-label/constants';

const ALGORITHM = 'aes-256-gcm';
const IV_LENGTH = 16;
const SALT_LENGTH = 32;

// Get or generate master key from environment
function getMasterKey(): Buffer {
  const envKey = process.env.GHOST_VAULT_KEY;
  if (!envKey) {
    // Derive from DATABASE_URL as fallback
    const fallback = process.env.DATABASE_URL || 'ghost-vault-default-key';
    return crypto.createHash('sha256').update(fallback).digest();
  }
  return crypto.createHash('sha256').update(envKey).digest();
}

export function encrypt(plaintext: string): string {
  const key = getMasterKey();
  const iv = crypto.randomBytes(IV_LENGTH);
  const salt = crypto.randomBytes(SALT_LENGTH);
  
  // Derive a unique key for this encryption using salt
  const derivedKey = crypto.pbkdf2Sync(key, salt, 100000, 32, 'sha512');
  
  const cipher = crypto.createCipheriv(ALGORITHM, derivedKey, iv);
  
  let encrypted = cipher.update(plaintext, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  
  const authTag = cipher.getAuthTag();
  
  // Format: salt:iv:authTag:encrypted
  return `${salt.toString('hex')}:${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
}

export function decrypt(encryptedData: string): string {
  const key = getMasterKey();
  const parts = encryptedData.split(':');
  
  if (parts.length !== 4) {
    throw new Error('Invalid encrypted data format');
  }
  
  const [saltHex, ivHex, authTagHex, encrypted] = parts;
  
  const salt = Buffer.from(saltHex, 'hex');
  const iv = Buffer.from(ivHex, 'hex');
  const authTag = Buffer.from(authTagHex, 'hex');
  
  // Derive the same key using the salt
  const derivedKey = crypto.pbkdf2Sync(key, salt, 100000, 32, 'sha512');
  
  const decipher = crypto.createDecipheriv(ALGORITHM, derivedKey, iv);
  decipher.setAuthTag(authTag);
  
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  
  return decrypted;
}

// Test if encryption is working
export function testEncryption(): boolean {
  try {
    const test = 'test-encryption-working';
    const encrypted = encrypt(test);
    const decrypted = decrypt(encrypted);
    return decrypted === test;
  } catch {
    return false;
  }
}
