var _excluded = ["unique_identification_number"],
  _excluded2 = ["num", "surcharge_fee", "discount_amount", "discount_type", "discountway", "product_discount_reason", "discount_per"],
  _excluded3 = ["_extend", "relation_id", "table_form_id", "resource_id", "summary", "lastOrderInfo", "paid_amount", "shop_id", "shop_note", "shop_service_type", "start_time", "customer", "discount_list", "tax_fee", "total_amount", "total_refund_amount", "create_date", "holder_id"],
  _excluded4 = ["collect_pax", "table_occupancy_duration"];
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 _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 _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 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 _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; }
import dayjs from "dayjs";
import Decimal from 'decimal.js';
import { buildProductLineFingerprint, createEmptySummary } from "../../solution/ScanOrder/utils";
/**
 * 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
 *
 * 新语义 v2 约定：
 * - `mainPrice` 必须是**已经包含 option 的主商品单价**（即 `metadata.main_product_selling_price`
 *   或 `metadata.main_product_original_price`），option 价格不由本函数叠加。
 * - 套餐价：Σ((bundle.bundle_selling_price ?? bundle.price) × (bundle.num ?? bundle.quantity ?? 1))
 *   当 `useOriginalBundle=true` 时，改用 `bundle.original_price ?? bundle.product_price ?? bundle.price`。
 * - 返回值：保留 2 位小数的字符串，方便直接写回 `selling_price` / `original_price` 字段。
 *
 * 被 `normalizeOrderProduct`、Rules setProduct 钩子、各 Solution 的 setDiscountSelected 共用，
 * 保证合成逻辑单点来源。
 */
export function composeLinePrice(params) {
  var mainPrice = params.mainPrice,
    bundle = params.bundle,
    useOriginalBundle = params.useOriginalBundle;
  var total = new Decimal(Number(mainPrice) || 0);
  if (Array.isArray(bundle)) {
    var _iterator = _createForOfIteratorHelper(bundle),
      _step;
    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var _ref, _item$num;
        var item = _step.value;
        // markdown（减价）按带符号净额取减；markup/原价维持相加。
        var signedUnit = getBundleSignedUnit(item, {
          useOriginal: useOriginalBundle
        });
        var rawNum = (_ref = (_item$num = item === null || item === void 0 ? void 0 : item.num) !== null && _item$num !== void 0 ? _item$num : item === null || item === void 0 ? void 0 : item.quantity) !== null && _ref !== void 0 ? _ref : 1;
        var num = new Decimal(Number(rawNum) || 0);
        total = total.plus(signedUnit.times(num));
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
  }
  return total.toDecimalPlaces(2).toFixed(2);
}
export function normalizeProductSkuOptions(options) {
  if (!Array.isArray(options)) return [];
  return options.map(function (option) {
    var _normalized$add_price;
    var normalized = _objectSpread({}, option && _typeof(option) === 'object' ? option : {});
    var addPrice = (_normalized$add_price = normalized.add_price) !== null && _normalized$add_price !== void 0 ? _normalized$add_price : normalized.price;
    if (addPrice !== undefined) normalized.add_price = addPrice;
    delete normalized.price;
    return normalized;
  });
}
export function ensureProductSku(product) {
  var rawSku = product !== null && product !== void 0 && product.product_sku && _typeof(product.product_sku) === 'object' ? product.product_sku : {};
  return _objectSpread(_objectSpread({}, rawSku), {}, {
    option: normalizeProductSkuOptions(rawSku.option)
  });
}
export function getProductSkuOptions(product) {
  return ensureProductSku(product).option;
}

/**
 * 计算 option 单价合计：Σ(option.add_price × option.num)。
 * 兼容入参仍带旧 `price` 的调用方，但运行时归一化后只维护 `add_price`。
 * 在新语义 v2 下，main_product_original_price = source_product_price + 本函数结果。
 */
