import { Injectable } from '@nestjs/common';
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'crypto';
import { loadEnv } from '@/config/env';

/**
 * AES-256-GCM encryption for secrets at rest (webhook secrets, connector credentials).
 * ENCRYPTION_KEY: "base64:<32 bytes>" or any string (hashed to 32 bytes).
 */
@Injectable()
export class EncryptionService {
  private readonly key: Buffer;

  constructor() {
    const raw = loadEnv().ENCRYPTION_KEY;
    this.key = raw.startsWith('base64:') ? Buffer.from(raw.slice(7), 'base64') : createHash('sha256').update(raw).digest();
    if (this.key.length !== 32) throw new Error('ENCRYPTION_KEY must decode to 32 bytes');
  }

  encrypt(plain: string): string {
    const iv = randomBytes(12);
    const cipher = createCipheriv('aes-256-gcm', this.key, iv);
    const enc = Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()]);
    const tag = cipher.getAuthTag();
    return `v1.${iv.toString('base64url')}.${tag.toString('base64url')}.${enc.toString('base64url')}`;
  }

  decrypt(payload: string): string {
    const [v, ivB, tagB, encB] = payload.split('.');
    if (v !== 'v1') throw new Error('Unsupported ciphertext version');
    const decipher = createDecipheriv('aes-256-gcm', this.key, Buffer.from(ivB, 'base64url'));
    decipher.setAuthTag(Buffer.from(tagB, 'base64url'));
    return Buffer.concat([decipher.update(Buffer.from(encB, 'base64url')), decipher.final()]).toString('utf8');
  }
}
