import db from "../models/index.js";

class ServiceGuard {
  /**
   * Checks if a customer has access to a specific system service based on their KYC status.
   * 
   * @param {string} customerId 
   * @param {string} serviceCode 
   * @throws {Error} if access is denied or service is inactive
   */
  static async checkAccess(customerId, serviceCode) {
    const { Customer, SystemService, KycStage, KycStageService } = db;

    // 1. Fetch the customer
    const customer = await Customer.findByPk(customerId);
    if (!customer) {
      throw new Error("Customer not found");
    }

    // 2. Fetch the system service from DB
    const service = await SystemService.findOne({ where: { code: serviceCode } });
    if (!service) {
      // If service is not registered in DB, default to allowed (unrestricted)
      return true;
    }

    if (!service.isActive) {
      throw new Error(`The service '${service.name}' is currently deactivated globally`);
    }

    // 3. Check service capabilities
    if (serviceCode === "ngn_payout_service" && !service.canSend) {
      throw new Error(`Access Denied: The service '${service.name}' does not support sending money out`);
    }

    // 4. Find if this service is mapped to any KYC stage
    const stageMapping = await KycStageService.findOne({
      where: { serviceId: service.id, isActive: true }
    });

    if (!stageMapping) {
      // No active KYC stage restriction for this service
      return true;
    }

    // 5. Fetch the stage details to check requirement
    const stage = await KycStage.findByPk(stageMapping.stageId);
    if (!stage) {
      return true;
    }

    // Check customer's compliance with the stage requirements
    if (stage.code === "bvn_stage") {
      if (customer.bvnStatus !== "verified") {
        throw new Error(`Access Denied: Customer must complete Stage 1 (BVN Verification) to use '${service.name}'`);
      }
    } else if (stage.code === "nin_stage") {
      if (customer.idStatus !== "verified") {
        throw new Error(`Access Denied: Customer must complete Stage 2 (NIN Verification) to use '${service.name}'`);
      }
    }

    return true;
  }
}

export default ServiceGuard;
