var _excluded = ["_promotionTags"];
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
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 _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); }
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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return 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 _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 _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 _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 _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; }
import Decimal from 'decimal.js';
import { cloneDeep } from 'lodash-es';
import { composeLinePrice, createUuidV4, getProductSkuOptions, sumOptionUnitPrice } from "../../../modules/Order/utils";
import { buildProductLineFingerprint, getSafeProductNum } from "../../ScanOrder/utils";

/**
 * Cart promotion 工具集（OS 内部纯函数）
 *
 * 这是 `private-materials/components/booking/hooks/usePromotion.ts` 中促销/赠品
 * 核心计算（evaluator → 拆分 / 计价 → 赠品差异化 / 未满足提示 / 标签）的 OS 等价实现。
 *
 * 与 legacy 的关键差异：
 * - legacy 操作 booking `_extend.*` 形状；OS 操作 `OrderProduct.metadata.*` 形状。
 * - 行唯一标识不再用 `_id`，统一改用 `metadata.unique_identification_number`。
 * - 赠品标签存到 `metadata._giftInfo`；主商品促销信息存到 `metadata._promotion`；
 *   商品卡列表的促销 tag 存到 `metadata._promotionTags`。
 *
 * 仅暴露纯函数，不持有任何状态；评估器以参数注入。
 *
 * @example
 * const evaluator = appHelper.utils.promotionEvaluator;
 * const result = processCartPromotion(tempOrder.products, evaluator);
 * // result.products: 处理后的商品（带 _promotion / 拆分）
 * // result.giftActions: 需要 add / reduce / remove 的赠品操作
 * // result.unfulfilledPromotions: 未满足策略列表（购物车底部 alert）
 */

// ============================================
// 类型定义
// ============================================

/** Cart 评估器协议（只描述本文件用到的方法，避免循环依赖） */

/** 单个赠品减量项 */

/** 赠品新增项 */

/** 赠品操作集合（OS 侧根据它落地 tempOrder.products） */

/** 未满足促销提示项（购物车底部 alert 数据源） */

/** 商品卡促销标签结构（写入 `metadata._promotionTags`） */

/** processCartPromotion 输出 */

// ============================================
// 字段适配 helper
// ============================================

/**
 * 获取商品的「主商品基础价」用于评估器入参。
 *
 * 优先级（与 OS v2 schema 一致）：
 * 1. `metadata.source_product_price`
 * 2. `metadata.main_product_original_price` 减去 option 合计
 * 3. `original_price`
 */
export function getOrderProductBasePrice(product) {
  var _ref, _product$original_pri;
  var metadata = (product === null || product === void 0 ? void 0 : product.metadata) || {};
  var optionSum = sumOptionUnitPrice(getProductSkuOptions(product)).toNumber();
  if (metadata.source_product_price !== undefined) {
    var _v = Number(metadata.source_product_price);
    return Number.isFinite(_v) ? _v : 0;
  }
  if (metadata.main_product_original_price !== undefined) {
    var _v2 = Number(metadata.main_product_original_price) - optionSum;
    return Number.isFinite(_v2) ? _v2 : 0;
  }
  var v = Number((_ref = (_product$original_pri = product === null || product === void 0 ? void 0 : product.original_price) !== null && _product$original_pri !== void 0 ? _product$original_pri : product === null || product === void 0 ? void 0 : product.selling_price) !== null && _ref !== void 0 ? _ref : 0);
  return Number.isFinite(v) ? v : 0;
}

/**
 * 促销均摊专用原价（对齐 legacy `getMainOriginalPrice` 语义）。
 *
 * 必须用券前原价做 X_ITEMS_FOR_Y_PRICE 比例拆分；`source_product_price` 在上一轮 applyPromotion
 * 后可能已被写成促销价（如 5 / 9 / 1），若继续用它会导致同商品两行出现 9+1 而非 5+5。
 *
 * @example
 * getOrderProductOriginalPriceForPromotion({ metadata: { source_product_price: '9', main_product_original_price: '5.80' } });
 * // => 5.8
 */
export function getOrderProductOriginalPriceForPromotion(product) {
  var _metadata$_promotion;
  var metadata = (product === null || product === void 0 ? void 0 : product.metadata) || {};
  var optionSum = sumOptionUnitPrice(getProductSkuOptions(product)).toNumber();
  if (metadata.main_product_original_price !== undefined && metadata.main_product_original_price !== null && metadata.main_product_original_price !== '') {
    var v = Number(metadata.main_product_original_price) - optionSum;
    if (Number.isFinite(v) && v >= 0) return v;
  }
  var promoOriginal = (_metadata$_promotion = metadata._promotion) === null || _metadata$_promotion === void 0 ? void 0 : _metadata$_promotion.originalPrice;
  if (promoOriginal !== undefined && promoOriginal !== null && promoOriginal !== '') {
    var _v3 = Number(promoOriginal);
    if (Number.isFinite(_v3) && _v3 >= 0) return _v3;
  }
  return getOrderProductBasePrice(product);
}

/**
 * 写入/清除促销 discount_list（type=promotion）。
 *
 * applyDiscount → applyProductDiscountPrices 会从 source_product_price 减去 discount_list 合计
 * 重算 main_product_selling_price；保留券前 source 时必须同步写入促销差额，否则会还原成原价。
 *
 * @example
 * updatePromotionDiscountList(line, { title: '2 items for $10', amount: '17.00', original_amount: '22.00', fixed_amount: '17.00' });
 */
function updatePromotionDiscountList(item, promotionDiscount) {
  var discountList = Array.isArray(item.discount_list) ? _toConsumableArray(item.discount_list) : [];
  discountList = discountList.filter(function (d) {
    return (d === null || d === void 0 ? void 0 : d.type) !== 'promotion';
  });
  if (promotionDiscount) {
    discountList.push({
      type: 'promotion',
      amount: promotionDiscount.amount,
      discount: {
        original_amount: promotionDiscount.original_amount,
        fixed_amount: promotionDiscount.fixed_amount,
        title: promotionDiscount.title,
        resource_id: ''
      }
    });
  }
  if (discountList.length > 0) {
    item.discount_list = discountList;
  } else {
    delete item.discount_list;
  }
}
var X_ITEMS_FOR_Y_PRICE = 'X_ITEMS_FOR_Y_PRICE';
var BUY_X_GET_Y_FREE = 'BUY_X_GET_Y_FREE';

/**
 * 将促销单价写入 OrderProduct（含 metadata 三字段 + promotion discount_list）。
 *
 * @example
 * applyPromoUnitPriceToLine(newItem, { promoUnitPrice: '5.00', originalBasePrice: 1, strategyTitle: '2 for 10' });
 */