export function sumOptionUnitPrice(options) {
  var total = new Decimal(0);
  if (!Array.isArray(options)) return total;
  var _iterator2 = _createForOfIteratorHelper(options),
    _step2;
  try {
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      var _opt$add_price;
      var opt = _step2.value;
      var price = new Decimal(Number((_opt$add_price = opt === null || opt === void 0 ? void 0 : opt.add_price) !== null && _opt$add_price !== void 0 ? _opt$add_price : opt === null || opt === void 0 ? void 0 : opt.price) || 0);
      var num = new Decimal(Number(opt === null || opt === void 0 ? void 0 : opt.num) || 0);
      total = total.plus(price.times(num));
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  return total;
}

/**
 * 判定套餐子商品是否为 markdown（减价）类型。
 * 与后端口径一致：price_type='markdown' 且 price_type_ext 非 'product_price'（原价子商品）。
 */
export function isMarkdownBundle(bundle) {
  var _bundle$price_type_ex, _bundle$price_type;
  if (!bundle || _typeof(bundle) !== 'object') return false;
  var ext = (_bundle$price_type_ex = bundle.price_type_ext) !== null && _bundle$price_type_ex !== void 0 ? _bundle$price_type_ex : bundle.custom_price_type_ext;
  var type = (_bundle$price_type = bundle.price_type) !== null && _bundle$price_type !== void 0 ? _bundle$price_type : bundle.custom_price_type;
  return type === 'markdown' && ext !== 'product_price';
}

/**
 * 套餐子商品对「行价」的带符号单位贡献（与后端 markdown 口径对齐）。
 *
 * - markdown（减价）：净额 = |catalog 毛价| − Σ(option.add_price×num)，**取负**（行内减）。
 *   catalog 毛价优先 `price`/`custom_price`（避免读已落净额的 `bundle_selling_price` 造成 option 二次扣减）；
 *   仅当毛价缺失（历史/hydrate 仅剩净额）时退回 `bundle_selling_price`，且此时不再扣 option。
 * - markup（加价）/原价子商品：维持 `+(bundle_selling_price ?? price)`，行为不变。
 */
export function getBundleSignedUnit(bundle, options) {
  var _options$useOriginal, _ref8, _bundle$original_pric2, _bundle$bundle_sellin;
  if (!bundle || _typeof(bundle) !== 'object') return new Decimal(0);
  var useOriginal = (_options$useOriginal = options === null || options === void 0 ? void 0 : options.useOriginal) !== null && _options$useOriginal !== void 0 ? _options$useOriginal : false;
  if (isMarkdownBundle(bundle)) {
    var _ref2, _ref3, _ref4, _bundle$original_pric, _ref5, _ref6, _ref7, _bundle$custom_price;
    var catalog = useOriginal ? (_ref2 = (_ref3 = (_ref4 = (_bundle$original_pric = bundle.original_price) !== null && _bundle$original_pric !== void 0 ? _bundle$original_pric : bundle.product_price) !== null && _ref4 !== void 0 ? _ref4 : bundle.custom_price) !== null && _ref3 !== void 0 ? _ref3 : bundle.base_price) !== null && _ref2 !== void 0 ? _ref2 : bundle.price : (_ref5 = (_ref6 = (_ref7 = (_bundle$custom_price = bundle.custom_price) !== null && _bundle$custom_price !== void 0 ? _bundle$custom_price : bundle.product_price) !== null && _ref7 !== void 0 ? _ref7 : bundle.original_price) !== null && _ref6 !== void 0 ? _ref6 : bundle.base_price) !== null && _ref5 !== void 0 ? _ref5 : bundle.price;
    if (catalog !== undefined && catalog !== null && catalog !== '') {
      var raw = new Decimal(Number(catalog) || 0);
      // 负值表示价格已是「带符号净额」（如 cart/changePrice 产出的 -3.7），直接取用不再扣 option，
      // 避免与下游 option 二次扣减；正值为毛价（H5 路径，如 5），净额 = price − Σoptions 后取负。
      if (raw.lt(0)) return raw;
      return raw.minus(sumOptionUnitPrice(bundle.option)).negated();
    }
    // 仅剩净额（无毛价）兜底：直接取负，不再扣 option
    return new Decimal(Number(bundle.bundle_selling_price) || 0).abs().negated();
  }
  var rawPrice = useOriginal ? (_ref8 = (_bundle$original_pric2 = bundle.original_price) !== null && _bundle$original_pric2 !== void 0 ? _bundle$original_pric2 : bundle.product_price) !== null && _ref8 !== void 0 ? _ref8 : bundle.price : (_bundle$bundle_sellin = bundle.bundle_selling_price) !== null && _bundle$bundle_sellin !== void 0 ? _bundle$bundle_sellin : bundle.price;
  return new Decimal(Number(rawPrice) || 0);
}

/**
 * 套餐子商品 `bundle_selling_price` 的存储净额（正值幅度）。
 * markdown 取净额绝对值（3.70）；markup/原价维持原值。
 */
export function getBundleSellingMagnitude(bundle) {
  return getBundleSignedUnit(bundle).abs();
}

/**
 * OrderModule 默认 Rules 钩子工厂。
 *
 * 价格语义约定（订单域，v2 composite 口径）：
 * - `selling_price`：券后 **行 composite 单价**
 *   = `metadata.main_product_selling_price` + Σ(bundle_selling_price × num)。
 * - `original_price`：券前 **行 composite 单价**
 *   = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
 * - `metadata.source_product_price`：主商品/variant 基础价（已应用报价单），不含 option、
 *   不含折扣。**权威源**。
 * - `metadata.main_product_original_price` = source + Σ(option.price × option.num)（含 option、不含折扣）。
 * - `metadata.main_product_selling_price` = main_original − 主商品券 per-unit amount（含 option、含折扣）。
 * - `payment_price`：出站 payload 中为行 composite 已减整单折扣均摊价（无折扣时与 `selling_price` 同义）。
 *
 * Rules 钩子契约（hook_adapt 方案，Rules 内部保持不变）：
 * - `getProduct.price` / `getProduct.original_price` 回传 **source-level 主价**
 *   （`metadata.source_product_price`）。Rules 内部 `getProductTotalPrice` /
 *   `getProductOriginTotalPrice` 会自行叠加 option + bundle，喂 source 可避免 option 双加。
 * - `getProduct.total` = `selling_price × num`（行 composite × num），与 Rules 内部产出的
 *   total（source + option + bundle）对齐。
 * - `setProduct` 反向流程：把 Rules 返回的 source-level `main_product_selling_price` / `price`
 *   加回 Σoptions，重新合成含 option 的 main_product_* 并派生 composite。
 *   优先级：
 *     1. `values.main_product_selling_price`（券应用分支，per-unit 券后 source-level 主价）
 *     2. `values.price`（还原分支 `restoredPrice`、good_pass 归零）
 *     3. `values.total / num`（仅当 Rules 只给出总价时的兜底）
 *
 * 导出为纯函数方便单测直接驱动钩子，不依赖 OrderModule 实例。
 */

/** Rules calcDiscount 用手动价标记；undefined 表示交给 Rules 用 total/origin_total 推断 */
export function resolveRulesManualDiscountFlag(metadata) {
  if (!metadata) return undefined;
  if (metadata.is_manual_discount === true || metadata.is_manual_discount === 1) {
    return true;
  }
  var priceOverride = metadata.price_override;
  if (priceOverride !== undefined && priceOverride !== null && priceOverride !== '') {
    return true;
  }
  return undefined;
}
function normalizeOrderProductDiscountAmount(amount) {
  if (amount === undefined || amount === null) return undefined;
  return String(amount);
}

/**
 * 商品行折扣只保留后端 OrderProductDiscountItem 协议字段。
 * Rules/券计算过程中的 `_num`、`config` 等运行态字段不应进入 tempOrder 或提交 payload。
 */
export function normalizeOrderProductDiscountList(discountList) {
  if (!Array.isArray(discountList)) return [];
  return discountList.filter(function (item) {
    return !!item && _typeof(item) === 'object';
  }).map(function (item) {
    var normalized = {
      discount_id: Number.isFinite(Number(item.discount_id)) ? Number(item.discount_id) : 0
    };
    if (item.order_discount_id === null) {
      normalized.order_discount_id = null;
    } else if (item.order_discount_id !== undefined) {
      var orderDiscountId = Number(item.order_discount_id);
      if (Number.isFinite(orderDiscountId)) {
        normalized.order_discount_id = orderDiscountId;
      }
    }
    if (item.type !== undefined) normalized.type = item.type;
    var amount = normalizeOrderProductDiscountAmount(item.amount);
    if (amount !== undefined) normalized.amount = amount;
    if (item.discount && _typeof(item.discount) === 'object') {
      normalized.discount = _objectSpread({}, item.discount);
    }
    if (item.metadata === null) {
      normalized.metadata = null;
    } else if (item.metadata && _typeof(item.metadata) === 'object') {
      normalized.metadata = _objectSpread({}, item.metadata);
    }
    return normalized;
  });
}

/**
 * 手动改价（price_override）时行级 original_price（composite 单价）：
 * 购物车划线价应对齐 metadata.origin._extend.origin_total（改价前单价 composite，如 40），
 * 而非 bundle 子项 catalog 原价合成的 composedOriginalPrice（如 30）。
 *
 * origin_total 与 SkuDetailModal / cacheItem._extend 一致，为单价语义，不再除以 num。
 */
export function resolveManualOverrideLineOriginalPrice(params, fallbackCompositeOriginal) {
  var _metadata$origin;
  var metadata = params.metadata || {};
  var priceOverride = metadata.price_override;
  if (priceOverride === undefined || priceOverride === null || priceOverride === '') {
    return fallbackCompositeOriginal;
  }
  var refTotal = (_metadata$origin = metadata.origin) === null || _metadata$origin === void 0 || (_metadata$origin = _metadata$origin._extend) === null || _metadata$origin === void 0 ? void 0 : _metadata$origin.origin_total;
  if (refTotal !== undefined && refTotal !== null && refTotal !== '') {
    var parsed = Number(refTotal);
    if (Number.isFinite(parsed)) {
      return new Decimal(parsed).toDecimalPlaces(2).toFixed(2);
    }
  }
  var lineOriginal = params.lineOriginalPrice;
  if (lineOriginal !== undefined && lineOriginal !== null && lineOriginal !== '') {
    var parsedLine = Number(lineOriginal);
    var parsedFallback = Number(fallbackCompositeOriginal);
    if (Number.isFinite(parsedLine) && Number.isFinite(parsedFallback) && parsedLine > parsedFallback) {
      return new Decimal(parsedLine).toDecimalPlaces(2).toFixed(2);
    }
  }
  return fallbackCompositeOriginal;
}

/**
 * 计算商品行「每单位有效折扣」：discount_list 合计 + 被 Rules 剥离但仍 inPromotion 的差额。
 *
 * Rules.calcDiscount 会把 type=promotion 从 discount_list 去掉，但 metadata._promotion 仍保留；
 * applyProductDiscountPrices 必须回读 _promotion，否则抬价/降价都会在第二步被 source 原价覆盖。
 *
 * @example
 * resolveEffectivePerUnitDiscount({ metadata: { _promotion: { inPromotion: true, originalPrice: 1, finalPrice: 5 } }, discount_list: [] });
 * // => -4
 */
export function resolveEffectivePerUnitDiscount(product) {
  var discountList = Array.isArray(product === null || product === void 0 ? void 0 : product.discount_list) ? product.discount_list : [];
  var fromList = discountList.reduce(function (sum, discount) {
    return sum + Number((discount === null || discount === void 0 ? void 0 : discount.amount) || 0);
  }, 0);
  var hasPromoDiscountItem = discountList.some(function (item) {
    return (item === null || item === void 0 ? void 0 : item.type) === 'promotion';
  });
  if (hasPromoDiscountItem) return fromList;
  var metadata = (product === null || product === void 0 ? void 0 : product.metadata) || {};
  var promo = metadata._promotion;
  if ((promo === null || promo === void 0 ? void 0 : promo.inPromotion) !== true) return fromList;
  var optionSum = sumOptionUnitPrice(getProductSkuOptions(product)).toNumber();

  // applyPromotion 写价后、Rules 剥离 promotion discount 的兜底
  if (!discountList.length && metadata.source_product_price != null && metadata.main_product_selling_price != null) {
    var source = Number(metadata.source_product_price);
    var selling = Number(metadata.main_product_selling_price) - optionSum;
    if (Number.isFinite(source) && Number.isFinite(selling) && source !== selling) {
      return fromList + (source - selling);
    }
  }
  var originalPrice = Number(promo.originalPrice);
  var finalPrice = Number(promo.finalPrice);
  if (!Number.isFinite(originalPrice) || !Number.isFinite(finalPrice)) return fromList;
  return fromList + (originalPrice - finalPrice);
}
export function createDefaultOrderRulesHooks() {
  var toUnitPriceString = function toUnitPriceString(totalLike, num) {
    var effectiveNum = Number(num) > 0 ? Number(num) : 1;
    return new Decimal(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
  };
  var getBundleIdentity = function getBundleIdentity(bundle) {
    var _ref9, _bundle$bundle_id, _ref10, _ref11, _bundle$bundle_produc, _ref12, _ref13, _bundle$bundle_varian, _ref14, _bundle$bundle_group_;
    return [(_ref9 = (_bundle$bundle_id = bundle.bundle_id) !== null && _bundle$bundle_id !== void 0 ? _bundle$bundle_id : bundle.id) !== null && _ref9 !== void 0 ? _ref9 : '', (_ref10 = (_ref11 = (_bundle$bundle_produc = bundle.bundle_product_id) !== null && _bundle$bundle_produc !== void 0 ? _bundle$bundle_produc : bundle._bundle_product_id) !== null && _ref11 !== void 0 ? _ref11 : bundle.product_id) !== null && _ref10 !== void 0 ? _ref10 : '', (_ref12 = (_ref13 = (_bundle$bundle_varian = bundle.bundle_variant_id) !== null && _bundle$bundle_varian !== void 0 ? _bundle$bundle_varian : bundle.variant_id) !== null && _ref13 !== void 0 ? _ref13 : bundle.product_variant_id) !== null && _ref12 !== void 0 ? _ref12 : 0, (_ref14 = (_bundle$bundle_group_ = bundle.bundle_group_id) !== null && _bundle$bundle_group_ !== void 0 ? _bundle$bundle_group_ : bundle.group_id) !== null && _ref14 !== void 0 ? _ref14 : ''].join('|');
  };
  var mergeRulesBundlePrices = function mergeRulesBundlePrices(currentBundle, rulesBundle) {
    if (!Array.isArray(rulesBundle)) return rulesBundle;
    var currentByIdentity = new Map();
    (currentBundle || []).forEach(function (bundle) {
      if (!bundle || _typeof(bundle) !== 'object') return;
      currentByIdentity.set(getBundleIdentity(bundle), bundle);
    });
    return rulesBundle.map(function (bundle) {
      var _bundle$price_type_ex2, _ref15, _ref16, _current$price, _ref17, _ref18, _ref19, _current$original_pri;
      if (!bundle || _typeof(bundle) !== 'object') return bundle;
      var current = currentByIdentity.get(getBundleIdentity(bundle));
      if (!current) return bundle;
      var isProductPriceBundle = ((_bundle$price_type_ex2 = bundle.price_type_ext) !== null && _bundle$price_type_ex2 !== void 0 ? _bundle$price_type_ex2 : current.price_type_ext) === 'product_price';
      if (!isProductPriceBundle) return bundle;
      var sourcePrice = (_ref15 = (_ref16 = (_current$price = current.price) !== null && _current$price !== void 0 ? _current$price : current.custom_price) !== null && _ref16 !== void 0 ? _ref16 : current.original_price) !== null && _ref15 !== void 0 ? _ref15 : current.bundle_selling_price;
      var originalPrice = (_ref17 = (_ref18 = (_ref19 = (_current$original_pri = current.original_price) !== null && _current$original_pri !== void 0 ? _current$original_pri : current.product_price) !== null && _ref19 !== void 0 ? _ref19 : current.price) !== null && _ref18 !== void 0 ? _ref18 : current.custom_price) !== null && _ref17 !== void 0 ? _ref17 : sourcePrice;
      return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, bundle), sourcePrice !== undefined ? {
        price: sourcePrice
      } : {}), originalPrice !== undefined ? {
        original_price: originalPrice
      } : {}), current.original_total !== undefined ? {
        original_total: current.original_total
      } : {});
    });
  };
  return {
    getProduct: function getProduct(product) {
      var _product$metadata, _product$metadata2, _product$metadata3, _product$metadata4, _product$metadata5, _metadataAny$_promoti;
      // source_product_price 是权威源；兜底链：source → mainSelling − options（反推）→ 行 selling_price
      var metadataAny = product.metadata || {};
      var optionSum = sumOptionUnitPrice(getProductSkuOptions(product));
      var sourcePrice;
      if (metadataAny.source_product_price !== undefined) {
        sourcePrice = String(metadataAny.source_product_price);
      } else if (metadataAny.main_product_selling_price !== undefined) {
        sourcePrice = new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(optionSum).toDecimalPlaces(2).toString();
      } else {
        var _product$selling_pric;
        sourcePrice = String((_product$selling_pric = product.selling_price) !== null && _product$selling_pric !== void 0 ? _product$selling_pric : 0);
      }
      var sourceOriginalPrice;
      if (metadataAny.source_product_price !== undefined) {
        sourceOriginalPrice = String(metadataAny.source_product_price);
      } else if (metadataAny.main_product_original_price !== undefined) {
        sourceOriginalPrice = new Decimal(Number(metadataAny.main_product_original_price) || 0).minus(optionSum).toDecimalPlaces(2).toString();
      } else {
        sourceOriginalPrice = sourcePrice;
      }
      return {
        id: product.product_id,
        // Rules 引擎用 _id 作为 processedProductsMap 键；必须与购物车行级 identity 一致，
        // 否则同 SKU 不同小料会在 calcDiscount 重组时互相覆盖。
        // 不透明 identity 契约下，normalizeOrderProduct / hydrate 已保证唯一值存在；
        // 留 fingerprint 分支仅作 Rules 单测里直接传裸 product 时的兜底。
        _id: (_product$metadata = product.metadata) !== null && _product$metadata !== void 0 && _product$metadata.unique_identification_number ? "".concat(product.product_id, "_").concat(product.product_variant_id, "_").concat(product.metadata.unique_identification_number) : "".concat(product.product_id, "_").concat(product.product_variant_id, "_").concat(buildProductLineFingerprint(getProductSkuOptions(product), product.product_bundle)),
        // Rules 内部 getProductTotalPrice / getProductOriginTotalPrice 会各自再叠加 bundle + option，
        // 所以这里必须喂 source-level（不含 option、不含 bundle、不含折扣）单价，避免双加 option。
        price: sourcePrice,
        // total / origin_total 使用 composite × num，跟 Rules 内部产出的 total 对齐（含 option + bundle）。
        total: new Decimal(product.selling_price || 0).times(product.num || 1).toNumber(),
        origin_total: new Decimal(product.original_price || product.selling_price || 0).times(product.num || 1).toNumber(),
        original_price: sourceOriginalPrice,
        quantity: product.num || 1,
        num: product.num || 1,
        discount_list: product.discount_list || [],
        bundle: product.product_bundle || [],
        booking_id: ((_product$metadata2 = product.metadata) === null || _product$metadata2 === void 0 ? void 0 : _product$metadata2.booking_id) || null,
        isClient: false,
        // 勿写死 false：否则 Rules 不会走 total≠origin_total 的手动价推断，
        // 无券时会把 bundle 价还原成 original_price（手动改价套餐会从 20 回到 30）。
        isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
        holder_id: (_product$metadata3 = product.metadata) === null || _product$metadata3 === void 0 ? void 0 : _product$metadata3.holder_id,
        startDate: ((_product$metadata4 = product.metadata) === null || _product$metadata4 === void 0 ? void 0 : _product$metadata4.start_date) || ((_product$metadata5 = product.metadata) === null || _product$metadata5 === void 0 ? void 0 : _product$metadata5.startDate),
        main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new Decimal(Number(metadataAny.main_product_selling_price) || 0).minus(optionSum).toDecimalPlaces(2).toString() : undefined,
        inPromotion: ((_metadataAny$_promoti = metadataAny._promotion) === null || _metadataAny$_promoti === void 0 ? void 0 : _metadataAny$_promoti.inPromotion) === true,
        _promotion: metadataAny._promotion
      };
    },
    setProduct: function setProduct(product, values) {
      var _ref20, _values$quantity, _ref21, _metadataAny$source_p, _values$discount_list, _values$quantity2;
      var nextNum = Number((_ref20 = (_values$quantity = values.quantity) !== null && _values$quantity !== void 0 ? _values$quantity : product.num) !== null && _ref20 !== void 0 ? _ref20 : 1) || 1;
      var metadataAny = product.metadata || {};
      var existedSource = (_ref21 = (_metadataAny$source_p = metadataAny.source_product_price) !== null && _metadataAny$source_p !== void 0 ? _metadataAny$source_p : product.selling_price) !== null && _ref21 !== void 0 ? _ref21 : '0';
      var nextOptions = getProductSkuOptions(product);
      var optionSum = sumOptionUnitPrice(nextOptions);

      // Rules 返回的 main_product_selling_price / price / total 均为 source-level。
      // 优先级：main_product_selling_price（per-unit 券后 source）> price（还原/good_pass 分支）>
      // total/num（仅当 Rules 只给 total 时的兜底）> 保留当前 source。
      var nextSourceSellingPrice = values.main_product_selling_price !== undefined ? String(values.main_product_selling_price) : values.price !== undefined ? String(values.price) : values.total !== undefined ? toUnitPriceString(values.total, nextNum) : String(existedSource);

      // 券前 source：values.original_price 是 source-level（Rules 层本就不含 option），
      // 缺省时保留现有 source（券前 = 当前 source）。
      var nextSourceOriginalPrice = values.original_price !== undefined ? String(values.original_price) : String(existedSource);

      // 含 option 的 main_product_*
      var nextMainSellingPrice = new Decimal(Number(nextSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
      var nextMainOriginalPrice = new Decimal(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
      var nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
      var composedSellingPrice = composeLinePrice({
        mainPrice: nextMainSellingPrice,
        bundle: nextBundle
      });
      var composedOriginalPrice = composeLinePrice({
        mainPrice: nextMainOriginalPrice,
        bundle: nextBundle,
        useOriginalBundle: true
      });
      var finalOriginalPrice = resolveManualOverrideLineOriginalPrice({
        num: nextNum,
        metadata: metadataAny,
        lineOriginalPrice: product.original_price
      }, composedOriginalPrice);
      return _objectSpread(_objectSpread({}, product), {}, {
        selling_price: composedSellingPrice,
        original_price: finalOriginalPrice,
        discount_list: (_values$discount_list = values.discount_list) !== null && _values$discount_list !== void 0 ? _values$discount_list : product.discount_list,
        num: (_values$quantity2 = values.quantity) !== null && _values$quantity2 !== void 0 ? _values$quantity2 : product.num,
        product_bundle: nextBundle,
        metadata: _objectSpread(_objectSpread({}, metadataAny), {}, {
          source_product_price: nextSourceOriginalPrice,
          main_product_selling_price: nextMainSellingPrice,
          main_product_original_price: nextMainOriginalPrice,
          price_schema_version: 2
        })
      });
    }
  };
}

/**
 * 通过 session 类商品的开始时间结束时间生成商品的时长
 * @param {CartItem} cartItem
 * @return {*}
 */
export var generateDuration = function generateDuration(cartItem) {
  var startDate = dayjs("".concat(cartItem.start_date, " ").concat(cartItem.start_time));
  var endDate = dayjs("".concat(cartItem.end_date, " ").concat(cartItem.end_time));
  var duration = endDate.diff(startDate, 'minutes');
  return {
    duration: duration,
    durationType: 'minutes'
  };
};

/**
 * 合并关联表单
 * @param relationForms 关联表单
 * @returns 合并后的关联表单
 */
export var mergeRelationForms = function mergeRelationForms(relationForms) {
  return Object.values(relationForms.reduce(function (acc, cur) {
    var _acc$form_id$form_rec;
    var form_id = cur.form_id,
      form_record_ids = cur.form_record_ids;
    // 如果 acc 中没有 form_id，则初始化一个空数组
    if (!acc[form_id]) {
      acc[form_id] = {
        form_id: form_id,
        form_record_ids: []
      };
    }

    // 兼容 form_record_id 可能是数组或单个数字
    var ids = Array.isArray(form_record_ids) ? form_record_ids : [form_record_ids];
    // 过滤掉空值（null、undefined等）
    var validIds = ids.filter(function (id) {
      return id != null;
    });
    (_acc$form_id$form_rec = acc[form_id].form_record_ids).push.apply(_acc$form_id$form_rec, _toConsumableArray(validIds));
    // 去重
    acc[form_id].form_record_ids = _toConsumableArray(new Set(acc[form_id].form_record_ids));
    return acc;
  }, {})).filter(function (item) {
    return item.form_record_ids.length > 0;
  }); // 过滤掉没有有效记录的表单
};
export var getAllDiscountList = function getAllDiscountList(cartItem) {
  var _cartItem$_origin, _cartItem$_origin2;
  var discountList = (cartItem === null || cartItem === void 0 || (_cartItem$_origin = cartItem._origin) === null || _cartItem$_origin === void 0 || (_cartItem$_origin = _cartItem$_origin.product) === null || _cartItem$_origin === void 0 ? void 0 : _cartItem$_origin.discount_list) || [];
  ((cartItem === null || cartItem === void 0 || (_cartItem$_origin2 = cartItem._origin) === null || _cartItem$_origin2 === void 0 || (_cartItem$_origin2 = _cartItem$_origin2.product) === null || _cartItem$_origin2 === void 0 ? void 0 : _cartItem$_origin2.product_bundle) || []).forEach(function (item) {
    discountList = [].concat(_toConsumableArray(discountList), _toConsumableArray((item === null || item === void 0 ? void 0 : item.discount_list) || []));
    item.discount_list = undefined;
  });
  return discountList;
};

// ─── 以下为从 ScanOrder/utils.ts 迁入的 Order 专属工具函数 ───

export function createUuidV4() {
  var template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
  return template.replace(/[xy]/g, function (char) {
    var randomValue = Math.floor(Math.random() * 16);
    var value = char === 'x' ? randomValue : randomValue & 0x3 | 0x8;
    return value.toString(16);
  });
}
export function isTempOrder(data) {
  if (!data || _typeof(data) !== 'object') return false;
  if (!Array.isArray(data.products)) return false;
  return true;
}
export function formatDateTime(date) {
  var pad = function pad(value) {
    return value.toString().padStart(2, '0');
  };
  var year = date.getFullYear();
  var month = pad(date.getMonth() + 1);
  var day = pad(date.getDate());
  var hours = pad(date.getHours());
  var minutes = pad(date.getMinutes());
  var seconds = pad(date.getSeconds());
  return "".concat(year, "-").concat(month, "-").concat(day, " ").concat(hours, ":").concat(minutes, ":").concat(seconds);
}
function normalizeSubmitPlatform(platform) {
  var value = String(platform || '').trim();
  if (!value) return 'H5';
  var lower = value.toLowerCase();
  if (lower === 'pc') return 'PC';
  if (lower === 'h5') return 'H5';
  return value;
}

// 后端 checkout 协议字段 option_group_item_id；tempOrder 内部也保持同一字段名。
function formatSubmitOptionItems(options) {
  if (!Array.isArray(options)) return [];
  return options.map(function (d) {
    var _d$add_price;
    var option = _objectSpread(_objectSpread({}, d && _typeof(d) === 'object' ? d : {}), {}, {
      num: d === null || d === void 0 ? void 0 : d.num,
      option_group_item_id: d === null || d === void 0 ? void 0 : d.option_group_item_id,
      option_group_id: d === null || d === void 0 ? void 0 : d.option_group_id
    });
    var addPrice = (_d$add_price = d === null || d === void 0 ? void 0 : d.add_price) !== null && _d$add_price !== void 0 ? _d$add_price : d === null || d === void 0 ? void 0 : d.price;
    if (addPrice !== undefined) option.add_price = String(addPrice);
    delete option.price;
    return option;
  });
}
function toBundleNumber(value) {
  var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  var parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : fallback;
}
function toMoneyString(value) {
  var parsed = Number(value);
  if (Number.isFinite(parsed)) return parsed.toFixed(2);
  if (value === null || value === undefined || value === '') return '0.00';
  return String(value);
}

// 出站补齐：只输出后端 checkout 协议字段，运行时/详情展示字段不进入 bundle payload。
function formatSubmitBundleItems(bundle) {
  if (!Array.isArray(bundle)) return [];
  return bundle.map(function (b) {
    var _ref22, _rawBundle$price, _rawBundle$surcharge_, _rawBundle$num, _rawBundle$is_charge_, _rawBundle$bundle_var, _rawBundle$quantity, _rawBundle$extension_, _rawBundle$extension_2, _ref23, _rawBundle$price_type, _ref24, _rawBundle$price_type2, _rawBundle$bundle_gro, _rawBundle$bundle_id, _rawBundle$bundle_pro;
    var rawBundle = b && _typeof(b) === 'object' ? b : {};
    var existedMetadata = rawBundle.metadata && _typeof(rawBundle.metadata) === 'object' ? rawBundle.metadata : {};

    // bundle_selling_price 出站存「正净额」：markdown 为 |price| − Σoptions（如 3.70），
    // markup/原价维持原值；与后端口径一致（price 仍为毛价）。
    var sellingPrice = getBundleSellingMagnitude(rawBundle).toFixed(2);
    // payment 价由整单折扣均摊层产出；缺省（无折扣）时与 selling 净额同义。
    var paymentPrice = rawBundle.bundle_payment_price !== undefined && rawBundle.bundle_payment_price !== null && rawBundle.bundle_payment_price !== '' ? toMoneyString(rawBundle.bundle_payment_price) : sellingPrice;
    var priceValue = (_ref22 = (_rawBundle$price = rawBundle.price) !== null && _rawBundle$price !== void 0 ? _rawBundle$price : rawBundle.custom_price) !== null && _ref22 !== void 0 ? _ref22 : rawBundle.bundle_selling_price;
    var relationSurchargeIds = Array.isArray(rawBundle.relation_surcharge_ids) ? rawBundle.relation_surcharge_ids : Array.isArray(existedMetadata.relation_surcharge_ids) ? existedMetadata.relation_surcharge_ids : [];
    var surchargeFee = toMoneyString((_rawBundle$surcharge_ = rawBundle.surcharge_fee) !== null && _rawBundle$surcharge_ !== void 0 ? _rawBundle$surcharge_ : existedMetadata.surcharge_fee);
    var productDiscountDifference = toBundleNumber(existedMetadata.product_discount_difference, 0);
    var num = toBundleNumber((_rawBundle$num = rawBundle.num) !== null && _rawBundle$num !== void 0 ? _rawBundle$num : rawBundle.quantity, 1);
    return {
      is_charge_tax: (_rawBundle$is_charge_ = rawBundle.is_charge_tax) !== null && _rawBundle$is_charge_ !== void 0 ? _rawBundle$is_charge_ : 0,
      bundle_variant_id: (_rawBundle$bundle_var = rawBundle.bundle_variant_id) !== null && _rawBundle$bundle_var !== void 0 ? _rawBundle$bundle_var : 0,
      num: num,
      quantity: toBundleNumber((_rawBundle$quantity = rawBundle.quantity) !== null && _rawBundle$quantity !== void 0 ? _rawBundle$quantity : rawBundle.num, num),
      extension_id: (_rawBundle$extension_ = rawBundle.extension_id) !== null && _rawBundle$extension_ !== void 0 ? _rawBundle$extension_ : 0,
      extension_type: (_rawBundle$extension_2 = rawBundle.extension_type) !== null && _rawBundle$extension_2 !== void 0 ? _rawBundle$extension_2 : 'normal',
      price: priceValue,
      price_type: (_ref23 = (_rawBundle$price_type = rawBundle.price_type) !== null && _rawBundle$price_type !== void 0 ? _rawBundle$price_type : rawBundle.custom_price_type) !== null && _ref23 !== void 0 ? _ref23 : '',
      price_type_ext: (_ref24 = (_rawBundle$price_type2 = rawBundle.price_type_ext) !== null && _rawBundle$price_type2 !== void 0 ? _rawBundle$price_type2 : rawBundle.custom_price_type_ext) !== null && _ref24 !== void 0 ? _ref24 : '',
      bundle_selling_price: sellingPrice,
      bundle_payment_price: paymentPrice,
      option: formatSubmitOptionItems(rawBundle.option),
      bundle_group_id: (_rawBundle$bundle_gro = rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle.bundle_group_id) !== null && _rawBundle$bundle_gro !== void 0 ? _rawBundle$bundle_gro : rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle.group_id,
      bundle_id: (_rawBundle$bundle_id = rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle.bundle_id) !== null && _rawBundle$bundle_id !== void 0 ? _rawBundle$bundle_id : rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle.id,
      bundle_product_id: (_rawBundle$bundle_pro = rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle.bundle_product_id) !== null && _rawBundle$bundle_pro !== void 0 ? _rawBundle$bundle_pro : rawBundle === null || rawBundle === void 0 ? void 0 : rawBundle._bundle_product_id,
      metadata: _objectSpread(_objectSpread({}, existedMetadata), {}, {
        surcharge_fee: surchargeFee,
        relation_surcharge_ids: relationSurchargeIds,
        product_discount_difference: productDiscountDifference
      })
    };
  });
}

/**
 * 把 tempOrder product 打包成出站 submit payload。
 *
 * 价格字段语义（出站口径，v2 composite）：
 * - `selling_price`：**行 composite 券后单价**
 *   = `metadata.main_product_selling_price` + Σ(bundle_selling_price × num)。
 * - `original_price`：**行 composite 券前单价**
 *   = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
 * - `payment_price`：兼容后端的出站字段，行 composite 已减整单折扣均摊（无折扣时与 `selling_price` 同义）。
 * - `metadata.source_product_price`：主商品/variant 基础价（不含 option、不含折扣），权威源。
 * - `metadata.main_product_original_price`：含 option、不含折扣。
 * - `metadata.main_product_selling_price`：含 option、含主商品折扣。
 * - `metadata.price_schema_version`：schema 版本号（当前 = 2），用于跨端协商价格口径。
 *
 * 本函数不再改造价格字段形状，仅做字段/metadata 裁剪。
 */
function normalizeSubmitProduct(product) {
  var _rawMetadata$product_, _submitProduct$produc, _submitProduct$paymen;
  var _ref25 = product,
    _runtimeUid = _ref25.unique_identification_number,
    submitProduct = _objectWithoutProperties(_ref25, _excluded);
  var num = submitProduct.num,
    _productSurchargeFee = submitProduct.surcharge_fee,
    _deprecatedDiscountAmount = submitProduct.discount_amount,
    _deprecatedDiscountType = submitProduct.discount_type,
    _deprecatedDiscountway = submitProduct.discountway,
    _deprecatedProductDiscountReason = submitProduct.product_discount_reason,
    _deprecatedDiscountPer = submitProduct.discount_per,
    productRest = _objectWithoutProperties(submitProduct, _excluded2);
  delete productRest["product_".concat('option', "_item")];
  var rawMetadata = submitProduct.metadata || {};
  var bookingUid = rawMetadata.booking_uid;
  var cleanMetadata = {};
  if (rawMetadata.unique_identification_number) {
    cleanMetadata.unique_identification_number = rawMetadata.unique_identification_number;
  }
  var priceMetaKeys = ['main_product_original_price', 'main_product_selling_price', 'main_product_attached_bundle_selling_price', 'main_product_attached_bundle_payment_price', 'average_discount_amount_rate', 'source_product_price', 'main_product_attached_bundle_surcharge_fee', 'main_product_attached_bundle_tax_fee', 'surcharge_rounding_remainder', 'tax_fee_rounding_remainder', 'relation_surcharge_ids', 'discountable_flag', 'parent_unique_identification_number', 'product_add_schedule_time'];
  for (var _i = 0, _priceMetaKeys = priceMetaKeys; _i < _priceMetaKeys.length; _i++) {
    var key = _priceMetaKeys[_i];
    if (rawMetadata[key] !== undefined) {
      cleanMetadata[key] = rawMetadata[key];
    }
  }
  cleanMetadata.product_discount_difference = (_rawMetadata$product_ = rawMetadata.product_discount_difference) !== null && _rawMetadata$product_ !== void 0 ? _rawMetadata$product_ : '';
  if (rawMetadata.price_breakdown) {
    cleanMetadata.price_breakdown = rawMetadata.price_breakdown;
  }
  if (rawMetadata.is_rule !== undefined) {
    cleanMetadata.is_rule = rawMetadata.is_rule;
  }
  var productSku = _objectSpread(_objectSpread({}, submitProduct.product_sku && _typeof(submitProduct.product_sku) === 'object' ? submitProduct.product_sku : {}), {}, {
    option: formatSubmitOptionItems((_submitProduct$produc = submitProduct.product_sku) === null || _submitProduct$produc === void 0 ? void 0 : _submitProduct$produc.option)
  });
  return _objectSpread(_objectSpread(_objectSpread({}, productRest), bookingUid ? {
    booking_uid: bookingUid
  } : {}), {}, {
    product_quantity: toBundleNumber(num !== null && num !== void 0 ? num : submitProduct.product_quantity, 1),
    product_sku: productSku,
    discount_list: normalizeOrderProductDiscountList(submitProduct.discount_list),
    product_bundle: formatSubmitBundleItems(submitProduct.product_bundle),
    metadata: cleanMetadata,
    // 出站兼容：后端消费 payment_price 字段（行 composite 已减整单折扣均摊）。
    // 由整单折扣均摊层产出；缺省（无折扣）时与 selling_price 同义。
    payment_price: (_submitProduct$paymen = submitProduct.payment_price) !== null && _submitProduct$paymen !== void 0 ? _submitProduct$paymen : submitProduct.selling_price
  });
}
var SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type'];
export function normalizeBookingIsAll(booking) {
  return booking.is_all === true || booking.is_all === 1 || booking.is_all === '1' || booking.is_all === 'true' ? 1 : 0;
}
export function normalizeBookingSubType(booking) {
  if (normalizeBookingIsAll(booking) === 1) return 'days';
  if (booking.sub_type !== undefined && booking.sub_type !== null && booking.sub_type !== '') {
    return String(booking.sub_type);
  }
  return 'minutes';
}
export function normalizeSubmitBooking(booking) {
  var rawMetadata = booking.metadata || {};
  var cleanMetadata = {};
  var _iterator3 = _createForOfIteratorHelper(SUBMIT_BOOKING_METADATA_WHITELIST),
    _step3;
  try {
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      var key = _step3.value;
      if (rawMetadata[key] !== undefined) {
        cleanMetadata[key] = rawMetadata[key];
      }
    }
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
  if (cleanMetadata.holder_id === undefined) cleanMetadata.holder_id = null;
  var bookingRecord = booking;
  var startDate = bookingRecord.start_date;
  var shouldRestoreSelectDate = bookingRecord.select_date === undefined || bookingRecord.select_date === null || bookingRecord.select_date === '';
  var selectDateFromStartDate = typeof startDate === 'string' ? startDate.split(/\s+/)[0] : startDate;
  return _objectSpread(_objectSpread(_objectSpread({}, booking), shouldRestoreSelectDate && selectDateFromStartDate ? {
    select_date: selectDateFromStartDate
  } : {}), {}, {
    is_all: normalizeBookingIsAll(bookingRecord),
    sub_type: normalizeBookingSubType(bookingRecord),
    metadata: cleanMetadata
  });
}
var DEFAULT_TABLE_OCCUPANCY_DURATION = 20;
function resolveTableOccupancyDuration(tempOrder) {
  var _metadata$table_confi, _metadata$tableConfig, _metadata$resource_co, _metadata$resourceCon;
  var metadata = tempOrder.metadata || {};
  var candidates = [metadata.table_occupancy_duration, metadata.booking_duration, metadata.table_duration, metadata.duration, (_metadata$table_confi = metadata.table_config) === null || _metadata$table_confi === void 0 ? void 0 : _metadata$table_confi.occupancy_duration, (_metadata$tableConfig = metadata.tableConfig) === null || _metadata$tableConfig === void 0 ? void 0 : _metadata$tableConfig.occupancy_duration, (_metadata$resource_co = metadata.resource_config) === null || _metadata$resource_co === void 0 ? void 0 : _metadata$resource_co.occupancy_duration, (_metadata$resourceCon = metadata.resourceConfig) === null || _metadata$resourceCon === void 0 ? void 0 : _metadata$resourceCon.occupancy_duration];
  for (var _i2 = 0, _candidates = candidates; _i2 < _candidates.length; _i2++) {
    var value = _candidates[_i2];
    var duration = Number(value);
    if (Number.isFinite(duration) && duration > 0) {
      return Math.floor(duration);
    }
  }
  return DEFAULT_TABLE_OCCUPANCY_DURATION;
}

/** 提交用人数：有限且为正则向下取整，否则为 1 */
export function normalizeSubmitCollectPaxValue(value) {
  var n = Number(value);
  return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1;
}

/** 从临时订单 metadata 解析合成 booking 的 collect_pax */
export function resolveSubmitCollectPax(tempOrder) {
  var _tempOrder$metadata;
  return normalizeSubmitCollectPaxValue((_tempOrder$metadata = tempOrder.metadata) === null || _tempOrder$metadata === void 0 ? void 0 : _tempOrder$metadata.collect_pax);
}
export function createDefaultTempOrder(params) {
  return {
    order_id: null,
    external_sale_number: '',
    order_number: null,
    shop_order_number: null,
    shop_full_order_number: null,
    type: '',
    business_code: undefined,
    platform: 'h5',
    sales_channel: 'my_pisel',
    order_sales_channel: 'online_store',
    status: 'normal',
    payment_status: 'payment_processing',
    shipping_status: 'unfulfilled',
    customer_id: 0,
    customer_name: '',
    country_calling_code: '',
    phone: '',
    email: '',
    customer: null,
    is_price_include_tax: 1,
    tax_title: '',
    tax_country_code: '',
    currency_code: '',
    currency_symbol: '',
    currency_format: 'symbol_first',
    is_deposit: 0,
    deposit_amount: '0.00',
    shop_discount: '0.00',
    surcharge_fee: '0.00',
    note: '',
    schedule_date: params.now,
    created_at: undefined,
    request_unique_idempotency_token: '',
    vouchers: [],
    products: [],
    bookings: [],
    payments: [],
    surcharges: [],
    relation_forms: [],
    contacts: [],
    contacts_info: null,
    holder: null,
    metadata: {},
    _extend: {
      productsByUid: {}
    }
  };
}
export function buildSubmitPayload(params) {
  var _tempOrder$customer_i, _tempOrder$order_numb, _tempOrder$shop_order, _tempOrder$shop_full_, _ref27, _tempOrder$is_price_i, _tempOrder$is_deposit, _enhancedPayload$summ;
  var tempOrder = params.tempOrder,
    cacheId = params.cacheId,
    _params$now = params.now,
    now = _params$now === void 0 ? new Date() : _params$now,
    platform = params.platform,
    businessCode = params.businessCode,
    channel = params.channel,
    type = params.type,
    summary = params.summary,
    enhance = params.enhance;
  var scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
  var bookingUuid = createUuidV4();
  var _ref26 = tempOrder,
    _extend = _ref26._extend,
    _relationId = _ref26.relation_id,
    _tableFormId = _ref26.table_form_id,
    _resourceId = _ref26.resource_id,
    _summary = _ref26.summary,
    _lastOrderInfo = _ref26.lastOrderInfo,
    _paidAmount = _ref26.paid_amount,
    _shopId = _ref26.shop_id,
    _shopNote = _ref26.shop_note,
    _shopServiceType = _ref26.shop_service_type,
    _startTime = _ref26.start_time,
    _customer = _ref26.customer,
    _discountList = _ref26.discount_list,
    _rootTaxFee = _ref26.tax_fee,
    _totalAmount = _ref26.total_amount,
    _totalRefundAmount = _ref26.total_refund_amount,
    _createDate = _ref26.create_date,
    _holderId = _ref26.holder_id,
    tempOrderRest = _objectWithoutProperties(_ref26, _excluded3);
  var submitType = type !== null && type !== void 0 ? type : tempOrder.type;
  if (!submitType) {
    var _tempOrder$bookings;
    // 如果外部没有传递 types，根据订单里当前是否有 bookings 来决定是 appointment_booking 还是 virtual
    if (tempOrder !== null && tempOrder !== void 0 && (_tempOrder$bookings = tempOrder.bookings) !== null && _tempOrder$bookings !== void 0 && _tempOrder$bookings.length) {
      submitType = 'appointment_booking';
    } else {
      submitType = 'virtual';
    }
  }
  var payload = _objectSpread(_objectSpread({}, tempOrderRest), {}, {
    customer_id: (_tempOrder$customer_i = tempOrder.customer_id) !== null && _tempOrder$customer_i !== void 0 ? _tempOrder$customer_i : 1,
    customer_name: tempOrder.customer_name || 'Walk-In',
    order_number: (_tempOrder$order_numb = tempOrder.order_number) !== null && _tempOrder$order_numb !== void 0 ? _tempOrder$order_numb : null,
    shop_order_number: (_tempOrder$shop_order = tempOrder.shop_order_number) !== null && _tempOrder$shop_order !== void 0 ? _tempOrder$shop_order : null,
    shop_full_order_number: (_tempOrder$shop_full_ = tempOrder.shop_full_order_number) !== null && _tempOrder$shop_full_ !== void 0 ? _tempOrder$shop_full_ : null,
    platform: normalizeSubmitPlatform(platform),
    request_unique_idempotency_token: tempOrder.request_unique_idempotency_token || "".concat(tempOrder.external_sale_number, "_").concat(now.getTime()),
    type: submitType,
    business_code: businessCode !== null && businessCode !== void 0 ? businessCode : tempOrder.business_code,
    sales_channel: tempOrder.sales_channel || 'my_pisel',
    order_sales_channel: (_ref27 = channel !== null && channel !== void 0 ? channel : tempOrder.order_sales_channel) !== null && _ref27 !== void 0 ? _ref27 : 'online_store',
    status: tempOrder.status || 'normal',
    payment_status: tempOrder.payment_status || 'payment_processing',
    // shipping_status: tempOrder.shipping_status || 'unfulfilled',
    is_price_include_tax: (_tempOrder$is_price_i = tempOrder.is_price_include_tax) !== null && _tempOrder$is_price_i !== void 0 ? _tempOrder$is_price_i : 1,
    currency_format: tempOrder.currency_format || 'symbol_first',
    is_deposit: (_tempOrder$is_deposit = tempOrder.is_deposit) !== null && _tempOrder$is_deposit !== void 0 ? _tempOrder$is_deposit : 0,
    deposit_amount: tempOrder.deposit_amount || '0.00',
    shop_discount: tempOrder.shop_discount || '0.00',
    surcharge_fee: tempOrder.surcharge_fee || '0.00',
    note: tempOrder.note || '',
    delivery_type: tempOrder.delivery_type || 'nil',
    schedule_date: scheduleDate,
    // created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
    bookings: (tempOrder.bookings || []).filter(function (booking) {
      return Number(booking.parent_id) !== 0;
    }).map(function (booking) {
      return normalizeSubmitBooking(booking);
    }),
    payments: tempOrder.payments || [],
    relation_forms: tempOrder.relation_forms || [],
    // contacts: tempOrder.contacts || [],
    contacts_info: tempOrder.contacts_info && !Array.isArray(tempOrder.contacts_info) ? tempOrder.contacts_info : null,
    // holder: tempOrder.holder || null,
    summary: summary || tempOrder.summary || createEmptySummary(),
    metadata: function () {
      var _ref28 = tempOrder.metadata || {},
        _collectPax = _ref28.collect_pax,
        _tableOccupancyDuration = _ref28.table_occupancy_duration,
        rest = _objectWithoutProperties(_ref28, _excluded4);
      return _objectSpread({}, rest);
    }(),
    products: (tempOrder.products || []).map(function (product) {
      return normalizeSubmitProduct(product);
    })
  });
  if (!enhance) return payload;
  var enhancedPayload = enhance(payload, {
    tempOrder: tempOrder,
    bookingUuid: bookingUuid,
    now: now
  });
  return _objectSpread(_objectSpread({}, enhancedPayload), {}, {
    summary: (_enhancedPayload$summ = enhancedPayload.summary) !== null && _enhancedPayload$summ !== void 0 ? _enhancedPayload$summ : payload.summary
  });
}
export function mapPaymentItemToOrderPayment(paymentItem) {
  var _item$custom_payment_, _item$amount;
  var item = paymentItem;
  var customPaymentId = (_item$custom_payment_ = item.custom_payment_id) !== null && _item$custom_payment_ !== void 0 ? _item$custom_payment_ : item.id;
  var metadata = item.metadata && _typeof(item.metadata) === 'object' ? _objectSpread({}, item.metadata) : {};
  if (item.uuid && !metadata.unique_payment_number) {
    metadata.unique_payment_number = String(item.uuid);
  }
  var paymentMetadataKeys = ['rounding_rule', 'shop_wallet_pass_id', 'actual_paid_amount', 'change_given_amount'];
  for (var _i3 = 0, _paymentMetadataKeys = paymentMetadataKeys; _i3 < _paymentMetadataKeys.length; _i3++) {
    var key = _paymentMetadataKeys[_i3];
    if (item[key] !== undefined && metadata[key] === undefined) {
      metadata[key] = item[key];
    }
  }
  return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, item.order_payment_id !== undefined ? {
    order_payment_id: item.order_payment_id
  } : {}), {}, {
    amount: String((_item$amount = item.amount) !== null && _item$amount !== void 0 ? _item$amount : '0.00'),
    code: String(item.code || ''),
    custom_payment_id: Number(customPaymentId !== null && customPaymentId !== void 0 ? customPaymentId : 0),
    name: String(item.name || ''),
    type: String(item.type || '')
  }, item.voucher_id !== undefined ? {
    voucher_id: item.voucher_id
  } : {}), item.origin_amount !== undefined ? {
    origin_amount: String(item.origin_amount)
  } : {}), item.service_fee !== undefined ? {
    service_fee: String(item.service_fee)
  } : {}), item.status !== undefined ? {
    status: item.status
  } : {}), item.payment_time !== undefined ? {
    payment_time: item.payment_time
  } : {}), item.wallet_pass_usage_unit !== undefined ? {
    wallet_pass_usage_unit: item.wallet_pass_usage_unit
  } : {}), item.wallet_pass_use_value !== undefined ? {
    wallet_pass_use_value: item.wallet_pass_use_value
  } : {}), item.fund_record && _typeof(item.fund_record) === 'object' && !Array.isArray(item.fund_record) ? {
    fund_record: _objectSpread({}, item.fund_record)
  } : {}), {}, {
    metadata: metadata
  }, item.rounding_amount !== undefined ? {
    rounding_amount: String(item.rounding_amount)
  } : {}), item.service_charge !== undefined ? {
    service_charge: item.service_charge
  } : {}), item.order_payment_type !== undefined ? {
    order_payment_type: item.order_payment_type
  } : {}), item.updated_at !== undefined ? {
    updated_at: item.updated_at
  } : {});
}
export function mapPaymentItemsToOrderPayments(paymentItems) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  if (!Array.isArray(paymentItems)) return [];
  return paymentItems.filter(function (item) {
    return options.includeVoided || item.status !== 'voided';
  }).map(function (item) {
    return mapPaymentItemToOrderPayment(item);
  });
}

