const LicenseService = require("./license.service");
const logger = require("../../handlers/logger");
const db = require("../../managers/dbConfig");
const {
  saveLicense,
  loadLicense,
  verifyMachine,
} = require("../../managers/licenseManager");

// Check License Validity

exports.checkLicense = () => {
  try {
    // Verify machine ID
    const machineCheck = verifyMachine();
    if (!machineCheck.success) {
      throw machineCheck.message;
    }

    // Load license data
    const licenseData = loadLicense();
    if (!licenseData) {
      throw "License file missing or corrupted. Please activate the software.";
    }

    const { license_key, expiry_date } = licenseData;
    const currentDate = new Date();
    const expiryDate = new Date(expiry_date);

    if (currentDate > expiryDate) {
      throw "License expired. Please renew.";
    }

    return { success: true, message: "License is valid." };
  } catch (error) {
    logger.error(`License check failed: ${error.message}`);
    return { success: false, message: error.message };
  }
};

// Renew License

exports.renewLicense = async (hospitalId) => {
  const connection = await db.getConnection();
  await connection.beginTransaction();

  try {
    const [plans] = await connection.query(
      `SELECT sp.duration, sp.price, w.balance
             FROM subscription_plans sp
             JOIN hosp_setting hs ON hs.plan_id = sp.id
             JOIN wallets w ON w.hospital_id = hs.id
             WHERE hs.id = ?`,
      [hospitalId]
    );

    if (!plans || plans.length === 0) {
      throw new Error("Subscription plan not found");
    }

    const { duration, price, balance } = plans[0];

    if (balance < price) {
      throw new Error("Insufficient funds in wallet");
    }

    // Deduct from wallet
    const newBalance = balance - price;
    await connection.query(
      `UPDATE wallets SET balance = ? WHERE hospital_id = ?`,
      [newBalance, hospitalId]
    );

    // Log transaction
    await connection.query(
      `INSERT INTO wallet_transactions 
             (hospital_id, transaction_type, amount, balance_before, balance_after, description)
             VALUES (?, 'debit', ?, ?, ?, 'License renewal')`,
      [hospitalId, price, balance, newBalance]
    );

    // Generate new license key
    const newLicenseKey = generateLicenseKey();
    const newExpiryDate = new Date();
    newExpiryDate.setDate(newExpiryDate.getDate() + duration);

    // Update license online
    await connection.query(
      `UPDATE licenses SET license_key = ?, expiry_date = ? WHERE hospital_id = ?`,
      [newLicenseKey, newExpiryDate, hospitalId]
    );

    await connection.commit();

    // Save encrypted license with machine ID
    saveLicense({
      license_key: newLicenseKey,
      expiry_date: newExpiryDate.toISOString(),
    });

    logger.info(
      `License renewed for hospital ${hospitalId}. New key: ${newLicenseKey}`
    );

    return {
      success: true,
      message: "License renewed successfully",
      newLicenseKey,
    };
  } catch (error) {
    await connection.rollback();
    logger.error(
      `License renewal failed for hospital ${hospitalId}: ${error.message}`
    );
    return { success: false, message: error.message };
  } finally {
    connection.release();
  }
};

// Reset License (Admin only)
exports.resetLicense = async (req, res) => {
  try {
    const { hospital_id, new_machine_id } = req.body;

    // Ensure only admin can reset
    if (!req.user || req.user.role !== "admin") {
      return res.status(403).json({ message: "Unauthorized" });
    }

    await LicenseService.resetLicense(hospital_id, new_machine_id);
    return res.status(200).json({ message: "License reset successfully" });
  } catch (error) {
    logger.error(error);
    res.status(500).json({ message: "Server error" });
  }
};