function applyPromoUnitPriceToLine(item, input) {
  var metadata = item.metadata || (item.metadata = {});
  var optionSum = sumOptionUnitPrice(getProductSkuOptions(item)).toNumber();
  var promoUnitPrice = new Decimal(Number(input.promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
  var mainSelling = new Decimal(Number(promoUnitPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
  var catalogSource = new Decimal(input.originalBasePrice).toDecimalPlaces(2).toFixed(2);
  metadata.source_product_price = catalogSource;
  metadata.main_product_original_price = new Decimal(Number(catalogSource) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
  metadata.main_product_selling_price = mainSelling;
  metadata.price_schema_version = 2;
  item.selling_price = composeLinePrice({
    mainPrice: mainSelling,
    bundle: item.product_bundle
  });
  item.original_price = composeLinePrice({
    mainPrice: metadata.main_product_original_price,
    bundle: item.product_bundle,
    useOriginalBundle: true
  });
  var discountAmount = new Decimal(input.originalBasePrice).minus(Number(promoUnitPrice) || 0).toDecimalPlaces(2).toFixed(2);
  if (Number(catalogSource) !== Number(promoUnitPrice)) {
    updatePromotionDiscountList(item, {
      title: input.strategyTitle || '',
      amount: discountAmount,
      original_amount: catalogSource,
      fixed_amount: discountAmount
    });
  } else {
    updatePromotionDiscountList(item, null);
  }
}
function getPromotionActionType(promotion) {
  var _promotion$strategyMe, _actions$;
  if (promotion !== null && promotion !== void 0 && promotion.actionType) return String(promotion.actionType);
  var actions = promotion === null || promotion === void 0 || (_promotion$strategyMe = promotion.strategyMetadata) === null || _promotion$strategyMe === void 0 ? void 0 : _promotion$strategyMe.actions;
  if (Array.isArray(actions) && (_actions$ = actions[0]) !== null && _actions$ !== void 0 && _actions$.type) return String(actions[0].type);
  return undefined;
}

/**
 * 同款行凑满 X件Y元 且仅该行参与时，按 Y/X 计算期望单价（2 件 $10 → $5）。
 *
 * @example
 * resolveXItemsExpectedUnitPrice({ actionType: 'X_ITEMS_FOR_Y_PRICE', actionDetail: { x: 2, price: 10 } }, 2);
 */
function resolveXItemsExpectedUnitPrice(promotion, sourceCartNum) {
  if (getPromotionActionType(promotion) !== X_ITEMS_FOR_Y_PRICE) return undefined;
  var detail = promotion === null || promotion === void 0 ? void 0 : promotion.actionDetail;
  var x = Number(detail === null || detail === void 0 ? void 0 : detail.x);
  var y = Number(detail === null || detail === void 0 ? void 0 : detail.price);
  if (!Number.isFinite(x) || x <= 0 || !Number.isFinite(y)) return undefined;
  if (sourceCartNum < x) return undefined;
  return Number(new Decimal(y).div(x).toDecimalPlaces(2).toFixed(2));
}

/**
 * 合并「同商品 + 同规格指纹 + 同促销策略 + 同促销单价」的参与促销行（num 累加）。
 * 避免 Browse Items 连续加购同款时拆成多行且单价被错误均摊。
 *
 * @example
 * mergeIdenticalPromotionCartLines(processedProducts);
 */
export function mergeIdenticalPromotionCartLines(products) {
  if (!Array.isArray(products) || products.length <= 1) {
    return _toConsumableArray(products || []);
  }
  var merged = [];
  var indexByKey = new Map();
  var _iterator = _createForOfIteratorHelper(products),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var _line$metadata, _ref2, _line$metadata$source, _line$metadata2, _ref3, _promotion$finalPrice, _line$metadata3, _line$booking_uid, _line$metadata4, _line$order_detail_id, _line$product_variant;
      var line = _step.value;
      if (getGiftInfo(line)) {
        merged.push(line);
        continue;
      }
      var promotion = line === null || line === void 0 || (_line$metadata = line.metadata) === null || _line$metadata === void 0 ? void 0 : _line$metadata._promotion;
      if (!(promotion !== null && promotion !== void 0 && promotion.inPromotion) || !promotion.strategyId) {
        merged.push(line);
        continue;
      }
      var fingerprint = buildProductLineFingerprint(getProductSkuOptions(line), line.product_bundle);
      var unitPrice = String((_ref2 = (_line$metadata$source = (_line$metadata2 = line.metadata) === null || _line$metadata2 === void 0 ? void 0 : _line$metadata2.source_product_price) !== null && _line$metadata$source !== void 0 ? _line$metadata$source : line.selling_price) !== null && _ref2 !== void 0 ? _ref2 : '');
      var promoUnitPrice = String((_ref3 = (_promotion$finalPrice = promotion.finalPrice) !== null && _promotion$finalPrice !== void 0 ? _promotion$finalPrice : (_line$metadata3 = line.metadata) === null || _line$metadata3 === void 0 ? void 0 : _line$metadata3.main_product_selling_price) !== null && _ref3 !== void 0 ? _ref3 : '');
      var bookingUid = (_line$booking_uid = line === null || line === void 0 ? void 0 : line.booking_uid) !== null && _line$booking_uid !== void 0 ? _line$booking_uid : line === null || line === void 0 || (_line$metadata4 = line.metadata) === null || _line$metadata4 === void 0 ? void 0 : _line$metadata4.booking_uid;
      var orderDetailId = (_line$order_detail_id = line === null || line === void 0 ? void 0 : line.order_detail_id) !== null && _line$order_detail_id !== void 0 ? _line$order_detail_id : line === null || line === void 0 ? void 0 : line.orderDetailId;
      var mergeKey = [line.product_id, (_line$product_variant = line.product_variant_id) !== null && _line$product_variant !== void 0 ? _line$product_variant : 0, fingerprint, bookingUid ? String(bookingUid) : '', orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '' ? String(orderDetailId) : '', promotion.strategyId, unitPrice, promoUnitPrice].join('#');
      var hitIndex = indexByKey.get(mergeKey);
      if (hitIndex === undefined) {
        indexByKey.set(mergeKey, merged.length);
        merged.push(line);
        continue;
      }
      var target = merged[hitIndex];
      target.num = getSafeProductNum(Number(target.num || 0) + Number(line.num || 0));
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return merged;
}

/**
 * 同一原购物车行被多个「inPromotion」评估结果命中时（如买赠不改价 + X件Y元），
 * 优先保留 X件Y元 定价，并恢复加购前的行数量。
 *
 * @example
 * dedupePromotionProcessedLines(processedProducts);
 */
function dedupePromotionProcessedLines(lines) {
  if (!Array.isArray(lines) || lines.length <= 1) return _toConsumableArray(lines || []);
  var passthrough = [];
  var buckets = new Map();
  var _iterator2 = _createForOfIteratorHelper(lines),
    _step2;
  try {
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      var _line$metadata6;
      var line = _step2.value;
      var promo = line === null || line === void 0 || (_line$metadata6 = line.metadata) === null || _line$metadata6 === void 0 ? void 0 : _line$metadata6._promotion;
      var originalUid = String(line._originalProductUid || getOrderProductUid(line) || '');
      if (!(promo !== null && promo !== void 0 && promo.inPromotion) || !originalUid) {
        passthrough.push(line);
        continue;
      }
      var group = buckets.get(originalUid) || [];
      group.push(line);
      buckets.set(originalUid, group);
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  var promotionDelta = function promotionDelta(line) {
    var _line$metadata5;
    var promo = (_line$metadata5 = line.metadata) === null || _line$metadata5 === void 0 ? void 0 : _line$metadata5._promotion;
    var original = Number(promo === null || promo === void 0 ? void 0 : promo.originalPrice);
    var final = Number(promo === null || promo === void 0 ? void 0 : promo.finalPrice);
    if (!Number.isFinite(original) || !Number.isFinite(final)) return 0;
    return Math.abs(original - final);
  };
  var deduped = [].concat(passthrough);
  var _iterator3 = _createForOfIteratorHelper(buckets),
    _step3;
  try {
    var _loop = function _loop() {
      var _winner$metadata, _winner$metadata2, _winner$metadata3;
      var _step3$value = _slicedToArray(_step3.value, 2),
        originalUid = _step3$value[0],
        group = _step3$value[1];
      if (group.length === 1) {
        deduped.push(group[0]);
        return 1; // continue
      }
      var sourceCartNum = Math.max.apply(Math, _toConsumableArray(group.map(function (line) {
        return Number(line._sourceCartNum || line.num || 0);
      })));
      var pricingLines = group.filter(function (line) {
        return promotionDelta(line) > 0;
      });
      var xItemsLines = (pricingLines.length ? pricingLines : group).filter(function (line) {
        var _line$metadata7;
        return getPromotionActionType((_line$metadata7 = line.metadata) === null || _line$metadata7 === void 0 ? void 0 : _line$metadata7._promotion) === X_ITEMS_FOR_Y_PRICE;
      });
      var pool = xItemsLines.length ? xItemsLines : pricingLines.length ? pricingLines : group;
      var winner = pool[0];
      var expectedUnit = resolveXItemsExpectedUnitPrice((_winner$metadata = winner.metadata) === null || _winner$metadata === void 0 ? void 0 : _winner$metadata._promotion, sourceCartNum);
      if (expectedUnit != null && pool.length > 1) {
        winner = pool.reduce(function (best, line) {
          var _best$metadata, _line$metadata8;
          var bestDiff = Math.abs(Number((_best$metadata = best.metadata) === null || _best$metadata === void 0 || (_best$metadata = _best$metadata._promotion) === null || _best$metadata === void 0 ? void 0 : _best$metadata.finalPrice) - expectedUnit);
          var lineDiff = Math.abs(Number((_line$metadata8 = line.metadata) === null || _line$metadata8 === void 0 || (_line$metadata8 = _line$metadata8._promotion) === null || _line$metadata8 === void 0 ? void 0 : _line$metadata8.finalPrice) - expectedUnit);
          return lineDiff < bestDiff ? line : best;
        }, pool[0]);
      } else if (pool.length > 1 && !expectedUnit) {
        winner = pool.reduce(function (best, line) {
          var _best$metadata2, _line$metadata9, _line$metadata10;
          var bestFinal = Number((_best$metadata2 = best.metadata) === null || _best$metadata2 === void 0 || (_best$metadata2 = _best$metadata2._promotion) === null || _best$metadata2 === void 0 ? void 0 : _best$metadata2.finalPrice);
          var lineFinal = Number((_line$metadata9 = line.metadata) === null || _line$metadata9 === void 0 || (_line$metadata9 = _line$metadata9._promotion) === null || _line$metadata9 === void 0 ? void 0 : _line$metadata9.finalPrice);
          var original = Number((_line$metadata10 = line.metadata) === null || _line$metadata10 === void 0 || (_line$metadata10 = _line$metadata10._promotion) === null || _line$metadata10 === void 0 ? void 0 : _line$metadata10.originalPrice);
          if (Number.isFinite(original) && lineFinal >= original && bestFinal >= original) {
            return lineFinal < bestFinal ? line : best;
          }
          return promotionDelta(line) > promotionDelta(best) ? line : best;
        }, pool[0]);
      }

      // X件Y元：评估器会按单件均摊产出多条 inPromotion 行（如 $1 + $9），
      // dedupe 应合并为「同组 X件Y元 行 num 之和」，不能用 sourceCartNum（整单 3 件）。
      var winnerIsXItems = getPromotionActionType((_winner$metadata2 = winner.metadata) === null || _winner$metadata2 === void 0 ? void 0 : _winner$metadata2._promotion) === X_ITEMS_FOR_Y_PRICE;
      if (winnerIsXItems) {
        var xItemsGroupLines = group.filter(function (line) {
          var _line$metadata11;
          return getPromotionActionType((_line$metadata11 = line.metadata) === null || _line$metadata11 === void 0 ? void 0 : _line$metadata11._promotion) === X_ITEMS_FOR_Y_PRICE;
        });
        var evaluatedPromoQty = xItemsGroupLines.reduce(function (sum, line) {
          return sum + Number(line.num || 0);
        }, 0);
        winner.num = getSafeProductNum(evaluatedPromoQty || winner.num || 1);
      } else {
        winner.num = getSafeProductNum(sourceCartNum || winner.num || 1);
      }
      var recomputeUnit = resolveXItemsExpectedUnitPrice((_winner$metadata3 = winner.metadata) === null || _winner$metadata3 === void 0 ? void 0 : _winner$metadata3._promotion, sourceCartNum);
      if (recomputeUnit != null) {
        var _promo$strategyMetada;
        var _promo = winner.metadata._promotion;
        applyPromoUnitPriceToLine(winner, {
          promoUnitPrice: recomputeUnit,
          originalBasePrice: Number(_promo.originalPrice),
          strategyTitle: (_promo$strategyMetada = _promo.strategyMetadata) === null || _promo$strategyMetada === void 0 ? void 0 : _promo$strategyMetada.name
        });
        _promo.finalPrice = recomputeUnit;
      }
      var _iterator4 = _createForOfIteratorHelper(group),
        _step4;
      try {
        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
          var _line$metadata12, _winner$metadata4;
          var _line = _step4.value;
          var giftInfo = (_line$metadata12 = _line.metadata) === null || _line$metadata12 === void 0 || (_line$metadata12 = _line$metadata12._promotion) === null || _line$metadata12 === void 0 ? void 0 : _line$metadata12.giftInfo;
          if (giftInfo && (_winner$metadata4 = winner.metadata) !== null && _winner$metadata4 !== void 0 && _winner$metadata4._promotion && !winner.metadata._promotion.giftInfo) {
            winner.metadata._promotion.giftInfo = giftInfo;
          }
        }
      } catch (err) {
        _iterator4.e(err);
      } finally {
        _iterator4.f();
      }
      deduped.push(winner);
    };
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      if (_loop()) continue;
    }
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
  return deduped;
}

/** 获取行 uid（统一以 `metadata.unique_identification_number` 为唯一键） */
export function getOrderProductUid(product) {
  var _ref4, _product$metadata$uni, _product$metadata;
  return String((_ref4 = (_product$metadata$uni = product === null || product === void 0 || (_product$metadata = product.metadata) === null || _product$metadata === void 0 ? void 0 : _product$metadata.unique_identification_number) !== null && _product$metadata$uni !== void 0 ? _product$metadata$uni : product === null || product === void 0 ? void 0 : product.unique_identification_number) !== null && _ref4 !== void 0 ? _ref4 : '');
}
function getGiftInfo(product) {
  var _product$metadata2;
  return (product === null || product === void 0 || (_product$metadata2 = product.metadata) === null || _product$metadata2 === void 0 ? void 0 : _product$metadata2._giftInfo) || (product === null || product === void 0 ? void 0 : product._giftInfo) || null;
}
function isPersistedGeneratedVoucher(product) {
  var _product$order_detail;
  var orderDetailId = (_product$order_detail = product === null || product === void 0 ? void 0 : product.order_detail_id) !== null && _product$order_detail !== void 0 ? _product$order_detail : product === null || product === void 0 ? void 0 : product.orderDetailId;
  if (orderDetailId === undefined || orderDetailId === null || orderDetailId === '') {
    return false;
  }
  var metadata = (product === null || product === void 0 ? void 0 : product.metadata) || {};
  return (product === null || product === void 0 ? void 0 : product.extension_type) === 'product_voucher' || metadata.parent_order_detail_id !== undefined || metadata.gift_card_type !== undefined;
}
function getProductBundleForEvaluator(product) {
  var bundles = Array.isArray(product === null || product === void 0 ? void 0 : product.product_bundle) ? product.product_bundle : [];
  return bundles.map(function (b) {
    var _ref5, _b$bundle_product_id, _ref6, _b$bundle_variant_id, _ref7, _b$num, _ref8, _b$bundle_selling_pri, _ref9, _ref10, _b$original_price, _ref11, _b$bundle_id, _ref12, _b$_bundle_product_id;
    return {
      product_id: (_ref5 = (_b$bundle_product_id = b === null || b === void 0 ? void 0 : b.bundle_product_id) !== null && _b$bundle_product_id !== void 0 ? _b$bundle_product_id : b === null || b === void 0 ? void 0 : b._bundle_product_id) !== null && _ref5 !== void 0 ? _ref5 : b === null || b === void 0 ? void 0 : b.product_id,
      product_variant_id: (_ref6 = (_b$bundle_variant_id = b === null || b === void 0 ? void 0 : b.bundle_variant_id) !== null && _b$bundle_variant_id !== void 0 ? _b$bundle_variant_id : b === null || b === void 0 ? void 0 : b.product_variant_id) !== null && _ref6 !== void 0 ? _ref6 : 0,
      quantity: Number((_ref7 = (_b$num = b === null || b === void 0 ? void 0 : b.num) !== null && _b$num !== void 0 ? _b$num : b === null || b === void 0 ? void 0 : b.quantity) !== null && _ref7 !== void 0 ? _ref7 : 1) || 1,
      price: Number((_ref8 = (_b$bundle_selling_pri = b === null || b === void 0 ? void 0 : b.bundle_selling_price) !== null && _b$bundle_selling_pri !== void 0 ? _b$bundle_selling_pri : b === null || b === void 0 ? void 0 : b.price) !== null && _ref8 !== void 0 ? _ref8 : 0) || 0,
      original_price: Number((_ref9 = (_ref10 = (_b$original_price = b === null || b === void 0 ? void 0 : b.original_price) !== null && _b$original_price !== void 0 ? _b$original_price : b === null || b === void 0 ? void 0 : b.product_price) !== null && _ref10 !== void 0 ? _ref10 : b === null || b === void 0 ? void 0 : b.price) !== null && _ref9 !== void 0 ? _ref9 : 0) || 0,
      id: (_ref11 = (_b$bundle_id = b === null || b === void 0 ? void 0 : b.bundle_id) !== null && _b$bundle_id !== void 0 ? _b$bundle_id : b === null || b === void 0 ? void 0 : b.id) !== null && _ref11 !== void 0 ? _ref11 : 0,
      _bundle_product_id: (_ref12 = (_b$_bundle_product_id = b === null || b === void 0 ? void 0 : b._bundle_product_id) !== null && _b$_bundle_product_id !== void 0 ? _b$_bundle_product_id : b === null || b === void 0 ? void 0 : b.bundle_product_id) !== null && _ref12 !== void 0 ? _ref12 : b === null || b === void 0 ? void 0 : b.product_id
    };
  });
}

/**
 * 促销评估前合并同 SKU 拆分行（含促销/原价行），避免加购后仅前 2 件享受优惠。
 * 带 `booking_uid` 的预约行不参与合并（每次加车独立 booking + 商品行）。
 *
 * @example
 * consolidateMainProductsForPromotion([
 *   { item: promoLineNum2, originalListIndex: 0 },
 *   { item: regularLineNum2, originalListIndex: 1 },
 * ]);
 * // => 单行 num=4，清除 _promotion 后重新评估
 */
export function buildConsolidateKeyForPromotion(item) {
  var _item$booking_uid, _item$metadata, _item$order_detail_id, _item$product_variant3;
  var fingerprint = buildProductLineFingerprint(getProductSkuOptions(item), item.product_bundle);
  var bookingUid = (_item$booking_uid = item === null || item === void 0 ? void 0 : item.booking_uid) !== null && _item$booking_uid !== void 0 ? _item$booking_uid : item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.booking_uid;
  var orderDetailId = (_item$order_detail_id = item === null || item === void 0 ? void 0 : item.order_detail_id) !== null && _item$order_detail_id !== void 0 ? _item$order_detail_id : item === null || item === void 0 ? void 0 : item.orderDetailId;
  if (orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '') {
    var _item$product_variant;
    return [item.product_id, (_item$product_variant = item.product_variant_id) !== null && _item$product_variant !== void 0 ? _item$product_variant : 0, fingerprint, String(orderDetailId)].join('#');
  }
  if (bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '') {
    var _item$product_variant2;
    return [item.product_id, (_item$product_variant2 = item.product_variant_id) !== null && _item$product_variant2 !== void 0 ? _item$product_variant2 : 0, fingerprint, String(bookingUid)].join('#');
  }
  return [item.product_id, (_item$product_variant3 = item.product_variant_id) !== null && _item$product_variant3 !== void 0 ? _item$product_variant3 : 0, fingerprint].join('#');
}
function consolidateMainProductsForPromotion(entries) {
  if (!Array.isArray(entries) || entries.length <= 1) {
    return _toConsumableArray(entries || []);
  }
  var groups = new Map();
  var _iterator5 = _createForOfIteratorHelper(entries),
    _step5;
  try {
    for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
      var _step5$value = _step5.value,
        item = _step5$value.item,
        originalListIndex = _step5$value.originalListIndex;
      var key = buildConsolidateKeyForPromotion(item);
      var existing = groups.get(key);
      if (!existing) {
        var mergedItem = cloneDeep(item);
        var metadata = mergedItem.metadata || {};
        delete metadata._promotion;
        mergedItem.metadata = metadata;
        if (Array.isArray(mergedItem.product_bundle)) {
          var _iterator6 = _createForOfIteratorHelper(mergedItem.product_bundle),
            _step6;
          try {
            for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
              var bundle = _step6.value;
              if (bundle && _typeof(bundle) === 'object') delete bundle._promotion;
            }
          } catch (err) {
            _iterator6.e(err);
          } finally {
            _iterator6.f();
          }
        }
        groups.set(key, {
          item: mergedItem,
          originalListIndex: originalListIndex
        });
        continue;
      }
      existing.item.num = getSafeProductNum(Number(existing.item.num || 0) + Number(item.num || 0));
    }
  } catch (err) {
    _iterator5.e(err);
  } finally {
    _iterator5.f();
  }
  return Array.from(groups.values());
}

/**
 * X件Y元 整组凑满时按每组 x 件拆开展示（4 件 → 2 行各 2 件 $10）。
 *
 * @example
 * splitXItemsPromoLinesByGroup(mergedLines, strategyActionMap);
 */
function splitXItemsPromoLinesByGroup(lines, strategyActionMap) {
  var result = [];
  var _iterator7 = _createForOfIteratorHelper(lines),
    _step7;
  try {
    for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
      var _line$metadata13, _actionMeta$actionDet;
      var line = _step7.value;
      var promo = line === null || line === void 0 || (_line$metadata13 = line.metadata) === null || _line$metadata13 === void 0 ? void 0 : _line$metadata13._promotion;
      if (!(promo !== null && promo !== void 0 && promo.inPromotion) || !promo.strategyId) {
        result.push(line);
        continue;
      }
      if (getPromotionActionType(promo) !== X_ITEMS_FOR_Y_PRICE) {
        result.push(line);
        continue;
      }
      var actionMeta = strategyActionMap.get(promo.strategyId);
      var detail = (_actionMeta$actionDet = actionMeta === null || actionMeta === void 0 ? void 0 : actionMeta.actionDetail) !== null && _actionMeta$actionDet !== void 0 ? _actionMeta$actionDet : promo.actionDetail;
      var x = Number(detail === null || detail === void 0 ? void 0 : detail.x);
      var num = Number(line.num || 0);
      var isCumulative = (detail === null || detail === void 0 ? void 0 : detail.cumulative) !== false;
      if (!isCumulative || !Number.isFinite(x) || x <= 0 || num <= x || num % x !== 0) {
        result.push(line);
        continue;
      }
      var groupCount = num / x;
      for (var i = 0; i < groupCount; i++) {
        var splitLine = cloneDeep(line);
        splitLine.num = getSafeProductNum(x);
        splitLine.metadata = _objectSpread(_objectSpread({}, splitLine.metadata || {}), {}, {
          unique_identification_number: createUuidV4()
        });
        result.push(splitLine);
      }
    }
  } catch (err) {
    _iterator7.e(err);
  } finally {
    _iterator7.f();
  }
  return result;
}

/** 生成新 numeric id（仅用于评估器内部追踪） */
function generateNumericId() {
  return Math.floor(Math.random() * 1000000000) + Date.now();
}

/**
 * 把 OrderProduct 转成 evaluator 的 PromotionProduct（仅评估期使用）。
 *
 * 注意：评估器是「无状态、按 product_id + variant 组」工作的；这里给每行分配一个
 * numericId 用于关联回原 OrderProduct（通过 originalItemMap）。
 */
function convertToPromotionProduct(product, index) {
  var _product$product_id, _product$product_vari, _product$num;
  var metadata = (product === null || product === void 0 ? void 0 : product.metadata) || {};
  var numericId = generateNumericId();
  var originalItem = product;
  return {
    id: numericId,
    product_id: Number((_product$product_id = product === null || product === void 0 ? void 0 : product.product_id) !== null && _product$product_id !== void 0 ? _product$product_id : 0) || 0,
    product_variant_id: Number((_product$product_vari = product === null || product === void 0 ? void 0 : product.product_variant_id) !== null && _product$product_vari !== void 0 ? _product$product_vari : 0) || 0,
    name: metadata.product_name || (product === null || product === void 0 ? void 0 : product.title) || '',
    price: getOrderProductOriginalPriceForPromotion(product),
    quantity: Number((_product$num = product === null || product === void 0 ? void 0 : product.num) !== null && _product$num !== void 0 ? _product$num : 1) || 1,
    bundle: getProductBundleForEvaluator(product),
    _originalItem: originalItem,
    _originalId: getOrderProductUid(product),
    _originalIndex: index
  };
}

// ============================================
// 主流程：processCartPromotion
// ============================================

/**
 * 计算赠品差异化操作（toAdd / toReduce / toRemove）。
 *
 * 与 legacy `calculateGiftActions` 等价；唯一差别是行键从 `_id` 改成 `metadata.unique_identification_number`。
 */
function calculateGiftActions(gifts, existingGifts) {
  var toAdd = [];
  var toReduce = [];
  var toRemove = [];

  // 按 strategyId 分组现有赠品
  var existingByStrategy = new Map();
  var _iterator8 = _createForOfIteratorHelper(existingGifts),
    _step8;
  try {
    for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
      var _getGiftInfo, _gift$num;
      var gift = _step8.value;
      var strategyId = (_getGiftInfo = getGiftInfo(gift)) === null || _getGiftInfo === void 0 ? void 0 : _getGiftInfo.strategyId;
      if (!strategyId) continue;
      var existing = existingByStrategy.get(strategyId);
      var qty = Number((_gift$num = gift === null || gift === void 0 ? void 0 : gift.num) !== null && _gift$num !== void 0 ? _gift$num : 1) || 1;
      if (existing) {
        existing.items.push(gift);
        existing.totalQuantity += qty;
      } else {
        existingByStrategy.set(strategyId, {
          items: [gift],
          totalQuantity: qty
        });
      }
    }
  } catch (err) {
    _iterator8.e(err);
  } finally {
    _iterator8.f();
  }
  var processedStrategyIds = new Set();
  var _iterator9 = _createForOfIteratorHelper(gifts),
    _step9;
  try {
    for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
      var _existing$totalQuanti;
      var giftInfo = _step9.value;
      var _strategyId = giftInfo.strategyId,
        strategyName = giftInfo.strategyName,
        giftCount = giftInfo.giftCount,
        giftOptions = giftInfo.giftOptions,
        sourceProductIds = giftInfo.sourceProductIds;
      processedStrategyIds.add(_strategyId);
      var _existing = existingByStrategy.get(_strategyId);
      var existingCount = (_existing$totalQuanti = _existing === null || _existing === void 0 ? void 0 : _existing.totalQuantity) !== null && _existing$totalQuanti !== void 0 ? _existing$totalQuanti : 0;
      var diff = giftCount - existingCount;
      if (diff > 0) {
        var _getGiftInfo2, _existing$items;
        // 判断「用户手动减赠品」: 若评估器的 giftCount 没变，diff>0 说明是手动减，跳过补回
        var lastEvaluated = (_getGiftInfo2 = getGiftInfo(_existing === null || _existing === void 0 || (_existing$items = _existing.items) === null || _existing$items === void 0 ? void 0 : _existing$items[0])) === null || _getGiftInfo2 === void 0 ? void 0 : _getGiftInfo2.lastEvaluatedGiftCount;
        var strategyChanged = lastEvaluated === undefined || giftCount !== lastEvaluated;
        if (strategyChanged) {
          toAdd.push({
            strategyId: _strategyId,
            strategyName: strategyName,
            giftCount: diff,
            giftOptions: giftOptions,
            sourceProductIds: sourceProductIds
          });
        }
      } else if (diff < 0) {
        // 减赠品：后进先出
        var remaining = Math.abs(diff);
        var reduceItems = [];
        var removeIds = [];
        var reversed = _toConsumableArray((_existing === null || _existing === void 0 ? void 0 : _existing.items) || []).reverse();
        var _iterator11 = _createForOfIteratorHelper(reversed),
          _step11;
        try {
          for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
            var _giftItem$num;
            var giftItem = _step11.value;
            if (remaining <= 0) break;
            var uid = getOrderProductUid(giftItem);
            var _qty = Number((_giftItem$num = giftItem === null || giftItem === void 0 ? void 0 : giftItem.num) !== null && _giftItem$num !== void 0 ? _giftItem$num : 1) || 1;
            if (_qty <= remaining) {
              removeIds.push(uid);
              remaining -= _qty;
            } else {
              reduceItems.push({
                uid: uid,
                currentQuantity: _qty,
                newQuantity: _qty - remaining
              });
              remaining = 0;
            }
          }
        } catch (err) {
          _iterator11.e(err);
        } finally {
          _iterator11.f();
        }
        if (reduceItems.length > 0) toReduce.push({
          strategyId: _strategyId,
          items: reduceItems
        });
        toRemove.push.apply(toRemove, removeIds);
      }
    }

    // 失效策略的赠品：全部 remove
  } catch (err) {
    _iterator9.e(err);
  } finally {
    _iterator9.f();
  }
  var _iterator10 = _createForOfIteratorHelper(existingByStrategy),
    _step10;
  try {
    for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
      var _step10$value = _slicedToArray(_step10.value, 2),
        _strategyId2 = _step10$value[0],
        _existing2 = _step10$value[1];
      if (processedStrategyIds.has(_strategyId2)) continue;
      var _iterator12 = _createForOfIteratorHelper(_existing2.items),
        _step12;
      try {
        for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
          var _giftItem = _step12.value;
          toRemove.push(getOrderProductUid(_giftItem));
        }
      } catch (err) {
        _iterator12.e(err);
      } finally {
        _iterator12.f();
      }
    }
  } catch (err) {
    _iterator10.e(err);
  } finally {
    _iterator10.f();
  }
  return {
    toAdd: toAdd,
    toReduce: toReduce,
    toRemove: toRemove
  };
}

