'use strict';

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const KEYS_DIR = path.join(__dirname, 'keys');
const AES_KEY_PATH = path.join(KEYS_DIR, 'aes-256.key');

function normalizeAesKey(raw) {
  if (!raw) return null;
  const value = String(raw).trim();
  if (/^[a-f0-9]{64}$/i.test(value)) return Buffer.from(value, 'hex');
  try {
    const decoded = Buffer.from(value, 'base64');
    if (decoded.length === 32) return decoded;
  } catch (_) {}
  return crypto.createHash('sha256').update(value).digest();
}

function loadAesKey({ createIfMissing = false } = {}) {
  const fromEnv = normalizeAesKey(process.env.ARKHON_LICENSE_AES_KEY);
  if (fromEnv) return fromEnv;

  if (fs.existsSync(AES_KEY_PATH)) {
    return normalizeAesKey(fs.readFileSync(AES_KEY_PATH, 'utf8'));
  }

  if (!createIfMissing) {
    throw new Error(
      'Clave AES-256 no configurada. Define ARKHON_LICENSE_AES_KEY o crea license/keys/aes-256.key'
    );
  }

  fs.mkdirSync(KEYS_DIR, { recursive: true });
  const key = crypto.randomBytes(32);
  fs.writeFileSync(AES_KEY_PATH, key.toString('base64'), { mode: 0o600 });
  return key;
}

function encryptPayloadAes256(payload, options = {}) {
  const key = options.key || loadAesKey({ createIfMissing: options.createKeyIfMissing });
  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
  const plaintext = Buffer.from(JSON.stringify(payload), 'utf8');
  const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
  const tag = cipher.getAuthTag();
  return `ARKHON5-${iv.toString('base64url')}.${encrypted.toString('base64url')}.${tag.toString('base64url')}`;
}

function decryptPayloadAes256(rawKey, options = {}) {
  const clean = String(rawKey || '').trim().replace(/\s/g, '');
  const body = clean.replace(/^ARKHON5-/i, '');
  const parts = body.split('.');
  if (parts.length !== 3) throw new Error('FORMATO_V5_INVALIDO');

  const key = options.key || loadAesKey({ createIfMissing: false });
  const iv = Buffer.from(parts[0], 'base64url');
  const encrypted = Buffer.from(parts[1], 'base64url');
  const tag = Buffer.from(parts[2], 'base64url');
  const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
  decipher.setAuthTag(tag);
  const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
  return JSON.parse(decrypted.toString('utf8'));
}

module.exports = {
  AES_KEY_PATH,
  normalizeAesKey,
  loadAesKey,
  encryptPayloadAes256,
  decryptPayloadAes256,
};
