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

// src/plus/salesSdk/utils/mergeBookingsForDisplay.ts
var mergeBookingsForDisplay_exports = {};
__export(mergeBookingsForDisplay_exports, {
  buildBookingMergeKey: () => buildBookingMergeKey,
  cloneBookingForMergedBookingAppend: () => cloneBookingForMergedBookingAppend,
  cloneProductForMergedBookingAppend: () => cloneProductForMergedBookingAppend,
  getMergedBookingSources: () => getMergedBookingSources,
  isMergedBookingTarget: () => isMergedBookingTarget,
  mergeBookingsForDisplay: () => mergeBookingsForDisplay,
  resolveBookingDisplayQuantity: () => resolveBookingDisplayQuantity
});
module.exports = __toCommonJS(mergeBookingsForDisplay_exports);
var import_identity = require("./identity");
var import_productSkuOptions = require("./productSkuOptions");
function stableSerialize(value) {
  return JSON.stringify(normalizeForStableSerialize(value));
}
function normalizeForStableSerialize(value) {
  if (value === void 0) return null;
  if (value === null) return null;
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
    return value;
  }
  if (Array.isArray(value)) {
    return value.map((item) => normalizeForStableSerialize(item));
  }
  if (typeof value === "object") {
    return Object.keys(value).sort().reduce((acc, key) => {
      acc[key] = normalizeForStableSerialize(value[key]);
      return acc;
    }, {});
  }
  return String(value);
}
var PROMOTION_IDENTITY_KEYS = /* @__PURE__ */ new Set([
  "unique_identification_number",
  "product_uid",
  "booking_uid",
  "sourceProductIds",
  "source_product_ids"
]);
function normalizePromotionState(value) {
  if (Array.isArray(value)) {
    return value.map((item) => normalizePromotionState(item));
  }
  if (!value || typeof value !== "object") {
    return value;
  }
  return Object.keys(value).reduce(
    (acc, key) => {
      if (PROMOTION_IDENTITY_KEYS.has(key)) return acc;
      acc[key] = normalizePromotionState(value[key]);
      return acc;
    },
    {}
  );
}
function normalizeKeyPart(value) {
  if (value === void 0 || value === null) return "";
  return String(value);
}
function resolveBookingNote(booking) {
  var _a;
  return normalizeKeyPart(((_a = booking == null ? void 0 : booking._extend) == null ? void 0 : _a.note) ?? (booking == null ? void 0 : booking.note)).trim();
}
function buildResourceFingerprint(booking) {
  var _a;
  return stableSerialize({
    relation_id: booking.relation_id,
    relation_type: booking.relation_type,
    resource_id: booking.resource_id,
    resources: booking.resources,
    resource: (_a = booking._extend) == null ? void 0 : _a.resource
  });
}
function buildHolderFingerprint(booking) {
  return stableSerialize({
    holder_id: booking.holder_id,
    holders: booking.holders
  });
}
function buildProductSpecFingerprint(product) {
  return stableSerialize({
    option: (0, import_productSkuOptions.getLineProductOptions)(product),
    bundle: product.product_bundle
  });
}
function buildPriceFingerprint(product) {
  const metadata = product.metadata || {};
  return stableSerialize({
    selling_price: product.selling_price,
    original_price: product.original_price,
    source_product_price: metadata.source_product_price,
    main_product_selling_price: metadata.main_product_selling_price,
    main_product_original_price: metadata.main_product_original_price,
    price_override: metadata.price_override,
    is_manual_discount: metadata.is_manual_discount
  });
}
function buildPromotionFingerprint(product) {
  const metadata = product.metadata || {};
  return stableSerialize({
    discount_list: product.discount_list,
    promotion: normalizePromotionState(metadata._promotion),
    promotionTags: metadata._promotionTags ?? product._promotionTags,
    giftInfo: normalizePromotionState(metadata._giftInfo ?? product._giftInfo),
    giftData: normalizePromotionState(product.giftData),
    isGiftPromotion: product._isGiftPromotion
  });
}
function buildBookingTimeFingerprint(booking) {
  return stableSerialize({
    start_date: booking.start_date,
    start_time: booking.start_time,
    end_date: booking.end_date,
    end_time: booking.end_time,
    duration: booking.duration
  });
}
function buildBookingMergeKey(booking) {
  var _a;
  const product = (_a = booking._extend) == null ? void 0 : _a.product;
  if (!product) return null;
  return stableSerialize({
    bookingTime: buildBookingTimeFingerprint(booking),
    productBase: {
      product_id: product.product_id,
      product_variant_id: product.product_variant_id
    },
    productSpec: buildProductSpecFingerprint(product),
    price: buildPriceFingerprint(product),
    resource: buildResourceFingerprint(booking),
    holder: buildHolderFingerprint(booking),
    note: resolveBookingNote(booking),
    promotion: buildPromotionFingerprint(product)
  });
}
function resolveBookingDisplayQuantity(product) {
  const num = Number(product == null ? void 0 : product.num);
  return Number.isFinite(num) && num > 0 ? num : 1;
}
function getMergedBookingSources(target) {
  const extend = target == null ? void 0 : target._extend;
  const sources = (extend == null ? void 0 : extend.mergedFrom) ?? (extend == null ? void 0 : extend.mergedBookingSources);
  return Array.isArray(sources) ? sources : [];
}
function isMergedBookingTarget(target) {
  return getMergedBookingSources(target).length > 1;
}
function mergeBookingsForDisplay(bookings) {
  if (!Array.isArray(bookings) || bookings.length <= 1) return bookings;
  const groups = /* @__PURE__ */ new Map();
  const passthrough = [];
  bookings.forEach((booking, index) => {
    const key = buildBookingMergeKey(booking);
    if (!key) {
      passthrough.push({ index, booking });
      return;
    }
    const existed = groups.get(key) ?? [];
    existed.push(booking);
    groups.set(key, existed);
  });
  const representatives = /* @__PURE__ */ new Map();
  groups.forEach((group) => {
    if (group.length <= 1) {
      representatives.set(group[0], group[0]);
      return;
    }
    const sources = group.map((booking) => {
      var _a;
      const product = (_a = booking._extend) == null ? void 0 : _a.product;
      if (!product) return null;
      return {
        booking,
        product,
        identity: (0, import_identity.pickIdentity)(product)
      };
    }).filter((item) => item !== null);
    const displayQuantity = sources.reduce(
      (total, source) => total + resolveBookingDisplayQuantity(source.product),
      0
    );
    const representative = group[0];
    const representativeProduct = representative._extend.product;
    const displayProduct = representativeProduct ? {
      ...representativeProduct,
      num: displayQuantity,
      _extend: {
        ...representativeProduct._extend,
        isMergedBookingLine: true,
        displayQuantity,
        mergedBookingSources: sources
      }
    } : representativeProduct;
    representatives.set(representative, {
      ...representative,
      _extend: {
        ...representative._extend,
        product: displayProduct,
        isMergedBookingLine: true,
        displayQuantity,
        mergedFrom: sources
      }
    });
  });
  return bookings.reduce((acc, booking, index) => {
    const passthroughItem = passthrough.find((item) => item.index === index);
    if (passthroughItem) {
      acc.push(passthroughItem.booking);
      return acc;
    }
    const representative = representatives.get(booking);
    if (representative) {
      acc.push(representative);
    }
    return acc;
  }, []);
}
function cloneProductForMergedBookingAppend(product) {
  const cloned = {
    ...product,
    num: 1,
    metadata: {
      ...product.metadata || {}
    }
  };
  delete cloned._identity;
  delete cloned._extend;
  delete cloned.unique_identification_number;
  delete cloned.identity_key;
  delete cloned.booking_uid;
  delete cloned.metadata.unique_identification_number;
  delete cloned.metadata.booking_uid;
  return cloned;
}
function cloneBookingForMergedBookingAppend(booking) {
  const cloned = {
    ...booking,
    metadata: {
      ...booking.metadata || {}
    }
  };
  delete cloned.product_uid;
  delete cloned.booking_uid;
  delete cloned.booking_id;
  delete cloned.metadata.unique_identification_number;
  return cloned;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildBookingMergeKey,
  cloneBookingForMergedBookingAppend,
  cloneProductForMergedBookingAppend,
  getMergedBookingSources,
  isMergedBookingTarget,
  mergeBookingsForDisplay,
  resolveBookingDisplayQuantity
});