/**
 * 从策略配置的 product_match 规则提取可参与商品列表。
 *
 * @example
 * extractProductMatchIdentifiersFromStrategyConfig(strategyConfig);
 * // => [{ product_id: 60736, product_variant_id: 0 }]
 */
export function extractProductMatchIdentifiersFromStrategyConfig(strategyConfig) {
  var _strategyConfig$condi;
  var rules = strategyConfig === null || strategyConfig === void 0 || (_strategyConfig$condi = strategyConfig.conditions) === null || _strategyConfig$condi === void 0 ? void 0 : _strategyConfig$condi.rules;
  if (!Array.isArray(rules)) return [];
  var _iterator13 = _createForOfIteratorHelper(rules),
    _step13;
  try {
    for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
      var rule = _step13.value;
      if ((rule === null || rule === void 0 ? void 0 : rule.field) === 'productIdAndVariantId' && ((rule === null || rule === void 0 ? void 0 : rule.operator) === 'product_match' || (rule === null || rule === void 0 ? void 0 : rule.operator) === 'object_in') && Array.isArray(rule === null || rule === void 0 ? void 0 : rule.value)) {
        return rule.value.map(function (item) {
          return {
            product_id: Number(item === null || item === void 0 ? void 0 : item.product_id) || 0,
            product_variant_id: Number(item === null || item === void 0 ? void 0 : item.product_variant_id) || 0
          };
        }).filter(function (item) {
          return item.product_id > 0;
        });
      }
    }
  } catch (err) {
    _iterator13.e(err);
  } finally {
    _iterator13.f();
  }
  return [];
}

