import crypto from 'crypto';

// Google OAuth tokenları asla plaintext saklanmaz (bkz. PRD §6) — AES-256-GCM
// ile şifrelenip tek bir string olarak (iv:authTag:ciphertext, hepsi base64)
// veritabanına yazılır. Node'un yerleşik crypto modülü kullanılıyor, ek
// bağımlılık gerekmiyor.
const ALGORITHM = 'aes-256-gcm';

function getKey(): Buffer {
  const raw = process.env.GOOGLE_TOKEN_ENCRYPTION_KEY;
  if (!raw) {
    throw new Error('GOOGLE_TOKEN_ENCRYPTION_KEY ortam değişkeni tanımlı değil.');
  }
  const buf = raw.length === 64 ? Buffer.from(raw, 'hex') : Buffer.from(raw, 'base64');
  if (buf.length !== 32) {
    throw new Error('GOOGLE_TOKEN_ENCRYPTION_KEY 32 byte olmalı (64 karakterlik hex ya da base64 olarak sağlayın).');
  }
  return buf;
}

export function encryptToken(plaintext: string): string {
  const key = getKey();
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
  const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
  const authTag = cipher.getAuthTag();
  return [iv, authTag, encrypted].map((b) => b.toString('base64')).join(':');
}

export function decryptToken(stored: string): string {
  const key = getKey();
  const [ivB64, tagB64, dataB64] = stored.split(':');
  if (!ivB64 || !tagB64 || !dataB64) {
    throw new Error('Şifrelenmiş token formatı geçersiz.');
  }
  const iv = Buffer.from(ivB64, 'base64');
  const authTag = Buffer.from(tagB64, 'base64');
  const data = Buffer.from(dataB64, 'base64');
  const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
  decipher.setAuthTag(authTag);
  return Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8');
}
