import crypto from 'crypto'

const ALGORITHM = 'aes-256-cbc'
const IV_LENGTH = 16

function getEncryptionKey(): Buffer {
  const key = process.env.CREDENTIAL_ENCRYPTION_KEY
  if (!key) {
    throw new Error('CREDENTIAL_ENCRYPTION_KEY environment variable is required')
  }
  // Use scrypt to derive a 32-byte key from the passphrase
  return crypto.scryptSync(key, 'letsbe-hub-salt', 32)
}

/**
 * Get the legacy encryption key (uses ENCRYPTION_KEY with 'salt')
 * Used for migrating data encrypted with the old system
 */
function getLegacyEncryptionKey(): Buffer {
  const key = process.env.ENCRYPTION_KEY
  if (!key) {
    throw new Error('ENCRYPTION_KEY environment variable is required for legacy decryption')
  }
  return crypto.scryptSync(key, 'salt', 32)
}

export const credentialService = {
  /**
   * Encrypt a plaintext string using AES-256-CBC
   * Returns format: iv:encryptedData (both hex-encoded)
   */
  encrypt(plaintext: string): string {
    const iv = crypto.randomBytes(IV_LENGTH)
    const key = getEncryptionKey()
    const cipher = crypto.createCipheriv(ALGORITHM, key, iv)
    let encrypted = cipher.update(plaintext, 'utf8', 'hex')
    encrypted += cipher.final('hex')
    return `${iv.toString('hex')}:${encrypted}`
  },

  /**
   * Decrypt a ciphertext string that was encrypted with encrypt()
   * Expects format: iv:encryptedData (both hex-encoded)
   */
  decrypt(ciphertext: string): string {
    const [ivHex, encrypted] = ciphertext.split(':')
    if (!ivHex || !encrypted) {
      throw new Error('Invalid ciphertext format')
    }
    const iv = Buffer.from(ivHex, 'hex')
    const key = getEncryptionKey()
    const decipher = crypto.createDecipheriv(ALGORITHM, key, iv)
    let decrypted = decipher.update(encrypted, 'hex', 'utf8')
    decrypted += decipher.final('utf8')
    return decrypted
  },

  /**
   * Check if the encryption key is configured
   */
  isConfigured(): boolean {
    return !!process.env.CREDENTIAL_ENCRYPTION_KEY
  },

  /**
   * Decrypt a ciphertext that was encrypted with the legacy ENCRYPTION_KEY
   * Used during migration from old encryption format
   */
  decryptLegacy(ciphertext: string): string {
    const [ivHex, encrypted] = ciphertext.split(':')
    if (!ivHex || !encrypted) {
      throw new Error('Invalid ciphertext format')
    }
    const iv = Buffer.from(ivHex, 'hex')
    const key = getLegacyEncryptionKey()
    const decipher = crypto.createDecipheriv(ALGORITHM, key, iv)
    let decrypted = decipher.update(encrypted, 'hex', 'utf8')
    decrypted += decipher.final('utf8')
    return decrypted
  },

  /**
   * Re-encrypt a value from legacy format to new format
   * @param legacyCiphertext Encrypted with ENCRYPTION_KEY + 'salt'
   * @returns Encrypted with CREDENTIAL_ENCRYPTION_KEY + 'letsbe-hub-salt'
   */
  migrateFromLegacy(legacyCiphertext: string): string {
    const plaintext = this.decryptLegacy(legacyCiphertext)
    return this.encrypt(plaintext)
  },

  /**
   * Check if the legacy encryption key is configured
   */
  isLegacyConfigured(): boolean {
    return !!process.env.ENCRYPTION_KEY
  }
}