/**
 * 解析策略凑单所需件数（evaluator 原始返回可能不含 requiredQuantity）。
 *
 * @example
 * resolveStrategyRequiredQuantity({ actionType: 'X_ITEMS_FOR_Y_PRICE', actionDetail: { x: 2 } });
 */
export function resolveStrategyRequiredQuantity(matched) {
  var preset = Number(matched.requiredQuantity);
  if (Number.isFinite(preset) && preset > 0) return preset;
  var detail = matched.actionDetail || {};
  if (matched.actionType === 'X_ITEMS_FOR_Y_PRICE') {
    return Number(detail.x) || 2;
  }
  if (matched.actionType === 'BUY_X_GET_Y_FREE') {
    return Number(detail.buyQuantity) || 1;
  }
  return 1;
}

/**
 * 解析 Browse Items 弹窗候选商品（优先 eligibleProducts，否则读 strategyConfig）。
 *
 * @example
 * resolveStrategyEligibleProducts(matchedStrategy);
 */
export function resolveStrategyEligibleProducts(matched) {
  if (Array.isArray(matched.eligibleProducts) && matched.eligibleProducts.length > 0) {
    return matched.eligibleProducts;
  }
  return extractProductMatchIdentifiersFromStrategyConfig(matched.strategyConfig);
}

