var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/model/strategy/adapter/itemRule/adapter.ts
var adapter_exports = {};
__export(adapter_exports, {
  ItemRuleAdapter: () => ItemRuleAdapter,
  default: () => adapter_default
});
module.exports = __toCommonJS(adapter_exports);
var import_type = require("./type");
var ItemRuleAdapter = class {
  constructor() {
    this.name = "ItemRuleAdapter";
    this.version = "1.0.0";
  }
  prepareContext(businessData) {
    const { pax, cartItems, serviceType, submissionIndex, custom } = businessData;
    return {
      entities: {
        cartItems,
        historicalItems: businessData.historicalItems || [],
        pax
      },
      attributes: {
        serviceType: serviceType || "",
        totalPax: pax.total,
        adultPax: pax.adult,
        childPax: pax.child,
        submissionIndex: submissionIndex ?? 0,
        cartItemCount: cartItems.length,
        cartTotalQuantity: cartItems.reduce((sum, item) => sum + item.quantity, 0),
        ...custom
      },
      metadata: {
        timestamp: Date.now()
      }
    };
  }
  transformResult(result, businessData) {
    const quantityChecks = [];
    const prefillItems = [];
    if (!result.applicable || !businessData) {
      return { quantityChecks, prefillItems };
    }
    for (const action of result.matchedActions) {
      if (action.type === import_type.ITEM_RULE_ACTION_TYPES.QUANTITY_CHECK) {
        const checkResult = this.processQuantityCheck(action, businessData);
        if (checkResult) {
          quantityChecks.push(checkResult);
        }
      } else if (action.type === import_type.ITEM_RULE_ACTION_TYPES.PREFILL_CART) {
        const items = this.processPrefillCart(action, businessData);
        prefillItems.push(...items);
      }
    }
    return { quantityChecks, prefillItems };
  }
  formatConfig(result, businessData) {
    return { result, businessData };
  }
  // ============================================
  // Quantity Check 处理
  // ============================================
  processQuantityCheck(action, businessData) {
    const config = action.config;
    if (!config)
      return null;
    const { scope, quantityRules, targetType, targets, validationMessage } = config;
    if (!this.shouldEvaluateForScope(scope, businessData.submissionIndex ?? 0)) {
      return null;
    }
    const actualQuantity = this.calculateActualQuantity(
      targets,
      scope,
      businessData
    );
    const { passed, failedRules, requiredMin, requiredMax, requiredExact, mustInclude } = this.evaluateQuantityRules(quantityRules, actualQuantity, businessData);
    const message = this.formatValidationMessage(
      validationMessage,
      requiredMin,
      requiredMax,
      requiredExact
    );
    return {
      ruleId: action.id,
      passed,
      targetType,
      targets,
      actualQuantity,
      requiredMin,
      requiredMax,
      requiredExact,
      mustInclude,
      validationMessage: message,
      scope,
      failedRules: passed ? void 0 : failedRules
    };
  }
  /**
   * 根据 scope 判断当前提交是否需要评估此规则
   */
  shouldEvaluateForScope(scope, submissionIndex) {
    switch (scope) {
      case "each_submission":
        return true;
      case "first_submission_only":
        return submissionIndex === 0;
      case "subsequent_only":
        return submissionIndex > 0;
      case "cumulative":
        return true;
      default:
        return true;
    }
  }
  /**
   * 计算目标商品在购物车中的实际数量
   *
   * cumulative scope 时还会加上历史订单数量。
   */
  calculateActualQuantity(targets, scope, businessData) {
    const targetIds = new Set(targets.map((t) => t.product_id));
    let quantity = 0;
    const countFromItems = (items) => {
      for (const item of items) {
        if (targetIds.has(item.product_id)) {
          quantity += item.quantity;
        }
      }
    };
    if (scope === "cumulative") {
      if (businessData.historicalItems) {
        countFromItems(businessData.historicalItems);
      }
      countFromItems(businessData.cartItems);
    } else {
      countFromItems(businessData.cartItems);
    }
    return quantity;
  }
  /**
   * 逐条评估数量规则
   */
  evaluateQuantityRules(rules, actualQuantity, businessData) {
    const failedRules = [];
    let requiredMin;
    let requiredMax;
    let requiredExact;
    let mustInclude;
    for (const rule of rules) {
      const resolvedValue = this.resolveQuantityValue(rule, businessData);
      switch (rule.comparison) {
        case "minimum": {
          if (requiredMin === void 0 || resolvedValue > requiredMin) {
            requiredMin = resolvedValue;
          }
          if (actualQuantity < resolvedValue) {
            failedRules.push(rule);
          }
          break;
        }
        case "maximum": {
          if (requiredMax === void 0 || resolvedValue < requiredMax) {
            requiredMax = resolvedValue;
          }
          if (actualQuantity > resolvedValue) {
            failedRules.push(rule);
          }
          break;
        }
        case "exact": {
          requiredExact = resolvedValue;
          if (actualQuantity !== resolvedValue) {
            failedRules.push(rule);
          }
          break;
        }
        case "must_include": {
          mustInclude = true;
          if (actualQuantity < 1) {
            failedRules.push(rule);
          }
          break;
        }
      }
    }
    return {
      passed: failedRules.length === 0,
      failedRules,
      requiredMin,
      requiredMax,
      requiredExact,
      mustInclude
    };
  }
  /**
   * 根据 source 解析出数量规则的实际数值
   */
  resolveQuantityValue(rule, businessData) {
    switch (rule.source) {
      case "total_pax":
        return businessData.pax.total;
      case "adult_pax":
        return businessData.pax.adult;
      case "fixed":
        return rule.value ?? 0;
      default:
        return rule.value ?? 0;
    }
  }
  /**
   * 格式化校验提示语，替换 {min} {max} 占位符
   */
  formatValidationMessage(template, min, max, exact, locale) {
    if (!template)
      return void 0;
    let text = typeof template === "string" ? template : template[locale || "en"] || Object.values(template)[0] || "";
    text = text.replace(/\{min\}/g, String(min ?? ""));
    text = text.replace(/\{max\}/g, String(max ?? ""));
    text = text.replace(/\{exact\}/g, String(exact ?? ""));
    return text;
  }
  // ============================================
  // Quantity Limit 提取（仅读取配置，不做校验）
  // ============================================
  /**
   * 从单个 QUANTITY_CHECK action 中提取数量限制配置。
   *
   * 根据 scope + submissionIndex 判断是否适用，
   * 解析动态数量来源（pax）后返回 min/max/exact/mustInclude。
   * 不适用或无配置时返回 null。
   */
  extractQuantityLimits(action, businessData) {
    const config = action.config;
    if (!config)
      return null;
    const { scope, quantityRules, targetType, targets, validationMessage } = config;
    if (!this.shouldEvaluateForScope(scope, businessData.submissionIndex ?? 0)) {
      return null;
    }
    let requiredMin;
    let requiredMax;
    let requiredExact;
    let mustInclude;
    for (const rule of quantityRules) {
      const resolvedValue = this.resolveQuantityValue(rule, businessData);
      switch (rule.comparison) {
        case "minimum": {
          if (requiredMin === void 0 || resolvedValue > requiredMin) {
            requiredMin = resolvedValue;
          }
          break;
        }
        case "maximum": {
          if (requiredMax === void 0 || resolvedValue < requiredMax) {
            requiredMax = resolvedValue;
          }
          break;
        }
        case "exact": {
          requiredExact = resolvedValue;
          break;
        }
        case "must_include": {
          mustInclude = true;
          break;
        }
      }
    }
    const remainingMax = this.calculateRemainingMax(
      scope,
      requiredMax,
      targets,
      businessData
    );
    const formattedValidationMessage = this.formatValidationMessage(
      validationMessage,
      requiredMin,
      requiredMax,
      requiredExact
    );
    return {
      ruleId: action.id,
      targetType,
      targets,
      requiredMin,
      requiredMax,
      remainingMax,
      requiredExact,
      mustInclude,
      scope,
      validationMessage: formattedValidationMessage,
      rawValidationMessage: validationMessage
    };
  }
  /**
   * 计算当前提交剩余可选的最大数量。
   *
   * 仅在 scope='cumulative' 且存在 requiredMax 时生效：
   * 用 requiredMax 减去 historicalItems 中目标商品的累计数量，保底 0。
   * 其余场景返回 undefined，保持向后兼容。
   */
  calculateRemainingMax(scope, requiredMax, targets, businessData) {
    if (scope !== "cumulative" || typeof requiredMax !== "number") {
      return void 0;
    }
    const historicalItems = businessData.historicalItems;
    if (!(historicalItems == null ? void 0 : historicalItems.length)) {
      return Math.max(0, requiredMax);
    }
    const targetIds = new Set(targets.map((t) => t.product_id));
    let historicalQty = 0;
    for (const item of historicalItems) {
      if (targetIds.has(item.product_id)) {
        historicalQty += item.quantity;
      }
    }
    return Math.max(0, requiredMax - historicalQty);
  }
  // ============================================
  // Prefill Cart 处理
  // ============================================
  processPrefillCart(action, businessData) {
    const config = action.config;
    if (!(config == null ? void 0 : config.products))
      return [];
    const results = [];
    for (const prefillProduct of config.products) {
      const quantity = this.resolvePrefillQuantity(prefillProduct.quantityFrom, prefillProduct.quantity, businessData);
      if (quantity <= 0)
        continue;
      results.push({
        ruleId: action.id,
        product_id: prefillProduct.product_id,
        product_variant_id: prefillProduct.product_variant_id,
        quantity
      });
    }
    return results;
  }
  /**
   * 根据 quantityFrom 计算预填数量
   */
  resolvePrefillQuantity(quantityFrom, fixedValue, businessData) {
    switch (quantityFrom) {
      case "total_pax":
        return businessData.pax.total;
      case "adult_pax":
        return businessData.pax.adult;
      case "fixed":
        return fixedValue ?? 0;
      default:
        return fixedValue ?? 0;
    }
  }
};
var adapter_default = ItemRuleAdapter;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ItemRuleAdapter
});
