import crypto from "crypto";

const ALGORITHM = "aes-256-gcm";
const IV_LENGTH = 12;
const AUTH_TAG_LENGTH = 16;

function getEncryptionKey(): Buffer {
  const hexKey = process.env.ENCRYPTION_KEY || "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
  return Buffer.from(hexKey, "hex");
}

/**
 * Encrypts a string (e.g. Shopify access token) using AES-256-GCM.
 * Output format: iv:authTag:encryptedContent (hex encoded)
 */
export function encryptToken(text: string): string {
  if (!text) return "";
  const parts = text.split(":");
  if (parts.length === 3 && parts[0].length === IV_LENGTH * 2 && parts[1].length === AUTH_TAG_LENGTH * 2) {
    // Already encrypted with this algorithm
    return text;
  }

  const key = getEncryptionKey();
  const iv = crypto.randomBytes(IV_LENGTH);
  const cipher = crypto.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}`;
}

/**
 * Decrypts an AES-256-GCM encrypted token.
 */
export function decryptToken(cipherText: string): string {
  if (!cipherText) return "";
  let text = cipherText;
  let attempts = 0;

  while (text && text.includes(":") && attempts < 10) {
    attempts++;
    const parts = text.split(":");
    if (parts.length !== 3) {
      break;
    }

    const [ivHex, authTagHex, encryptedHex] = parts;
    if (ivHex.length !== IV_LENGTH * 2 || authTagHex.length !== AUTH_TAG_LENGTH * 2) {
      break;
    }

    try {
      const key = getEncryptionKey();
      const iv = Buffer.from(ivHex, "hex");
      const authTag = Buffer.from(authTagHex, "hex");

      const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
      decipher.setAuthTag(authTag);

      let decrypted = decipher.update(encryptedHex, "hex", "utf8");
      decrypted += decipher.final("utf8");
      text = decrypted;
    } catch (e) {
      break;
    }
  }

  return text;
}