/**
 * 计算未满足促销条件（用于购物车底部「再买 N 件即可享受 XX」alert）。
 *
 * 数据源：商品的 `metadata._promotion.inPromotion === false`（来自 processCartPromotion
 * 第 8 步追加的「有适用策略但当前未参与促销」标记）。
 */
export function calculateUnfulfilledPromotions(processedProducts, applicableStrategiesResult, mainProducts) {
  var unfulfilledMap = new Map();
  var _loop2 = function _loop2() {
      var _product$metadata3, _ref13, _product$_originalPro, _product$metadata4, _product$num2;
      var product = processedProducts[i];
      var promotion = product === null || product === void 0 || (_product$metadata3 = product.metadata) === null || _product$metadata3 === void 0 ? void 0 : _product$metadata3._promotion;
      if (!promotion || promotion.inPromotion !== false) return 0; // continue
      var strategyId = promotion.strategyId;
      if (!strategyId) return 0; // continue
      var lookupUid = String((_ref13 = (_product$_originalPro = product === null || product === void 0 ? void 0 : product._originalProductUid) !== null && _product$_originalPro !== void 0 ? _product$_originalPro : product === null || product === void 0 || (_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4.unique_identification_number) !== null && _ref13 !== void 0 ? _ref13 : '');
      var originalIndex = mainProducts.findIndex(function (item) {
        return getOrderProductUid(item) === lookupUid;
      });
      if (originalIndex === -1) return 0; // continue
      var strategyData = applicableStrategiesResult[originalIndex];
      if (!strategyData || !strategyData.hasApplicableStrategy) return 0; // continue
      var matched = strategyData.applicableStrategies.find(function (s) {
        return s.strategyId === strategyId;
      });
      if (!matched) return 0; // continue
      var quantity = Number((_product$num2 = product === null || product === void 0 ? void 0 : product.num) !== null && _product$num2 !== void 0 ? _product$num2 : 1) || 1;
      if (unfulfilledMap.has(strategyId)) {
        unfulfilledMap.get(strategyId).currentQuantity += quantity;
      } else {
        unfulfilledMap.set(strategyId, {
          strategyId: strategyId,
          strategyName: matched.strategyName,
          actionType: matched.actionType,
          currentQuantity: quantity,
          requiredQuantity: resolveStrategyRequiredQuantity(matched),
          needQuantity: 0,
          eligibleProducts: resolveStrategyEligibleProducts(matched),
          strategyMetadata: matched.strategyMetadata,
          display: matched.display
        });
      }
    },
    _ret;
  for (var i = 0; i < processedProducts.length; i++) {
    _ret = _loop2();
    if (_ret === 0) continue;
  }
  var result = [];
  var _iterator14 = _createForOfIteratorHelper(unfulfilledMap.values()),
    _step14;
  try {
    for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
      var data = _step14.value;
      var needQuantity = data.requiredQuantity - data.currentQuantity;
      if (needQuantity > 0) {
        result.push(_objectSpread(_objectSpread({}, data), {}, {
          needQuantity: needQuantity
        }));
      }
    }
  } catch (err) {
    _iterator14.e(err);
  } finally {
    _iterator14.f();
  }
  return result;
}

