import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto'

export interface EncryptedBlob {
  iv: string
  ciphertext: string
  tag: string
}

const ALGO = 'aes-256-gcm'
const IV_BYTES = 12

function getKey(): Buffer {
  const hex = process.env.CREDENTIAL_ENCRYPTION_KEY
  if (!hex) {
    throw new Error('CREDENTIAL_ENCRYPTION_KEY env var is not set — cannot encrypt/decrypt stored credentials')
  }
  const key = Buffer.from(hex, 'hex')
  if (key.length !== 32) {
    throw new Error('CREDENTIAL_ENCRYPTION_KEY must be 32 bytes (64 hex chars), got ' + key.length + ' bytes')
  }
  return key
}

export function encryptPassword(plain: string): EncryptedBlob {
  const key = getKey()
  const iv = randomBytes(IV_BYTES)
  const cipher = createCipheriv(ALGO, key, iv)
  const ciphertext = Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()])
  const tag = cipher.getAuthTag()
  return {
    iv: iv.toString('hex'),
    ciphertext: ciphertext.toString('hex'),
    tag: tag.toString('hex'),
  }
}

export function decryptPassword(blob: EncryptedBlob): string {
  const key = getKey()
  const iv = Buffer.from(blob.iv, 'hex')
  const tag = Buffer.from(blob.tag, 'hex')
  const ciphertext = Buffer.from(blob.ciphertext, 'hex')
  const decipher = createDecipheriv(ALGO, key, iv)
  decipher.setAuthTag(tag)
  const plain = Buffer.concat([decipher.update(ciphertext), decipher.final()])
  return plain.toString('utf8')
}