/**
 * 历史 V1 加餐结构映射器。
 *
 * @deprecated 标准 Sales checkout 已统一提交结构。
 * 本函数仅保留以兼容历史接入方，未来会移除。新代码请勿再调用。
 */
export function formatV1Product(products) {
  return products.map(function (product) {
    var _product$product_sku, _product$note;
    return {
      bundle: product.product_bundle,
      key: product.product_id,
      option: ((_product$product_sku = product.product_sku) === null || _product$product_sku === void 0 ? void 0 : _product$product_sku.option) || [],
      product_id: product.product_id,
      product_variant_id: product.product_variant_id,
      num: product.product_quantity,
      note: String((_product$note = product.note) !== null && _product$note !== void 0 ? _product$note : ''),
      rowKey: product.product_id,
      session: null,
      unique: createUuidV4()
    };
  });
}

/**
 * 判断 holder_id 是否已分配（非空）。
 *
 * @example
 * hasAssignedHolderId(12); // true
 * hasAssignedHolderId([]); // false
 */
export function hasAssignedHolderId(value) {
  if (value === undefined || value === null || value === '') return false;
  if (Array.isArray(value)) return value.length > 0;
  return true;
}

/**
 * 清空 tempOrder 购物车行上的 holder 分配（products / bookings / runtime origin）。
 * 移除或更换下单客户时调用，与 booking 页换客户清 holder 行为对齐。
 *
 * @example
 * clearTempOrderHolderAssignments(tempOrder);
 */