/**
 * 给商品列表追加促销标签（写入 `metadata._promotionTags`），供 ProductCard 渲染。
 *
 * - 没有适用策略的商品会清除 `_promotionTags`（避免脏数据）。
 * - 仅基于 product_id 匹配（matchVariant=false），与商品卡通用场景对齐。
 *
 * @example
 * const list = appendPromotionTags(catalog, evaluator);
 * // list[i].metadata._promotionTags = [{ text, type, strategyId }]
 */
export function appendPromotionTags(products, evaluator) {
  if (!Array.isArray(products) || products.length === 0 || !evaluator) {
    return products || [];
  }

  // 评估器期望的 product shape，最少字段集
  var evaluatorInput = products.map(function (item, index) {
    var _ref14, _item$id, _item$product_variant4, _item$price, _item$quantity;
    return {
      id: index,
      product_id: Number((_ref14 = (_item$id = item === null || item === void 0 ? void 0 : item.id) !== null && _item$id !== void 0 ? _item$id : item === null || item === void 0 ? void 0 : item.product_id) !== null && _ref14 !== void 0 ? _ref14 : 0) || 0,
      product_variant_id: Number((_item$product_variant4 = item === null || item === void 0 ? void 0 : item.product_variant_id) !== null && _item$product_variant4 !== void 0 ? _item$product_variant4 : 0) || 0,
      name: (item === null || item === void 0 ? void 0 : item.title) || (item === null || item === void 0 ? void 0 : item.name) || '',
      price: Number((_item$price = item === null || item === void 0 ? void 0 : item.price) !== null && _item$price !== void 0 ? _item$price : 0) || 0,
      quantity: Number((_item$quantity = item === null || item === void 0 ? void 0 : item.quantity) !== null && _item$quantity !== void 0 ? _item$quantity : 1) || 1,
      bundle: []
    };
  });
  var strategies = evaluator.getProductsApplicableStrategies({
    products: evaluatorInput
  }, false);
  return products.map(function (item, index) {
    var data = strategies[index];
    var tags = [];
    if (data !== null && data !== void 0 && data.hasApplicableStrategy) {
      var _iterator15 = _createForOfIteratorHelper(data.applicableStrategies),
        _step15;
      try {
        for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
          var strategy = _step15.value;
          if (strategy.display) {
            tags.push({
              text: strategy.display.text,
              type: strategy.display.type,
              strategyId: strategy.strategyId
            });
          }
        }
      } catch (err) {
        _iterator15.e(err);
      } finally {
        _iterator15.f();
      }
    }
    // 商品卡兼容两种位置：顶层 `_promotionTags` 与 `metadata._promotionTags`
    // ProductCard 现有实现读顶层（详见 productSelect/ProductCard/index.tsx），
    // 此处同时写顶层以保持视图直连；OrderProduct 行版本走 metadata（避免顶层非协议字段）。
    if (tags.length === 0) {
      var _ref15 = item,
        _promotionTags = _ref15._promotionTags,
        rest = _objectWithoutProperties(_ref15, _excluded);
      void _promotionTags;
      return rest;
    }
    return _objectSpread(_objectSpread({}, item), {}, {
      _promotionTags: tags
    });
  });
}

/**
 * 处理购物车的促销计算与赠品差异化。
 *
 * 流程：
 * 1. 分离 main / gift / edit-product 三类（带 `booking_id` 的编辑态商品不参与促销）
 * 2. 转 PromotionProduct 喂评估器 → 拿到 `evaluateCartWithPricing` 与 `getProductsApplicableStrategies`
 * 3. 把 PricedProduct 映射回 OrderProduct 形态：
 *    - 参与促销的，写 `metadata._promotion` + 调整 `selling_price` / `main_product_selling_price`
 *    - 拆分的，生成新 uid，复制原行其它字段
 * 4. 计算 `_giftInfo` 挂主商品（每个策略首个主商品）
 * 5. 计算 `giftActions`（toAdd / toReduce / toRemove）
 * 6. 计算 `unfulfilledPromotions`
 *
 * @example
 * const { products, giftActions, unfulfilledPromotions } = processCartPromotion(
 *   tempOrder.products,
 *   evaluator,
 * );
 */
