function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { ITEM_RULE_ACTION_TYPES } from "./type";

/**
 * ItemRule 适配器
 *
 * 将堂食扫码点餐的商品规则业务数据转换为策略引擎格式，
 * 并将引擎结果转换为数量校验和预填购物车的业务结果。
 */
export var ItemRuleAdapter = /*#__PURE__*/function () {
  function ItemRuleAdapter() {
    _classCallCheck(this, ItemRuleAdapter);
    _defineProperty(this, "name", 'ItemRuleAdapter');
    _defineProperty(this, "version", '1.0.0');
  }
  _createClass(ItemRuleAdapter, [{
    key: "prepareContext",
    value: function prepareContext(businessData) {
      var pax = businessData.pax,
        cartItems = businessData.cartItems,
        serviceType = businessData.serviceType,
        submissionIndex = businessData.submissionIndex,
        custom = businessData.custom;
      return {
        entities: {
          cartItems: cartItems,
          historicalItems: businessData.historicalItems || [],
          pax: pax
        },
        attributes: _objectSpread({
          serviceType: serviceType || '',
          totalPax: pax.total,
          adultPax: pax.adult,
          childPax: pax.child,
          submissionIndex: submissionIndex !== null && submissionIndex !== void 0 ? submissionIndex : 0,
          cartItemCount: cartItems.length,
          cartTotalQuantity: cartItems.reduce(function (sum, item) {
            return sum + item.quantity;
          }, 0)
        }, custom),
        metadata: {
          timestamp: Date.now()
        }
      };
    }
  }, {
    key: "transformResult",
    value: function transformResult(result, businessData) {
      var quantityChecks = [];
      var prefillItems = [];
      if (!result.applicable || !businessData) {
        return {
          quantityChecks: quantityChecks,
          prefillItems: prefillItems
        };
      }
      var _iterator = _createForOfIteratorHelper(result.matchedActions),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var action = _step.value;
          if (action.type === ITEM_RULE_ACTION_TYPES.QUANTITY_CHECK) {
            var checkResult = this.processQuantityCheck(action, businessData);
            if (checkResult) {
              quantityChecks.push(checkResult);
            }
          } else if (action.type === ITEM_RULE_ACTION_TYPES.PREFILL_CART) {
            var items = this.processPrefillCart(action, businessData);
            prefillItems.push.apply(prefillItems, _toConsumableArray(items));
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
      return {
        quantityChecks: quantityChecks,
        prefillItems: prefillItems
      };
    }
  }, {
    key: "formatConfig",
    value: function formatConfig(result, businessData) {
      return {
        result: result,
        businessData: businessData
      };
    }

    // ============================================
    // Quantity Check 处理
    // ============================================
  }, {
    key: "processQuantityCheck",
    value: function processQuantityCheck(action, businessData) {
      var _businessData$submiss;
      var config = action.config;
      if (!config) return null;
      var scope = config.scope,
        quantityRules = config.quantityRules,
        targetType = config.targetType,
        targets = config.targets,
        validationMessage = config.validationMessage;
      if (!this.shouldEvaluateForScope(scope, (_businessData$submiss = businessData.submissionIndex) !== null && _businessData$submiss !== void 0 ? _businessData$submiss : 0)) {
        return null;
      }
      var actualQuantity = this.calculateActualQuantity(targets, scope, businessData);
      var _this$evaluateQuantit = this.evaluateQuantityRules(quantityRules, actualQuantity, businessData),
        passed = _this$evaluateQuantit.passed,
        failedRules = _this$evaluateQuantit.failedRules,
        requiredMin = _this$evaluateQuantit.requiredMin,
        requiredMax = _this$evaluateQuantit.requiredMax,
        requiredExact = _this$evaluateQuantit.requiredExact,
        mustInclude = _this$evaluateQuantit.mustInclude;
      var message = this.formatValidationMessage(validationMessage, requiredMin, requiredMax, requiredExact);
      return {
        ruleId: action.id,
        passed: passed,
        targetType: targetType,
        targets: targets,
        actualQuantity: actualQuantity,
        requiredMin: requiredMin,
        requiredMax: requiredMax,
        requiredExact: requiredExact,
        mustInclude: mustInclude,
        validationMessage: message,
        scope: scope,
        failedRules: passed ? undefined : failedRules
      };
    }

    /**
     * 根据 scope 判断当前提交是否需要评估此规则
     */
  }, {
    key: "shouldEvaluateForScope",
    value: function 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 时还会加上历史订单数量。
     */
  }, {
    key: "calculateActualQuantity",
    value: function calculateActualQuantity(targets, scope, businessData) {
      var targetIds = new Set(targets.map(function (t) {
        return t.product_id;
      }));
      var quantity = 0;
      var countFromItems = function countFromItems(items) {
        var _iterator2 = _createForOfIteratorHelper(items),
          _step2;
        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            var item = _step2.value;
            if (targetIds.has(item.product_id)) {
              quantity += item.quantity;
            }
          }
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }
      };
      if (scope === 'cumulative') {
        if (businessData.historicalItems) {
          countFromItems(businessData.historicalItems);
        }
        countFromItems(businessData.cartItems);
      } else {
        countFromItems(businessData.cartItems);
      }
      return quantity;
    }
    /**
     * 逐条评估数量规则
     */
  }, {
    key: "evaluateQuantityRules",
    value: function evaluateQuantityRules(rules, actualQuantity, businessData) {
      var failedRules = [];
      var requiredMin;
      var requiredMax;
      var requiredExact;
      var mustInclude;
      var _iterator3 = _createForOfIteratorHelper(rules),
        _step3;
      try {
        for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
          var rule = _step3.value;
          var resolvedValue = this.resolveQuantityValue(rule, businessData);
          switch (rule.comparison) {
            case 'minimum':
              {
                if (requiredMin === undefined || resolvedValue > requiredMin) {
                  requiredMin = resolvedValue;
                }
                if (actualQuantity < resolvedValue) {
                  failedRules.push(rule);
                }
                break;
              }
            case 'maximum':
              {
                if (requiredMax === undefined || 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;
              }
          }
        }
      } catch (err) {
        _iterator3.e(err);
      } finally {
        _iterator3.f();
      }
      return {
        passed: failedRules.length === 0,
        failedRules: failedRules,
        requiredMin: requiredMin,
        requiredMax: requiredMax,
        requiredExact: requiredExact,
        mustInclude: mustInclude
      };
    }

    /**
     * 根据 source 解析出数量规则的实际数值
     */
  }, {
    key: "resolveQuantityValue",
    value: function resolveQuantityValue(rule, businessData) {
      var _rule$value, _rule$value2;
      switch (rule.source) {
        case 'total_pax':
          return businessData.pax.total;
        case 'adult_pax':
          return businessData.pax.adult;
        case 'fixed':
          return (_rule$value = rule.value) !== null && _rule$value !== void 0 ? _rule$value : 0;
        default:
          return (_rule$value2 = rule.value) !== null && _rule$value2 !== void 0 ? _rule$value2 : 0;
      }
    }

    /**
     * 格式化校验提示语，替换 {min} {max} 占位符
     */
  }, {
    key: "formatValidationMessage",
    value: function formatValidationMessage(template, min, max, exact, locale) {
      if (!template) return undefined;
      var text = typeof template === 'string' ? template : template[locale || 'en'] || Object.values(template)[0] || '';
      text = text.replace(/\{min\}/g, String(min !== null && min !== void 0 ? min : ''));
      text = text.replace(/\{max\}/g, String(max !== null && max !== void 0 ? max : ''));
      text = text.replace(/\{exact\}/g, String(exact !== null && exact !== void 0 ? exact : ''));
      return text;
    }

    // ============================================
    // Quantity Limit 提取（仅读取配置，不做校验）
    // ============================================

    /**
     * 从单个 QUANTITY_CHECK action 中提取数量限制配置。
     *
     * 根据 scope + submissionIndex 判断是否适用，
     * 解析动态数量来源（pax）后返回 min/max/exact/mustInclude。
     * 不适用或无配置时返回 null。
     */
  }, {
    key: "extractQuantityLimits",
    value: function extractQuantityLimits(action, businessData) {
      var _businessData$submiss2;
      var config = action.config;
      if (!config) return null;
      var scope = config.scope,
        quantityRules = config.quantityRules,
        targetType = config.targetType,
        targets = config.targets,
        validationMessage = config.validationMessage;
      if (!this.shouldEvaluateForScope(scope, (_businessData$submiss2 = businessData.submissionIndex) !== null && _businessData$submiss2 !== void 0 ? _businessData$submiss2 : 0)) {
        return null;
      }
      var requiredMin;
      var requiredMax;
      var requiredExact;
      var mustInclude;
      var _iterator4 = _createForOfIteratorHelper(quantityRules),
        _step4;
      try {
        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
          var rule = _step4.value;
          var resolvedValue = this.resolveQuantityValue(rule, businessData);
          switch (rule.comparison) {
            case 'minimum':
              {
                if (requiredMin === undefined || resolvedValue > requiredMin) {
                  requiredMin = resolvedValue;
                }
                break;
              }
            case 'maximum':
              {
                if (requiredMax === undefined || resolvedValue < requiredMax) {
                  requiredMax = resolvedValue;
                }
                break;
              }
            case 'exact':
              {
                requiredExact = resolvedValue;
                break;
              }
            case 'must_include':
              {
                mustInclude = true;
                break;
              }
          }
        }
      } catch (err) {
        _iterator4.e(err);
      } finally {
        _iterator4.f();
      }
      var remainingMax = this.calculateRemainingMax(scope, requiredMax, targets, businessData);
      var formattedValidationMessage = this.formatValidationMessage(validationMessage, requiredMin, requiredMax, requiredExact);
      return {
        ruleId: action.id,
        targetType: targetType,
        targets: targets,
        requiredMin: requiredMin,
        requiredMax: requiredMax,
        remainingMax: remainingMax,
        requiredExact: requiredExact,
        mustInclude: mustInclude,
        scope: scope,
        validationMessage: formattedValidationMessage,
        rawValidationMessage: validationMessage
      };
    }

    /**
     * 计算当前提交剩余可选的最大数量。
     *
     * 仅在 scope='cumulative' 且存在 requiredMax 时生效：
     * 用 requiredMax 减去 historicalItems 中目标商品的累计数量，保底 0。
     * 其余场景返回 undefined，保持向后兼容。
     */
  }, {
    key: "calculateRemainingMax",
    value: function calculateRemainingMax(scope, requiredMax, targets, businessData) {
      if (scope !== 'cumulative' || typeof requiredMax !== 'number') {
        return undefined;
      }
      var historicalItems = businessData.historicalItems;
      if (!(historicalItems !== null && historicalItems !== void 0 && historicalItems.length)) {
        return Math.max(0, requiredMax);
      }
      var targetIds = new Set(targets.map(function (t) {
        return t.product_id;
      }));
      var historicalQty = 0;
      var _iterator5 = _createForOfIteratorHelper(historicalItems),
        _step5;
      try {
        for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
          var item = _step5.value;
          if (targetIds.has(item.product_id)) {
            historicalQty += item.quantity;
          }
        }
      } catch (err) {
        _iterator5.e(err);
      } finally {
        _iterator5.f();
      }
      return Math.max(0, requiredMax - historicalQty);
    }

    // ============================================
    // Prefill Cart 处理
    // ============================================
  }, {
    key: "processPrefillCart",
    value: function processPrefillCart(action, businessData) {
      var config = action.config;
      if (!(config !== null && config !== void 0 && config.products)) return [];
      var results = [];
      var _iterator6 = _createForOfIteratorHelper(config.products),
        _step6;
      try {
        for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
          var prefillProduct = _step6.value;
          var 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: quantity
          });
        }
      } catch (err) {
        _iterator6.e(err);
      } finally {
        _iterator6.f();
      }
      return results;
    }

    /**
     * 根据 quantityFrom 计算预填数量
     */
  }, {
    key: "resolvePrefillQuantity",
    value: function resolvePrefillQuantity(quantityFrom, fixedValue, businessData) {
      switch (quantityFrom) {
        case 'total_pax':
          return businessData.pax.total;
        case 'adult_pax':
          return businessData.pax.adult;
        case 'fixed':
          return fixedValue !== null && fixedValue !== void 0 ? fixedValue : 0;
        default:
          return fixedValue !== null && fixedValue !== void 0 ? fixedValue : 0;
      }
    }
  }]);
  return ItemRuleAdapter;
}();
export default ItemRuleAdapter;