import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';

const ALGORITHM = 'aes-256-gcm';

function getKey(): Buffer {
  const encKey = process.env.ENCRYPTION_KEY;
  const jwtKey = process.env.JWT_SECRET;
  const secret = encKey || jwtKey;
  if (!secret) {
    if (process.env.NODE_ENV === 'production') {
      throw new Error(
        '[RestroAgent] ENCRYPTION_KEY (or JWT_SECRET) must be set in production. ' +
        'Add it to your .env file. Using the default key is not permitted in production.'
      );
    }
    return scryptSync('restroagent-default-key-change-me', 'restroagent-salt', 32);
  }
  return scryptSync(secret, 'restroagent-salt', 32);
}

export function encrypt(text: string): string {
  const key = getKey();
  const iv = randomBytes(16);
  const cipher = createCipheriv(ALGORITHM, key, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  const authTag = cipher.getAuthTag().toString('hex');
  return `${iv.toString('hex')}:${authTag}:${encrypted}`;
}

export function decrypt(encryptedText: string): string {
  const key = getKey();
  const [ivHex, authTagHex, encrypted] = encryptedText.split(':');
  if (!ivHex || !authTagHex || !encrypted) {
    throw new Error('Invalid encrypted format');
  }
  const iv = Buffer.from(ivHex, 'hex');
  const authTag = Buffer.from(authTagHex, 'hex');
  if (authTag.length !== 16) {
    throw new Error('Invalid auth tag length — expected 16 bytes');
  }
  const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: 16 });
  decipher.setAuthTag(authTag);
  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}