export function clearTempOrderHolderAssignments(tempOrder) {
  var _tempOrder$_extend;
  var changed = false;
  var resetHolderField = function resetHolderField(target) {
    var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'holder_id';
    if (!hasAssignedHolderId(target[key])) return;
    target[key] = null;
    changed = true;
  };
  var _iterator4 = _createForOfIteratorHelper(tempOrder.products || []),
    _step4;
  try {
    for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
      var product = _step4.value;
      if (product.metadata && _typeof(product.metadata) === 'object') {
        resetHolderField(product.metadata);
      }
    }
  } catch (err) {
    _iterator4.e(err);
  } finally {
    _iterator4.f();
  }
  var _iterator5 = _createForOfIteratorHelper(tempOrder.bookings || []),
    _step5;
  try {
    for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
      var booking = _step5.value;
      var bookingRecord = booking;
      if (booking.metadata && _typeof(booking.metadata) === 'object') {
        resetHolderField(booking.metadata);
      }
      if (bookingRecord.holder !== undefined && bookingRecord.holder !== null) {
        delete bookingRecord.holder;
        changed = true;
      }
    }
  } catch (err) {
    _iterator5.e(err);
  } finally {
    _iterator5.f();
  }
  var productsByUid = (_tempOrder$_extend = tempOrder._extend) === null || _tempOrder$_extend === void 0 ? void 0 : _tempOrder$_extend.productsByUid;
  if (productsByUid && _typeof(productsByUid) === 'object') {
    for (var _i4 = 0, _Object$values = Object.values(productsByUid); _i4 < _Object$values.length; _i4++) {
      var entry = _Object$values[_i4];
      var origin = entry === null || entry === void 0 ? void 0 : entry.origin;
      if (!origin || _typeof(origin) !== 'object') continue;
      if (origin.metadata && _typeof(origin.metadata) === 'object') {
        resetHolderField(origin.metadata);
      }
      if (origin._extend && _typeof(origin._extend) === 'object') {
        resetHolderField(origin._extend);
      }
    }
  }
  return changed;
}