export function processCartPromotion(list, evaluator, options) {
  var empty = {
    products: Array.isArray(list) ? _toConsumableArray(list) : [],
    totalDiscount: 0,
    gifts: [],
    giftActions: {
      toAdd: [],
      toReduce: [],
      toRemove: []
    },
    unfulfilledPromotions: []
  };
  if (!list || list.length === 0 || !evaluator) return empty;

  // 0. 分类
  var mainProductsWithIndex = [];
  var existingGiftsWithIndex = [];
  var editProductsWithIndex = [];
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    var giftInfo = getGiftInfo(item);
    if (isPersistedGeneratedVoucher(item)) {
      editProductsWithIndex.push({
        item: item,
        originalListIndex: i
      });
    } else if (giftInfo) {
      existingGiftsWithIndex.push({
        item: item,
        originalListIndex: i
      });
    } else if ((item === null || item === void 0 ? void 0 : item.booking_id) !== undefined && (item === null || item === void 0 ? void 0 : item.booking_id) !== null && item.booking_id !== 0 && item.booking_id !== '0') {
      editProductsWithIndex.push({
        item: item,
        originalListIndex: i
      });
    } else {
      mainProductsWithIndex.push({
        item: item,
        originalListIndex: i
      });
    }
  }
  var consolidatedMainProductsWithIndex = consolidateMainProductsForPromotion(mainProductsWithIndex);
  var mainProducts = consolidatedMainProductsWithIndex.map(function (x) {
    return x.item;
  });
  var existingGifts = existingGiftsWithIndex.map(function (x) {
    return x.item;
  });
  if (mainProducts.length === 0) {
    var editProducts = editProductsWithIndex.map(function (x) {
      return x.item;
    });
    if (existingGifts.length > 0) {
      var toRemove = [];
      var _iterator16 = _createForOfIteratorHelper(existingGifts),
        _step16;
      try {
        for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
          var gift = _step16.value;
          var uid = getOrderProductUid(gift);
          if (uid) toRemove.push(uid);
        }
      } catch (err) {
        _iterator16.e(err);
      } finally {
        _iterator16.f();
      }
      return {
        products: editProducts,
        totalDiscount: 0,
        gifts: [],
        giftActions: {
          toAdd: [],
          toReduce: [],
          toRemove: toRemove
        },
        unfulfilledPromotions: []
      };
    }
    return _objectSpread(_objectSpread({}, empty), {}, {
      products: editProducts.length > 0 ? editProducts : _toConsumableArray(list)
    });
  }

  // 1. 转 PromotionProduct
  var promotionProducts = [];
  var originalItemMap = new Map();
  var productsForStrategies = consolidatedMainProductsWithIndex.map(function (_ref16, i) {
    var _item$product_id, _item$product_variant5, _item$metadata2, _item$num;
    var item = _ref16.item;
    return {
      id: i,
      product_id: Number((_item$product_id = item === null || item === void 0 ? void 0 : item.product_id) !== null && _item$product_id !== void 0 ? _item$product_id : 0) || 0,
      product_variant_id: Number((_item$product_variant5 = item === null || item === void 0 ? void 0 : item.product_variant_id) !== null && _item$product_variant5 !== void 0 ? _item$product_variant5 : 0) || 0,
      name: (item === null || item === void 0 || (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.product_name) || (item === null || item === void 0 ? void 0 : item.title) || '',
      price: getOrderProductBasePrice(item),
      quantity: Number((_item$num = item === null || item === void 0 ? void 0 : item.num) !== null && _item$num !== void 0 ? _item$num : 1) || 1,
      bundle: getProductBundleForEvaluator(item)
    };
  });
  for (var _i = 0; _i < consolidatedMainProductsWithIndex.length; _i++) {
    var _consolidatedMainProd = consolidatedMainProductsWithIndex[_i],
      _item = _consolidatedMainProd.item,
      originalListIndex = _consolidatedMainProd.originalListIndex;
    var promotionProduct = convertToPromotionProduct(_item, originalListIndex);
    promotionProducts.push(promotionProduct);
    originalItemMap.set(promotionProduct.id, {
      item: _item,
      index: originalListIndex
    });
  }

  // 2. 拿适用策略
  var applicableStrategiesResult = evaluator.getProductsApplicableStrategies({
    products: productsForStrategies,
    channel: options === null || options === void 0 ? void 0 : options.channel
  });
  var strategyActionMap = new Map();
  var _iterator17 = _createForOfIteratorHelper(applicableStrategiesResult || []),
    _step17;
  try {
    for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
      var row = _step17.value;
      var _iterator22 = _createForOfIteratorHelper((row === null || row === void 0 ? void 0 : row.applicableStrategies) || []),
        _step22;
      try {
        for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
          var strategy = _step22.value;
          if (!(strategy !== null && strategy !== void 0 && strategy.strategyId)) continue;
          strategyActionMap.set(strategy.strategyId, {
            actionType: strategy.actionType,
            actionDetail: strategy.actionDetail
          });
        }
      } catch (err) {
        _iterator22.e(err);
      } finally {
        _iterator22.f();
      }
    }

    // 3. 评估器
  } catch (err) {
    _iterator17.e(err);
  } finally {
    _iterator17.f();
  }
  var result = evaluator.evaluateCartWithPricing({
    products: promotionProducts,
    channel: options === null || options === void 0 ? void 0 : options.channel
  });

  // 4. 收集每个策略的 sourceProductIds（参与策略的主商品 uid）
  var strategySourceProductIds = new Map();
  var _iterator18 = _createForOfIteratorHelper(result.products),
    _step18;
  try {
    for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
      var priced = _step18.value;
      if (priced.inPromotion && priced.strategyId) {
        var _priced$originalId;
        var sourceId = (_priced$originalId = priced.originalId) !== null && _priced$originalId !== void 0 ? _priced$originalId : priced.id;
        var originalData = originalItemMap.get(sourceId);
        if (originalData) {
          var _uid = getOrderProductUid(originalData.item);
          if (!_uid) continue;
          var arr = strategySourceProductIds.get(priced.strategyId) || [];
          if (!arr.includes(_uid)) arr.push(_uid);
          strategySourceProductIds.set(priced.strategyId, arr);
        }
      }
    }

    // 5. 扩展 gifts，加 sourceProductIds
  } catch (err) {
    _iterator18.e(err);
  } finally {
    _iterator18.f();
  }
  var extendedGifts = result.gifts.map(function (gift) {
    return _objectSpread(_objectSpread({}, gift), {}, {
      sourceProductIds: strategySourceProductIds.get(gift.strategyId) || []
    });
  });

  // 6. PricedProduct → OrderProduct（含拆分与价格调整）
  var strategyGiftInfoMap = new Map();
  var _iterator19 = _createForOfIteratorHelper(extendedGifts),
    _step19;
  try {
    for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
      var _gift = _step19.value;
      strategyGiftInfoMap.set(_gift.strategyId, _gift);
    }
  } catch (err) {
    _iterator19.e(err);
  } finally {
    _iterator19.f();
  }
  var strategyGiftInfoOwner = new Map();
  var processedProducts = [];
  var _iterator20 = _createForOfIteratorHelper(result.products),
    _step20;
  try {
    for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
      var _priced$originalId2, _priced$product_id, _originalItem$product, _metadata$_promotion2;
      var _priced = _step20.value;
      var rawSourceId = (_priced$originalId2 = _priced.originalId) !== null && _priced$originalId2 !== void 0 ? _priced$originalId2 : _priced.id;
      var _sourceId = Number(rawSourceId);
      var _originalData = Number.isFinite(_sourceId) ? originalItemMap.get(_sourceId) : undefined;
      if (!_originalData) continue;
      var originalItem = _originalData.item,
        originalIndex = _originalData.index;
      var pricedProductId = Number((_priced$product_id = _priced.product_id) !== null && _priced$product_id !== void 0 ? _priced$product_id : 0);
      var originalProductId = Number((_originalItem$product = originalItem.product_id) !== null && _originalItem$product !== void 0 ? _originalItem$product : 0);
      if (pricedProductId > 0 && originalProductId > 0 && pricedProductId !== originalProductId) {
        continue;
      }
      var newItem = cloneDeep(originalItem);
      var metadata = newItem.metadata || {};
      var sourceCartNum = getSafeProductNum(originalItem.num);
      newItem._sourceCartNum = sourceCartNum;

      // 清掉历史促销字段
      var wasInPromotion = ((_metadata$_promotion2 = metadata._promotion) === null || _metadata$_promotion2 === void 0 ? void 0 : _metadata$_promotion2.inPromotion) === true;
      delete metadata._promotion;
      if (Array.isArray(newItem.product_bundle)) {
        var _iterator23 = _createForOfIteratorHelper(newItem.product_bundle),
          _step23;
        try {
          for (_iterator23.s(); !(_step23 = _iterator23.n()).done;) {
            var b = _step23.value;
            if (b && _typeof(b) === 'object') delete b._promotion;
          }
        } catch (err) {
          _iterator23.e(err);
        } finally {
          _iterator23.f();
        }
      }
      var originalBasePrice = getOrderProductOriginalPriceForPromotion(originalItem);
      var shouldModifyPrice = _priced.inPromotion || wasInPromotion;
      var priceUnchangedPromo = _priced.inPromotion && Number(_priced.finalPrice) === Number(originalBasePrice);
      if (shouldModifyPrice) {
        if (_priced.inPromotion && !priceUnchangedPromo) {
          var _priced$strategyMetad;
          var promoUnitPrice = new Decimal(_priced.finalPrice).toDecimalPlaces(2).toFixed(2);
          applyPromoUnitPriceToLine(newItem, {
            promoUnitPrice: promoUnitPrice,
            originalBasePrice: originalBasePrice,
            strategyTitle: (_priced$strategyMetad = _priced.strategyMetadata) === null || _priced$strategyMetad === void 0 ? void 0 : _priced$strategyMetad.name
          });
        } else {
          // 撤销上一轮促销：还原 selling_price 到 main_product_original_price 派生值
          var optionSum = sumOptionUnitPrice(getProductSkuOptions(newItem)).toNumber();
          var sourceRestore = new Decimal(originalBasePrice).toDecimalPlaces(2).toFixed(2);
          var mainRestore = new Decimal(Number(sourceRestore) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
          metadata.source_product_price = sourceRestore;
          metadata.main_product_selling_price = mainRestore;
          metadata.price_schema_version = 2;
          newItem.selling_price = composeLinePrice({
            mainPrice: mainRestore,
            bundle: newItem.product_bundle
          });
          updatePromotionDiscountList(newItem, null);
        }
      }
      newItem.num = _priced.isSplit ? getSafeProductNum(_priced.quantity) : sourceCartNum;

      // 拆分行：生成新 uid，复制原行
      if (_priced.isSplit) {
        metadata.unique_identification_number = createUuidV4();
      }
      if (_priced.strategyId) {
        var actionMeta = strategyActionMap.get(_priced.strategyId);
        var promotionInfo = {
          strategyId: _priced.strategyId,
          strategyMetadata: _priced.strategyMetadata,
          inPromotion: _priced.inPromotion,
          originalPrice: originalBasePrice,
          finalPrice: _priced.finalPrice,
          actionType: actionMeta === null || actionMeta === void 0 ? void 0 : actionMeta.actionType,
          actionDetail: actionMeta === null || actionMeta === void 0 ? void 0 : actionMeta.actionDetail
        };
        var bundleIdx = _priced.matchedBundleIndex;
        if (bundleIdx !== undefined && Array.isArray(newItem.product_bundle) && newItem.product_bundle[bundleIdx]) {
          newItem.product_bundle[bundleIdx]._promotion = promotionInfo;
        } else {
          metadata._promotion = promotionInfo;
        }
      }
      newItem.metadata = metadata;

      // 5.1 第一个参与「买X送Y」策略的主商品，挂 giftInfo
      if (_priced.inPromotion && _priced.strategyId) {
        var _gift2 = strategyGiftInfoMap.get(_priced.strategyId);
        if (_gift2 && Array.isArray(_gift2.giftOptions) && _gift2.giftOptions.length > 0 && !strategyGiftInfoOwner.has(_priced.strategyId)) {
          var _newItem$product_bund;
          var giftInfoData = {
            strategyName: _gift2.strategyName,
            giftCount: _gift2.giftCount,
            giftOptions: _gift2.giftOptions
          };
          var _bundleIdx = _priced.matchedBundleIndex;
          if (_bundleIdx !== undefined && Array.isArray(newItem.product_bundle) && (_newItem$product_bund = newItem.product_bundle[_bundleIdx]) !== null && _newItem$product_bund !== void 0 && _newItem$product_bund._promotion) {
            newItem.product_bundle[_bundleIdx]._promotion.giftInfo = giftInfoData;
          } else if (metadata._promotion) {
            metadata._promotion.giftInfo = giftInfoData;
          }
          strategyGiftInfoOwner.set(_priced.strategyId, getOrderProductUid(newItem));
        }
      }

      // 记录原商品 uid（用于排序与未满足匹配）
      newItem._sortIndex = originalIndex;
      newItem._sortSubIndex = _priced.inPromotion ? 0 : 1;
      newItem._originalProductUid = getOrderProductUid(originalItem);
      processedProducts.push(newItem);
    }

    // 7. 赠品/编辑商品原样拼回；同时同步赠品的 sourceProductIds / sourceProductId
  } catch (err) {
    _iterator20.e(err);
  } finally {
    _iterator20.f();
  }
  for (var _i2 = 0, _existingGiftsWithInd = existingGiftsWithIndex; _i2 < _existingGiftsWithInd.length; _i2++) {
    var _getGiftInfo3;
    var _existingGiftsWithInd2 = _existingGiftsWithInd[_i2],
      _item2 = _existingGiftsWithInd2.item,
      _originalListIndex = _existingGiftsWithInd2.originalListIndex;
    var next = _item2;
    next._sortIndex = _originalListIndex;
    next._sortSubIndex = 0;
    var strategyId = (_getGiftInfo3 = getGiftInfo(next)) === null || _getGiftInfo3 === void 0 ? void 0 : _getGiftInfo3.strategyId;
    if (strategyId) {
      var _next$metadata, _next$metadata2;
      var latest = strategyGiftInfoMap.get(strategyId);
      var owner = strategyGiftInfoOwner.get(strategyId);
      if (latest && (_next$metadata = next.metadata) !== null && _next$metadata !== void 0 && _next$metadata._giftInfo) {
        next.metadata._giftInfo.sourceProductIds = latest.sourceProductIds;
      }
      if (owner && (_next$metadata2 = next.metadata) !== null && _next$metadata2 !== void 0 && _next$metadata2._giftInfo) {
        next.metadata._giftInfo.sourceProductId = owner;
      }
    }
    processedProducts.push(next);
  }
  for (var _i3 = 0, _editProductsWithInde = editProductsWithIndex; _i3 < _editProductsWithInde.length; _i3++) {
    var _editProductsWithInde2 = _editProductsWithInde[_i3],
      _item3 = _editProductsWithInde2.item,
      _originalListIndex2 = _editProductsWithInde2.originalListIndex;
    var _next = _item3;
    _next._sortIndex = _originalListIndex2;
    _next._sortSubIndex = 0;
    processedProducts.push(_next);
  }

  // 8. 排序回原顺序，参与促销的拆分行排在前
  processedProducts.sort(function (a, b) {
    if (a._sortIndex !== b._sortIndex) return a._sortIndex - b._sortIndex;
    return a._sortSubIndex - b._sortSubIndex;
  });

  // 8.1 同款参与促销行：先去重（买赠+满减并存）再合并 num
  var dedupedPromotionLines = dedupePromotionProcessedLines(processedProducts);
  processedProducts.splice.apply(processedProducts, [0, processedProducts.length].concat(_toConsumableArray(dedupedPromotionLines)));
  var mergedPromotionLines = mergeIdenticalPromotionCartLines(processedProducts);
  processedProducts.splice.apply(processedProducts, [0, processedProducts.length].concat(_toConsumableArray(mergedPromotionLines)));
  var splitPromoLines = splitXItemsPromoLinesByGroup(processedProducts, strategyActionMap);
  processedProducts.splice.apply(processedProducts, [0, processedProducts.length].concat(_toConsumableArray(splitPromoLines)));

  // 9. 给「有适用策略但未参与促销」的主商品打 inPromotion:false
  var _loop3 = function _loop3() {
      var _product$_originalPro2;
      var product = _processedProducts[_i4];
      var metadata = product.metadata || {};
      if (metadata._promotion) return 0; // continue
      if (getGiftInfo(product)) return 0; // continue
      var lookupUid = String((_product$_originalPro2 = product._originalProductUid) !== null && _product$_originalPro2 !== void 0 ? _product$_originalPro2 : getOrderProductUid(product));
      var originalIndex = mainProducts.findIndex(function (item) {
        return getOrderProductUid(item) === lookupUid;
      });
      if (originalIndex === -1) return 0; // continue
      var strategyData = applicableStrategiesResult[originalIndex];
      if (!strategyData || !strategyData.hasApplicableStrategy) return 0; // continue
      var first = strategyData.applicableStrategies[0];
      if (!first) return 0; // continue
      var originalPrice = getOrderProductOriginalPriceForPromotion(mainProducts[originalIndex]);
      metadata._promotion = {
        strategyId: first.strategyId,
        strategyMetadata: first.strategyMetadata,
        inPromotion: false,
        originalPrice: originalPrice,
        finalPrice: originalPrice
      };
      product.metadata = metadata;
    },
    _ret2;
  for (var _i4 = 0, _processedProducts = processedProducts; _i4 < _processedProducts.length; _i4++) {
    _ret2 = _loop3();
    if (_ret2 === 0) continue;
  }

  // 10. 赠品操作（在更新 lastEvaluatedGiftCount 前做对比）
  var giftActions = calculateGiftActions(extendedGifts, existingGifts);

  // 10.1 更新 lastEvaluatedGiftCount，便于下次评估时判别「策略已变」
  var _iterator21 = _createForOfIteratorHelper(existingGifts),
    _step21;
  try {
    for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
      var _getGiftInfo4, _metadata;
      var _gift3 = _step21.value;
      var _strategyId3 = (_getGiftInfo4 = getGiftInfo(_gift3)) === null || _getGiftInfo4 === void 0 ? void 0 : _getGiftInfo4.strategyId;
      if (!_strategyId3) continue;
      var _latest = strategyGiftInfoMap.get(_strategyId3);
      if (_latest && (_metadata = _gift3.metadata) !== null && _metadata !== void 0 && _metadata._giftInfo) {
        _gift3.metadata._giftInfo.lastEvaluatedGiftCount = _latest.giftCount;
      }
    }

    // 11. 未满足促销
  } catch (err) {
    _iterator21.e(err);
  } finally {
    _iterator21.f();
  }
  var unfulfilledPromotions = calculateUnfulfilledPromotions(processedProducts, applicableStrategiesResult, mainProducts);

  // 12. 清理排序辅助字段
  for (var _i5 = 0, _processedProducts2 = processedProducts; _i5 < _processedProducts2.length; _i5++) {
    var product = _processedProducts2[_i5];
    delete product._sortIndex;
    delete product._sortSubIndex;
    delete product._originalProductUid;
    delete product._sourceCartNum;
  }
  return {
    products: processedProducts,
    totalDiscount: result.totalDiscount,
    gifts: extendedGifts,
    giftActions: giftActions,
    unfulfilledPromotions: unfulfilledPromotions
  };
}