const fs = require("fs");
const crypto = require("crypto");
const { generateSystemFingerprint } = require("./systemFingerprint");

const path = require("path");

const LICENSE_FILE_PATH = path.join(
  "C:",
  "ProgramData",
  "HospiTrack",
  "license.enc"
); // Encrypted license file path
const SECRET_KEY = process.env.LICENSE_SECRET;

if (!SECRET_KEY || SECRET_KEY.length !== 32) {
  throw new Error("Encryption key (LICENSE_SECRET) must be a 32-byte string.");
}

// Helper to encrypt with dynamic IV
function encryptData(data) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv(
    "aes-256-cbc",
    Buffer.from(SECRET_KEY),
    iv
  );
  let encrypted = cipher.update(JSON.stringify(data), "utf-8", "hex");
  encrypted += cipher.final("hex");
  return {
    iv: iv.toString("hex"),
    content: encrypted,
  };
}

// Helper to decrypt using IV
function decryptData({ iv, content }) {
  try {
    const decipher = crypto.createDecipheriv(
      "aes-256-cbc",
      Buffer.from(SECRET_KEY),
      Buffer.from(iv, "hex")
    );
    let decrypted = decipher.update(content, "hex", "utf-8");
    decrypted += decipher.final("utf-8");
    return JSON.parse(decrypted);
  } catch (error) {
    return null;
  }
}

// Save encrypted license to file (with fingerprint)
function saveEncryptedLicense(licenseData) {
  const fingerprint = generateSystemFingerprint();
  licenseData.fingerprint = fingerprint;

  const encryptedPayload = encryptData(licenseData);
  const payloadToStore = JSON.stringify(encryptedPayload);

  // Ensure directory exists
  const dir = path.dirname(LICENSE_FILE_PATH);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

  fs.writeFileSync(LICENSE_FILE_PATH, payloadToStore, "utf-8");
}

// Load and decrypt license file
function loadLicense() {
  if (!fs.existsSync(LICENSE_FILE_PATH)) throw "missing license";

  try {
    const encryptedPayload = JSON.parse(
      fs.readFileSync(LICENSE_FILE_PATH, "utf-8")
    );
    return decryptData(encryptedPayload);
  } catch (err) {
    return { status: "failed", error: err };
  }
}

// Validate license is for current machine
function verifyMachine() {
  const licenseData = loadLicense();
  if (!licenseData)
    return { status: "failed", error: "License file missing or corrupted." };

  const currentFingerprint = generateSystemFingerprint();

  if (licenseData.fingerprint !== currentFingerprint) {
    return {
      status: "failed",
      error: "Unrecognized machine, contact support.",
    };
  }

  return { status: "success" };
}

module.exports = {
  encryptData,
  decryptData,
  saveEncryptedLicense,
  loadLicense,
  verifyMachine,
};