/**
 * 读取购物车行的 stable uid（优先 metadata.unique_identification_number）。
 *
 * @example
 * getOrderProductLineUid({ metadata: { unique_identification_number: 'line-1' } }); // 'line-1'
 */
export function getOrderProductLineUid(product) {
  var _product$metadata$uni, _product$metadata6;
  if (!product || _typeof(product) !== 'object') return null;
  var uid = (_product$metadata$uni = (_product$metadata6 = product.metadata) === null || _product$metadata6 === void 0 ? void 0 : _product$metadata6.unique_identification_number) !== null && _product$metadata$uni !== void 0 ? _product$metadata$uni : product.unique_identification_number;
  if (uid === undefined || uid === null || uid === '') return null;
  return String(uid);
}

/**
 * 判断展示字段是否为空（含 i18n 对象全空）。
 *
 * @example
 * isEmptyOrderProductDisplayValue(''); // true
 * isEmptyOrderProductDisplayValue({ auto: '桌台费' }); // false
 */
export function isEmptyOrderProductDisplayValue(value) {
  if (value === undefined || value === null) return true;
  if (typeof value === 'string') return value.trim() === '';
  if (_typeof(value) === 'object') {
    var record = value;
    return !Object.values(record).some(function (item) {
      return typeof item === 'string' && item.trim() !== '';
    });
  }
  return false;
}

