import db from "../models/index.js";
import { Op } from "sequelize";

const { ServicePricing, MerchantSubscription, SubscriptionPlan, MerchantServicePricing } = db;

class PricingHelper {
  /**
   * Retrieves the effective service pricing for a given merchant, service, and currency.
   * Priority:
   * 1. A merchant-specific override (admin-set custom pricing for this exact merchant).
   * 2. The merchant's active subscription plan's servicePricingOverrides, if any.
   * 3. The platform-wide default ServicePricing table.
   *
   * @param {string} merchantId
   * @param {string} serviceName
   * @param {string} currency
   * @param {object} dbTransaction Optional transaction
   * @returns {object} The effective ServicePricing object
   */
  static async getEffectiveServicePricing(merchantId, serviceName, currency, dbTransaction = null) {
    let effectivePricing = null;

    // 1. Check for a merchant-specific override (most specific — set directly by an admin for this merchant)
    if (merchantId) {
      const merchantOverride = await MerchantServicePricing.findOne({
        where: { merchantId, serviceName, currency, isActive: true },
        transaction: dbTransaction,
      }) || await MerchantServicePricing.findOne({
        where: { merchantId, serviceName, currency: "*", isActive: true },
        transaction: dbTransaction,
      });

      if (merchantOverride) {
        effectivePricing = merchantOverride;
      }
    }

    // 2. Check for an active MerchantSubscription
    if (!effectivePricing && merchantId) {
      const activeSubscription = await MerchantSubscription.findOne({
        where: { 
          merchantId,
          status: "active",
          startDate: { [Op.lte]: new Date() },
          endDate: { [Op.gte]: new Date() }
        },
        include: [{
          model: SubscriptionPlan,
          as: "plan"
        }],
        transaction: dbTransaction
      });

      if (activeSubscription && activeSubscription.plan && activeSubscription.plan.servicePricingOverrides) {
        const overrides = activeSubscription.plan.servicePricingOverrides;
        
        // Find exact match (serviceName + currency)
        let override = overrides.find(o => o.serviceName === serviceName && o.currency === currency);
        
        // Find wildcard currency match (serviceName + "*") if no exact match
        if (!override) {
          override = overrides.find(o => o.serviceName === serviceName && o.currency === "*");
        }

        if (override) {
          // Format it to match a ServicePricing record for drop-in replacement
          effectivePricing = {
            serviceName: override.serviceName,
            currency: override.currency,
            providerPercentage: parseFloat(override.providerPercentage || 0),
            providerFixedFee: parseFloat(override.providerFixedFee || 0),
            providerMinCap: parseFloat(override.providerMinCap || 0),
            providerMaxCap: parseFloat(override.providerMaxCap || 999999999.99),
            customerPercentage: parseFloat(override.customerPercentage || 0),
            customerFixedFee: parseFloat(override.customerFixedFee || 0),
            customerMinCap: parseFloat(override.customerMinCap || 0),
            customerMaxCap: parseFloat(override.customerMaxCap || 999999999.99),
            isActive: true,
            isOverride: true // Flag to indicate it came from a subscription plan
          };
        }
      }
    }

    // 3. Fall back to default ServicePricing if no valid override was found
    if (!effectivePricing) {
      effectivePricing = await ServicePricing.findOne({
        where: { serviceName, currency, isActive: true },
        transaction: dbTransaction
      }) || await ServicePricing.findOne({
        where: { serviceName, currency: "*", isActive: true },
        transaction: dbTransaction
      });
    }

    return effectivePricing;
  }
}

export default PricingHelper;