/**
 * calcDiscount / applyDiscount 回写时 Rules 往往不带 product_title 等展示字段；
 * 用旧行补齐，避免编辑态 hydrate 后标题被冲掉。
 *
 * @example
 * mergeOrderProductDisplayFields(
 *   { product_title: { auto: '桌台费' }, metadata: { unique_identification_number: 'u1' } },
 *   { selling_price: '10.00', metadata: { unique_identification_number: 'u1' } },
 * );
 */
export function mergeOrderProductDisplayFields(previous, next) {
  var merged = _objectSpread({}, next);
  var displayFields = ['product_title', 'product_name', 'product_cover', 'cover', 'variant_title', 'product_sku', 'payment_price'];
  displayFields.forEach(function (field) {
    if (isEmptyOrderProductDisplayValue(merged[field]) && !isEmptyOrderProductDisplayValue(previous[field])) {
      merged[field] = previous[field];
    }
  });
  if (previous.metadata || next.metadata) {
    merged.metadata = _objectSpread(_objectSpread({}, previous.metadata || {}), next.metadata || {});
    ['product_title', 'product_name'].forEach(function (field) {
      var _previous$metadata;
      if (isEmptyOrderProductDisplayValue(merged.metadata[field]) && !isEmptyOrderProductDisplayValue((_previous$metadata = previous.metadata) === null || _previous$metadata === void 0 ? void 0 : _previous$metadata[field])) {
        merged.metadata[field] = previous.metadata[field];
      }
    });
  }
  if (previous._extend && !merged._extend) {
    merged._extend = previous._extend;
  }
  return merged;
}

/**
 * 按 uid 索引 tempOrder.products，供 applyDiscount 合并展示字段。
 *
 * @example
 * indexOrderProductsByUid([{ metadata: { unique_identification_number: 'u1' } }]);
 */
export function indexOrderProductsByUid(products) {
  var map = new Map();
  (products || []).forEach(function (product, index) {
    var uid = getOrderProductLineUid(product);
    if (uid) {
      map.set(uid, product);
      return;
    }
    map.set("__index__:".concat(index), product);
  });
  return map;
}
export { createEmptySummary } from "../../solution/ScanOrder/utils";
export { buildManualProductDiscountItem, ensureManualProductDiscountList, findManualProductDiscountItem, mergeManualProductDiscountIntoList, resolveManualDiscountMessage, resolveManualDiscountOriginTotal, resolveManualDiscountReasonFromSources, resolveSafeProductNum, shouldBuildManualProductDiscount, syncManualProductDiscountProductNum, stripManualProductDiscountItems } from "./utils/manualProductDiscount";