var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/modules/SalesSummary/utils.ts
var utils_exports = {};
__export(utils_exports, {
  calculateSalesSummary: () => calculateSalesSummary,
  createEmptySalesSummary: () => createEmptySalesSummary
});
module.exports = __toCommonJS(utils_exports);
var import_decimal = __toESM(require("decimal.js"));
var import_utils = require("../Summary/utils");
var import_utils2 = require("../Order/utils");
function toDecimal(value) {
  return new import_decimal.default(value || 0);
}
function toFixed2(value) {
  return new import_decimal.default(value || 0).toFixed(2);
}
function toAmountFormat(value) {
  return new import_decimal.default(value || 0).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
}
function toBackendTaxFee(value) {
  return toBcScale(value, 2);
}
function toBcScale(value, scale) {
  const factor = new import_decimal.default(10).pow(scale);
  return new import_decimal.default(value || 0).times(factor).toDecimalPlaces(0, import_decimal.default.ROUND_DOWN).div(factor);
}
function bcAdd(left, right, scale) {
  return toBcScale(new import_decimal.default(left || 0).plus(right || 0), scale);
}
function bcSub(left, right, scale) {
  return toBcScale(new import_decimal.default(left || 0).minus(right || 0), scale);
}
function bcMul(left, right, scale) {
  return toBcScale(new import_decimal.default(left || 0).times(right || 0), scale);
}
function bcDiv(left, right, scale) {
  const divisor = new import_decimal.default(right || 0);
  if (divisor.eq(0))
    return new import_decimal.default(0);
  return toBcScale(new import_decimal.default(left || 0).div(divisor), scale);
}
function getSafeNum(num) {
  if (!num || Number.isNaN(num))
    return 1;
  if (num < 1)
    return 1;
  return Math.floor(num);
}
function getBundleUnitPrice(product, useOriginal = false) {
  const bundleItems = product.product_bundle || [];
  return bundleItems.reduce((sum, item) => {
    const quantity = getSafeNum(item == null ? void 0 : item.num);
    const signedUnit = (0, import_utils2.getBundleSignedUnit)(item, { useOriginal });
    return sum.plus(signedUnit.times(quantity));
  }, new import_decimal.default(0));
}
function getUnitPaymentTotal(product) {
  var _a, _b;
  const mainSelling = (_a = product.metadata) == null ? void 0 : _a.main_product_selling_price;
  const mainOriginal = (_b = product.metadata) == null ? void 0 : _b.main_product_original_price;
  const basePrice = mainSelling !== void 0 ? toDecimal(mainSelling) : mainOriginal !== void 0 ? toDecimal(mainOriginal) : toDecimal(product.selling_price);
  return basePrice.plus(getBundleUnitPrice(product));
}
function getUnitOriginalTotal(product) {
  var _a, _b;
  const mainOriginal = (_a = product.metadata) == null ? void 0 : _a.main_product_original_price;
  const mainSelling = (_b = product.metadata) == null ? void 0 : _b.main_product_selling_price;
  const basePrice = mainOriginal !== void 0 ? toDecimal(mainOriginal) : mainSelling !== void 0 ? toDecimal(mainSelling) : toDecimal(product.original_price || product.selling_price);
  return basePrice.plus(getBundleUnitPrice(product, true));
}
function isGeneratedVoucherProduct(product) {
  const record = product;
  const metadata = (record == null ? void 0 : record.metadata) || {};
  return (record == null ? void 0 : record.extension_type) === "product_voucher" || metadata.parent_order_detail_id !== void 0 || metadata.gift_card_type !== void 0;
}
function buildSurchargeServiceItems(products) {
  return products.map((product) => {
    var _a, _b;
    const quantity = getSafeNum(product.num);
    const unitTotal = getUnitPaymentTotal(product);
    const options = (0, import_utils2.getProductSkuOptions)(product);
    const persistedSurchargeFee = getPersistedMainSurchargeFee(product);
    return {
      id: product.product_id,
      num: quantity,
      total: unitTotal.toNumber(),
      price: unitTotal.toNumber(),
      is_charge_tax: product.is_charge_tax ?? 0,
      isCustomItem: product.product_id === null,
      _origin: product._origin || {
        product: {
          discount_list: product.discount_list || [],
          product_bundle: product.product_bundle || [],
          product_sku: product.product_sku || { option: options }
        }
      },
      bundle: product.product_bundle || [],
      option: options,
      options,
      relation_details: [],
      metadata: {
        ...product.metadata || {},
        __persisted_surcharge_fee: persistedSurchargeFee == null ? void 0 : persistedSurchargeFee.toFixed(2)
      },
      start_date: ((_a = product.metadata) == null ? void 0 : _a.start_date) || "",
      start_time: ((_b = product.metadata) == null ? void 0 : _b.start_time) || ""
    };
  });
}
function getRelationSurchargeIds(item) {
  var _a;
  const ids = [
    ...Array.isArray(item == null ? void 0 : item.relation_surcharge_ids) ? item.relation_surcharge_ids : [],
    ...Array.isArray((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.relation_surcharge_ids) ? item.metadata.relation_surcharge_ids : []
  ];
  return [...new Set(ids.filter((id) => id !== void 0 && id !== null && id !== ""))];
}
function getSurchargeConfigId(config) {
  return (config == null ? void 0 : config.id) ?? (config == null ? void 0 : config.surcharge_id);
}
function getSurchargeConfigById(surchargeList) {
  const map = /* @__PURE__ */ new Map();
  for (const config of surchargeList || []) {
    const id = getSurchargeConfigId(config);
    if (id !== void 0)
      map.set(id, config);
  }
  return map;
}
function getMainSurchargeUnitAmount(product) {
  var _a, _b;
  const record = product;
  return toDecimal(
    ((_a = record.metadata) == null ? void 0 : _a.main_product_attached_bundle_selling_price) ?? ((_b = record.metadata) == null ? void 0 : _b.main_product_selling_price) ?? record.selling_price ?? 0
  );
}
function getBundleSurchargeUnitAmount(bundle) {
  return toDecimal((bundle == null ? void 0 : bundle.bundle_selling_price) ?? (bundle == null ? void 0 : bundle.bundle_sum_price) ?? (bundle == null ? void 0 : bundle.price) ?? 0);
}
function getBundleProductId(bundle) {
  const id = (bundle == null ? void 0 : bundle.bundle_product_id) ?? (bundle == null ? void 0 : bundle._bundle_product_id) ?? (bundle == null ? void 0 : bundle.product_id);
  if (id === void 0 || id === null || id === "")
    return null;
  const parsed = Number(id);
  if (!Number.isFinite(parsed))
    return null;
  return parsed;
}
function getPersistedMainSurchargeFee(product) {
  var _a;
  if ((product == null ? void 0 : product.order_detail_id) === void 0 || (product == null ? void 0 : product.order_detail_id) === null)
    return null;
  const value = (product == null ? void 0 : product.surcharge_fee) ?? (product == null ? void 0 : product.main_product_attached_bundle_surcharge_fee) ?? ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.main_product_attached_bundle_surcharge_fee);
  if (value === void 0 || value === null || value === "")
    return null;
  return toDecimal(value);
}
function getPersistedSourceSurchargeFee(sourceItem) {
  var _a;
  const value = (_a = sourceItem == null ? void 0 : sourceItem.metadata) == null ? void 0 : _a.__persisted_surcharge_fee;
  if (value === void 0 || value === null || value === "")
    return null;
  return toDecimal(value);
}
function getPersistedSurchargeRemainder(item, sourceItem) {
  var _a, _b;
  const value = ((_a = sourceItem == null ? void 0 : sourceItem.metadata) == null ? void 0 : _a.surcharge_rounding_remainder) ?? (item == null ? void 0 : item.surcharge_rounding_remainder) ?? ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.surcharge_rounding_remainder);
  if (value === void 0 || value === null || value === "")
    return null;
  return toDecimal(value);
}
function getPersistedQuantity(item, fallbackQuantity) {
  const isPersistedLine = (item == null ? void 0 : item.order_detail_id) !== void 0 && (item == null ? void 0 : item.order_detail_id) !== null;
  if (!isPersistedLine)
    return new import_decimal.default(0);
  const value = (item == null ? void 0 : item.product_quantity) ?? (item == null ? void 0 : item.quantity);
  const parsed = new import_decimal.default(value || 0);
  if (parsed.lte(0))
    return import_decimal.default.min(fallbackQuantity, 1);
  return import_decimal.default.min(fallbackQuantity, parsed);
}
function getPersistedBundleSurchargeFee(bundle, product) {
  var _a;
  if ((bundle == null ? void 0 : bundle.order_detail_id) === void 0 && (product == null ? void 0 : product.order_detail_id) === void 0)
    return null;
  if ((bundle == null ? void 0 : bundle.order_detail_id) === null && (product == null ? void 0 : product.order_detail_id) === null)
    return null;
  const value = (bundle == null ? void 0 : bundle.surcharge_fee) ?? ((_a = bundle == null ? void 0 : bundle.metadata) == null ? void 0 : _a.surcharge_fee);
  if (value === void 0 || value === null || value === "")
    return null;
  return toDecimal(value);
}
function createSurchargeAllocationNodes(products, sourceItems) {
  var _a;
  const nodes = [];
  for (let productIndex = 0; productIndex < products.length; productIndex++) {
    const product = products[productIndex];
    const sourceItem = sourceItems[productIndex] || {};
    const productQuantity = new import_decimal.default(getSafeNum(product.num));
    for (let bundleIndex = 0; bundleIndex < (product.product_bundle || []).length; bundleIndex++) {
      const bundle = product.product_bundle[bundleIndex];
      if (!isBundleOriginalPrice(bundle))
        continue;
      const sourceBundle = ((_a = sourceItem == null ? void 0 : sourceItem.bundle) == null ? void 0 : _a[bundleIndex]) || {};
      nodes.push({
        kind: "bundle",
        target: bundle,
        source: sourceBundle,
        productId: getBundleProductId(bundle),
        unitAmount: getBundleSurchargeUnitAmount(bundle),
        quantity: new import_decimal.default(getSafeNum((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity))).times(productQuantity),
        persistedQuantity: getPersistedQuantity(bundle, new import_decimal.default(getSafeNum((bundle == null ? void 0 : bundle.num) ?? (bundle == null ? void 0 : bundle.quantity))).times(productQuantity)),
        relationSurchargeIds: getRelationSurchargeIds(sourceBundle).length ? getRelationSurchargeIds(sourceBundle) : getRelationSurchargeIds(bundle),
        persistedUnitSurchargeFee: getPersistedBundleSurchargeFee(bundle, product),
        persistedSurchargeRemainder: getPersistedSurchargeRemainder(bundle, sourceBundle)
      });
    }
    nodes.push({
      kind: "main",
      target: product,
      source: sourceItem,
      productId: product.product_id ?? null,
      unitAmount: getMainSurchargeUnitAmount(product),
      quantity: productQuantity,
      persistedQuantity: getPersistedQuantity(product, productQuantity),
      relationSurchargeIds: getRelationSurchargeIds(sourceItem).length ? getRelationSurchargeIds(sourceItem) : getRelationSurchargeIds(product),
      persistedUnitSurchargeFee: getPersistedSourceSurchargeFee(sourceItem) ?? getPersistedMainSurchargeFee(product),
      persistedSurchargeRemainder: getPersistedSurchargeRemainder(product, sourceItem)
    });
  }
  return nodes;
}
function resetProductSurchargeFields(products) {
  for (const product of products) {
    product.surcharge_fee = 0;
    product.main_product_attached_bundle_surcharge_fee = "0.00";
    product.surcharge_rounding_remainder = 0;
    product.relation_surcharge_ids = [];
    for (const bundle of product.product_bundle || []) {
      bundle.surcharge_fee = 0;
      bundle.relation_surcharge_ids = [];
      bundle.metadata = {
        ...bundle.metadata || {},
        surcharge_fee: "0.00",
        surcharge_rounding_remainder: "0.00",
        relation_surcharge_ids: []
      };
    }
  }
}
function getPersistedSurchargeIds(nodes) {
  const ids = /* @__PURE__ */ new Set();
  for (const node of nodes) {
    if (!node.persistedUnitSurchargeFee || node.persistedUnitSurchargeFee.lte(0))
      continue;
    for (const surchargeId of node.relationSurchargeIds) {
      ids.add(surchargeId);
    }
  }
  return ids;
}
function buildSurchargeQuantityTotals(nodes) {
  const totals = /* @__PURE__ */ new Map();
  for (const node of nodes) {
    for (const surchargeId of node.relationSurchargeIds) {
      totals.set(
        surchargeId,
        (totals.get(surchargeId) || new import_decimal.default(0)).plus(node.quantity)
      );
    }
  }
  return totals;
}
function getFallbackAllProductSurchargeIds(surchargeList) {
  return (surchargeList || []).reduce((ids, config) => {
    const id = getSurchargeConfigId(config);
    if (id === void 0)
      return ids;
    if (Number(config.open_product ?? 0) === 0)
      return ids;
    if (Number(config.is_all ?? 0) !== 1)
      return ids;
    ids.push(id);
    return ids;
  }, []);
}
function getBackendSurchargeState(stateMap, surchargeId, config) {
  let state = stateMap.get(surchargeId);
  if (!state) {
    state = {
      config,
      amount: new import_decimal.default(0),
      totalOffsetFee: new import_decimal.default(0),
      calculatedQuantity: new import_decimal.default(0),
      fixedIncluded: false,
      fixedRemainderAssigned: false
    };
    stateMap.set(surchargeId, state);
  }
  return state;
}
function buildSurchargeResultItem(config, surchargeId, amount, index) {
  const name = (config == null ? void 0 : config.name) || (config == null ? void 0 : config.label) || {};
  return {
    key: `custom_surcharge_${index}`,
    label: name,
    name,
    value: amount.toNumber(),
    surcharge_id: surchargeId,
    description: config == null ? void 0 : config.description,
    type: "default",
    fixed: config == null ? void 0 : config.fixed,
    amount: amount.toNumber(),
    percentage: config == null ? void 0 : config.percentage,
    metadata: {
      open_product: config == null ? void 0 : config.open_product
    }
  };
}
function applySurchargeNodeResult(node, params) {
  const { unitSurchargeFee, roundingRemainder, surchargeIds } = params;
  if (node.kind === "main") {
    node.target.surcharge_fee = unitSurchargeFee.toNumber();
    node.target.main_product_attached_bundle_surcharge_fee = toFixed2(unitSurchargeFee);
    node.target.surcharge_rounding_remainder = roundingRemainder.toNumber();
    node.target.relation_surcharge_ids = surchargeIds;
    return;
  }
  node.target.surcharge_fee = unitSurchargeFee.toNumber();
  node.target.relation_surcharge_ids = surchargeIds;
  node.target.metadata = {
    ...node.target.metadata || {},
    surcharge_fee: toFixed2(unitSurchargeFee),
    surcharge_rounding_remainder: toFixed2(roundingRemainder),
    relation_surcharge_ids: surchargeIds
  };
}
function calculateBackendProductSurcharges(params) {
  const { products, sourceItems, surchargeList } = params;
  resetProductSurchargeFields(products);
  const configById = getSurchargeConfigById(surchargeList);
  const nodes = createSurchargeAllocationNodes(products, sourceItems);
  const fallbackAllProductSurchargeIds = getFallbackAllProductSurchargeIds(surchargeList);
  for (const node of nodes) {
    if (node.relationSurchargeIds.length === 0) {
      node.relationSurchargeIds = fallbackAllProductSurchargeIds;
    }
  }
  const persistedSurchargeIds = getPersistedSurchargeIds(nodes);
  const quantityTotals = buildSurchargeQuantityTotals(nodes);
  const stateMap = /* @__PURE__ */ new Map();
  for (const node of nodes) {
    let unitSurchargeFee = new import_decimal.default(0);
    let roundingRemainder = new import_decimal.default(0);
    const appliedSurchargeIds = [];
    let persistedRemainderApplied = false;
    for (const surchargeId of node.relationSurchargeIds) {
      const config = configById.get(surchargeId);
      const totalQuantity = quantityTotals.get(surchargeId) || new import_decimal.default(0);
      if (totalQuantity.lte(0))
        continue;
      const persistedUnitSurchargeFee = node.persistedUnitSurchargeFee;
      if (persistedUnitSurchargeFee && persistedUnitSurchargeFee.gt(0)) {
        const persistedQuantity = import_decimal.default.min(node.persistedQuantity, node.quantity);
        const deltaQuantity = import_decimal.default.max(node.quantity.minus(persistedQuantity), 0);
        const state2 = getBackendSurchargeState(
          stateMap,
          surchargeId,
          config || { surcharge_id: surchargeId }
        );
        const persistedSurchargeRemainder = !persistedRemainderApplied && node.persistedSurchargeRemainder ? node.persistedSurchargeRemainder : new import_decimal.default(0);
        state2.amount = bcAdd(
          bcAdd(
            state2.amount,
            bcMul(persistedUnitSurchargeFee, persistedQuantity, 2),
            2
          ),
          persistedSurchargeRemainder,
          2
        );
        const fixed2 = new import_decimal.default((config == null ? void 0 : config.fixed) || 0);
        if (fixed2.gt(0))
          state2.fixedIncluded = true;
        let nodeTotalSurcharge = bcAdd(
          bcMul(persistedUnitSurchargeFee, persistedQuantity, 2),
          persistedSurchargeRemainder,
          2
        );
        if (config && deltaQuantity.gt(0)) {
          const percentage2 = new import_decimal.default(config.percentage || 0);
          const deltaUnitPercentageFee = import_decimal.default.max(0, bcMul(node.unitAmount, percentage2, 2));
          const deltaSurcharge = bcMul(deltaQuantity, deltaUnitPercentageFee, 2);
          state2.amount = bcAdd(state2.amount, deltaSurcharge, 2);
          nodeTotalSurcharge = bcAdd(nodeTotalSurcharge, deltaSurcharge, 2);
        }
        if (node.quantity.gt(0)) {
          unitSurchargeFee = bcAdd(unitSurchargeFee, bcDiv(nodeTotalSurcharge, node.quantity, 2), 2);
        }
        if (!persistedSurchargeRemainder.eq(0)) {
          roundingRemainder = bcAdd(roundingRemainder, persistedSurchargeRemainder, 2);
          persistedRemainderApplied = true;
        }
        appliedSurchargeIds.push(surchargeId);
        continue;
      }
      if (!config)
        continue;
      const percentage = new import_decimal.default(config.percentage || 0);
      const fixed = new import_decimal.default(config.fixed || 0);
      const unitPercentageFee = import_decimal.default.max(0, bcMul(node.unitAmount, percentage, 2));
      const percentageTotalFee = bcMul(node.quantity, unitPercentageFee, 2);
      let unitFixedFee = new import_decimal.default(0);
      let fixedRemainder = new import_decimal.default(0);
      if (fixed.gt(0) && !persistedSurchargeIds.has(surchargeId)) {
        unitFixedFee = bcDiv(fixed, totalQuantity, 2);
        const distributedFixed = bcMul(unitFixedFee, totalQuantity, 2);
        fixedRemainder = bcSub(fixed, distributedFixed, 2);
      }
      const currentUnitSurcharge = import_decimal.default.max(
        0,
        bcAdd(unitPercentageFee, unitFixedFee, 2)
      );
      if (currentUnitSurcharge.lte(0))
        continue;
      const state = getBackendSurchargeState(stateMap, surchargeId, config);
      state.amount = bcAdd(state.amount, percentageTotalFee, 2);
      const precisePercentage = import_decimal.default.max(0, bcMul(node.unitAmount, percentage, 6));
      const offsetBaseFee = import_decimal.default.max(0, bcSub(precisePercentage, unitPercentageFee, 6));
      state.totalOffsetFee = bcAdd(
        state.totalOffsetFee,
        bcMul(offsetBaseFee, node.quantity, 6),
        6
      );
      state.calculatedQuantity = bcAdd(state.calculatedQuantity, node.quantity, 6);
      if (!state.fixedIncluded && fixed.gt(0) && !persistedSurchargeIds.has(surchargeId)) {
        state.amount = bcAdd(state.amount, fixed, 2);
        state.fixedIncluded = true;
      }
      if (!state.fixedRemainderAssigned && !fixedRemainder.eq(0)) {
        state.fixedRemainderAssigned = true;
        roundingRemainder = bcAdd(roundingRemainder, fixedRemainder, 2);
      }
      if (state.calculatedQuantity.gte(totalQuantity) && state.totalOffsetFee.gt(0)) {
        const totalOffsetFee = toAmountFormat(state.totalOffsetFee);
        state.amount = bcAdd(state.amount, totalOffsetFee, 2);
        roundingRemainder = bcAdd(roundingRemainder, totalOffsetFee, 2);
        state.totalOffsetFee = new import_decimal.default(0);
      }
      unitSurchargeFee = bcAdd(unitSurchargeFee, currentUnitSurcharge, 2);
      appliedSurchargeIds.push(surchargeId);
    }
    applySurchargeNodeResult(node, {
      unitSurchargeFee,
      roundingRemainder,
      surchargeIds: appliedSurchargeIds
    });
  }
  const result = (surchargeList || []).reduce((items, config, index) => {
    const surchargeId = getSurchargeConfigId(config);
    if (surchargeId === void 0)
      return items;
    const state = stateMap.get(surchargeId);
    if (!state || state.amount.lte(0))
      return items;
    items.push(buildSurchargeResultItem(config, surchargeId, state.amount, index));
    return items;
  }, []);
  const includedIds = new Set(
    result.map((item) => item == null ? void 0 : item.surcharge_id).filter((id) => id !== void 0)
  );
  for (const [surchargeId, state] of stateMap.entries()) {
    if (includedIds.has(surchargeId) || state.amount.lte(0))
      continue;
    result.push(buildSurchargeResultItem(state.config, surchargeId, state.amount, result.length));
  }
  return result;
}
function getProductDepositData(product) {
  var _a, _b, _c;
  const rootDepositData = (_a = product._origin) == null ? void 0 : _a.custom_deposit_data;
  if (rootDepositData && typeof rootDepositData === "object")
    return rootDepositData;
  const nestedDepositData = (_c = (_b = product._origin) == null ? void 0 : _b.product) == null ? void 0 : _c.custom_deposit_data;
  if (nestedDepositData && typeof nestedDepositData === "object")
    return nestedDepositData;
  return void 0;
}
function collectDepositPolicyIds(depositData) {
  const rawIds = [
    ...Array.isArray(depositData == null ? void 0 : depositData.self_deposit_policy_ids) ? depositData.self_deposit_policy_ids : [],
    ...Array.isArray(depositData == null ? void 0 : depositData.deposit_policy_ids) ? depositData.deposit_policy_ids : []
  ];
  return rawIds.reduce((result, id) => {
    const normalizedId = Number(id);
    if (!Number.isFinite(normalizedId))
      return result;
    result.push(Math.floor(normalizedId));
    return result;
  }, []);
}
function collectDepositPolicyData(depositData) {
  const rawPolicyData = Array.isArray(depositData == null ? void 0 : depositData.deposit_policy_data) ? depositData.deposit_policy_data : [];
  return rawPolicyData.reduce((result, policy) => {
    const normalizedId = Number(policy == null ? void 0 : policy.id);
    if (!Number.isFinite(normalizedId))
      return result;
    result.push({
      id: Math.floor(normalizedId),
      title: String((policy == null ? void 0 : policy.title) || "")
    });
    return result;
  }, []);
}
function calculateProductsDeposit(products) {
  let totalDeposit = new import_decimal.default(0);
  let hasDeposit = false;
  const policyIds = /* @__PURE__ */ new Set();
  const policyDataMap = /* @__PURE__ */ new Map();
  for (const product of products) {
    const depositData = getProductDepositData(product);
    if (!depositData || depositData.has_deposit != 1)
      continue;
    const num = getSafeNum(product.num);
    const unitTotal = getUnitPaymentTotal(product);
    const productTotal = unitTotal.times(num);
    const { deposit_fixed, deposit_percentage } = depositData;
    const fixed = toDecimal(deposit_fixed);
    const percentage = toDecimal(deposit_percentage);
    const itemDeposit = fixed.plus(percentage.times(productTotal));
    totalDeposit = totalDeposit.plus(itemDeposit);
    hasDeposit = true;
    for (const id of collectDepositPolicyIds(depositData)) {
      policyIds.add(id);
    }
    for (const policy of collectDepositPolicyData(depositData)) {
      if (!policyDataMap.has(policy.id)) {
        policyDataMap.set(policy.id, policy);
      }
      policyIds.add(policy.id);
    }
  }
  if (!hasDeposit)
    return void 0;
  for (const id of policyIds) {
    if (!policyDataMap.has(id)) {
      policyDataMap.set(id, {
        id,
        title: ""
      });
    }
  }
  return {
    total: totalDeposit.toFixed(2),
    deposit_policy_ids: [...policyIds],
    deposit_policy_data: [...policyDataMap.values()],
    hasDeposit: true
  };
}
function isBundleOriginalPrice(item) {
  return (item == null ? void 0 : item.price_type) === "markup" && (item == null ? void 0 : item.price_type_ext) === "product_price";
}
function isBundleMarkupOrDiscount(item) {
  const isMarkup = (item == null ? void 0 : item.price_type) === "markup" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
  const isDiscount = (item == null ? void 0 : item.price_type) === "markdown" && ((item == null ? void 0 : item.price_type_ext) === "" || !(item == null ? void 0 : item.price_type_ext));
  return isMarkup || isDiscount;
}
function calculateSingleItemTax(params) {
  const { price, taxRate, isPriceIncludeTax, isChargeTax } = params;
  if (price.lte(0))
    return new import_decimal.default(0);
  if (isChargeTax === 0 || !isChargeTax)
    return new import_decimal.default(0);
  const rate = taxRate.div(100);
  if (isPriceIncludeTax === 0) {
    return price.times(rate);
  }
  const divisor = new import_decimal.default(1).plus(rate);
  if (divisor.lte(0))
    return new import_decimal.default(0);
  return price.dividedBy(divisor).times(rate);
}
function getMainAttachedBundleSellingTotal(product) {
  var _a, _b;
  const mainSelling = ((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? ((_b = product.metadata) == null ? void 0 : _b.main_product_original_price) ?? 0;
  let total = toDecimal(mainSelling);
  const bundleItems = product.product_bundle || [];
  for (const bundleItem of bundleItems) {
    if (isBundleMarkupOrDiscount(bundleItem)) {
      const unit = (0, import_utils2.getBundleSignedUnit)(bundleItem);
      const qty = getSafeNum(bundleItem.num ?? bundleItem.quantity);
      total = total.plus(unit.times(qty));
    }
  }
  return import_decimal.default.max(total, 0);
}
function getMainProductPaymentTotal(product) {
  var _a;
  const attachedPayment = (_a = product.metadata) == null ? void 0 : _a.main_product_attached_bundle_payment_price;
  if (attachedPayment !== void 0 && attachedPayment !== null && attachedPayment !== "") {
    return import_decimal.default.max(toDecimal(attachedPayment), 0);
  }
  return getMainAttachedBundleSellingTotal(product);
}
function getExplicitTaxRemainder(item) {
  var _a;
  const value = (item == null ? void 0 : item.tax_fee_rounding_remainder) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.tax_fee_rounding_remainder);
  if (value === void 0 || value === null || value === "")
    return null;
  return new import_decimal.default(value || 0);
}
function getPersistedTaxRemainder(item, parentProduct) {
  const isPersistedLine = (item == null ? void 0 : item.order_detail_id) !== void 0 && (item == null ? void 0 : item.order_detail_id) !== null || (parentProduct == null ? void 0 : parentProduct.order_detail_id) !== void 0 && (parentProduct == null ? void 0 : parentProduct.order_detail_id) !== null;
  if (!isPersistedLine)
    return null;
  return getExplicitTaxRemainder(item);
}
function getPersistedMainTaxFee(product) {
  var _a;
  if ((product == null ? void 0 : product.order_detail_id) === void 0 || (product == null ? void 0 : product.order_detail_id) === null)
    return null;
  const value = ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.main_product_attached_bundle_tax_fee) ?? (product == null ? void 0 : product.main_product_attached_bundle_tax_fee) ?? (product == null ? void 0 : product.tax_fee);
  if (value === void 0 || value === null || value === "")
    return null;
  return toDecimal(value);
}
function writeTaxRemainder(item, roundingRemainder) {
  item.tax_fee_rounding_remainder = roundingRemainder.toNumber();
  if (item.metadata && typeof item.metadata === "object") {
    item.metadata.tax_fee_rounding_remainder = roundingRemainder.toFixed(2);
  }
}
function resetTaxRemainderFields(products) {
  for (const product of products) {
    const productRemainder = getPersistedTaxRemainder(product);
    if (productRemainder !== null) {
      product.tax_fee_rounding_remainder = productRemainder.toNumber();
    } else {
      delete product.tax_fee_rounding_remainder;
    }
    product.original_tax_fee_rounding_remainder = 0;
    for (const bundle of product.product_bundle || []) {
      const bundleRemainder = getPersistedTaxRemainder(bundle, product);
      bundle.metadata = {
        ...bundle.metadata || {}
      };
      if (bundleRemainder !== null) {
        bundle.metadata.tax_fee_rounding_remainder = bundleRemainder.toFixed(2);
        bundle.tax_fee_rounding_remainder = bundleRemainder.toNumber();
      } else {
        delete bundle.metadata.tax_fee_rounding_remainder;
        delete bundle.tax_fee_rounding_remainder;
      }
      bundle.original_tax_fee_rounding_remainder = 0;
    }
  }
}
function getBundlePaymentPrice(bundle, product) {
  var _a;
  if ((bundle == null ? void 0 : bundle.bundle_payment_price) !== void 0)
    return toDecimal(bundle.bundle_payment_price);
  const basePrice = toDecimal((bundle == null ? void 0 : bundle.bundle_selling_price) ?? (bundle == null ? void 0 : bundle.bundle_sum_price) ?? (bundle == null ? void 0 : bundle.price) ?? 0);
  if (!isBundleOriginalPrice(bundle))
    return basePrice;
  const averageDiscountRate = toDecimal(
    ((_a = product.metadata) == null ? void 0 : _a.average_discount_amount_rate) ?? 1
  );
  return toAmountFormat(bcMul(basePrice, averageDiscountRate, 6));
}
function applyBackendTaxRemainder(params) {
  const { target, rawTax, formattedTax, quantity, state } = params;
  const taxFeeDifference = bcMul(
    bcSub(rawTax, formattedTax, 6),
    quantity,
    6
  );
  state.difference = bcAdd(state.difference, taxFeeDifference, 6);
  if (state.difference.lt(5e-3))
    return new import_decimal.default(0);
  const roundingRemainder = toAmountFormat(state.difference);
  writeTaxRemainder(target, roundingRemainder);
  state.difference = bcSub(state.difference, roundingRemainder, 6);
  return roundingRemainder;
}
function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
  const rate = new import_decimal.default(taxRate);
  const taxRemainderState = { difference: new import_decimal.default(0) };
  let totalTax = new import_decimal.default(0);
  let totalOriginTax = new import_decimal.default(0);
  resetTaxRemainderFields(products);
  for (const product of products) {
    const quantity = new import_decimal.default(getSafeNum(product.num));
    let productUnitTax = new import_decimal.default(0);
    let productUnitOriginTax = new import_decimal.default(0);
    const bundleItems = product.product_bundle || [];
    for (const bundleItem of bundleItems) {
      if (!isBundleOriginalPrice(bundleItem))
        continue;
      const bundleQuantity = new import_decimal.default(getSafeNum(bundleItem.num ?? bundleItem.quantity));
      const totalBundleQuantity = bundleQuantity.times(quantity);
      const bundlePrice = getBundlePaymentPrice(bundleItem, product);
      const bundleOriginalPrice = toDecimal(bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? 0);
      const bundleSurchargeFee = toDecimal(bundleItem.surcharge_fee);
      const bundleTaxPrecise = calculateSingleItemTax({
        price: bundlePrice.plus(bundleSurchargeFee),
        taxRate: rate,
        isPriceIncludeTax,
        isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
      });
      const bundleTaxRounded = toBackendTaxFee(bundleTaxPrecise);
      bundleItem.tax_fee = bundleTaxRounded.toNumber();
      const persistedBundleRemainder = getPersistedTaxRemainder(bundleItem, product);
      const bundleRemainder = persistedBundleRemainder ?? applyBackendTaxRemainder({
        target: bundleItem,
        rawTax: bundleTaxPrecise,
        formattedTax: bundleTaxRounded,
        quantity: totalBundleQuantity,
        state: taxRemainderState
      });
      if (persistedBundleRemainder)
        writeTaxRemainder(bundleItem, persistedBundleRemainder);
      const bundleOrigTaxPrecise = calculateSingleItemTax({
        price: bundleOriginalPrice.plus(bundleSurchargeFee),
        taxRate: rate,
        isPriceIncludeTax,
        isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
      });
      const bundleOrigTaxRounded = toAmountFormat(bundleOrigTaxPrecise);
      bundleItem.original_tax_fee = bundleOrigTaxRounded.toNumber();
      productUnitTax = productUnitTax.plus(bundleTaxRounded.times(bundleQuantity));
      productUnitOriginTax = productUnitOriginTax.plus(bundleOrigTaxRounded.times(bundleQuantity));
      totalTax = totalTax.plus(bundleTaxRounded.times(totalBundleQuantity)).plus(bundleRemainder);
      totalOriginTax = totalOriginTax.plus(bundleOrigTaxRounded.times(totalBundleQuantity));
    }
    const mainTotal = getMainProductPaymentTotal(product);
    const surchargeFee = toDecimal(product.surcharge_fee);
    const mainTaxableBase = mainTotal.lte(0) ? surchargeFee : mainTotal.plus(surchargeFee);
    const mainTaxPrecise = calculateSingleItemTax({
      price: mainTaxableBase,
      taxRate: rate,
      isPriceIncludeTax,
      isChargeTax: product.is_charge_tax ?? 0
    });
    const mainTaxRounded = toBackendTaxFee(mainTaxPrecise);
    const persistedMainRemainder = getPersistedTaxRemainder(product);
    const persistedMainTaxFee = getPersistedMainTaxFee(product);
    const persistedQuantity = getPersistedQuantity(product, quantity);
    const deltaQuantity = import_decimal.default.max(quantity.minus(persistedQuantity), 0);
    const shouldUsePersistedMainTax = persistedMainTaxFee && persistedMainTaxFee.gt(0) && persistedQuantity.gte(quantity);
    const shouldSplitPersistedMainTax = persistedMainTaxFee && persistedMainTaxFee.gt(0) && persistedQuantity.gt(0) && deltaQuantity.gt(0);
    const mainRemainder = shouldUsePersistedMainTax || shouldSplitPersistedMainTax ? new import_decimal.default(0) : persistedMainRemainder ?? applyBackendTaxRemainder({
      target: product,
      rawTax: mainTaxPrecise,
      formattedTax: mainTaxRounded,
      quantity,
      state: taxRemainderState
    });
    if (persistedMainRemainder && !shouldSplitPersistedMainTax) {
      writeTaxRemainder(product, persistedMainRemainder);
    }
    const originalTotal = getUnitOriginalTotal(product);
    const originalTaxableBase = originalTotal.lte(0) ? surchargeFee : originalTotal.plus(surchargeFee);
    const originalTaxPrecise = calculateSingleItemTax({
      price: originalTaxableBase,
      taxRate: rate,
      isPriceIncludeTax,
      isChargeTax: product.is_charge_tax ?? 0
    });
    const originalTaxRounded = toAmountFormat(originalTaxPrecise);
    const effectiveMainUnitTax = shouldUsePersistedMainTax ? persistedMainTaxFee : shouldSplitPersistedMainTax ? persistedMainTaxFee.times(persistedQuantity).plus(mainTaxRounded.times(deltaQuantity)).div(quantity).toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP) : mainTaxRounded;
    productUnitTax = productUnitTax.plus(effectiveMainUnitTax);
    productUnitOriginTax = productUnitOriginTax.plus(originalTaxRounded);
    product.main_product_attached_bundle_tax_fee = effectiveMainUnitTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
    product.tax_fee = productUnitTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
    product.original_tax_fee = productUnitOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
    totalTax = totalTax.plus(
      shouldUsePersistedMainTax ? persistedMainTaxFee.times(quantity).plus(persistedMainRemainder || 0) : shouldSplitPersistedMainTax ? persistedMainTaxFee.times(persistedQuantity).plus(mainTaxRounded.times(deltaQuantity)) : mainTaxRounded.times(quantity).plus(mainRemainder)
    );
    totalOriginTax = totalOriginTax.plus(originalTaxRounded.times(quantity));
    if (product.tax_fee_rounding_remainder === void 0) {
      product.tax_fee_rounding_remainder = 0;
    }
  }
  return {
    tax: totalTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP),
    originTax: totalOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP)
  };
}
function allocateShopDiscountToPayment(products, productAmount, shopDiscountAmount) {
  const effectiveDiscount = productAmount.lte(0) ? new import_decimal.default(0) : import_decimal.default.max(import_decimal.default.min(productAmount, shopDiscountAmount), 0);
  let allocatedDiscount = new import_decimal.default(0);
  products.forEach((product, index) => {
    const quantity = new import_decimal.default(getSafeNum(product.num));
    const sellingUnit = getUnitPaymentTotal(product);
    const lineSellingTotal = sellingUnit.times(quantity);
    const lineDiscount = effectiveDiscount.lte(0) ? new import_decimal.default(0) : index === products.length - 1 ? import_decimal.default.max(effectiveDiscount.minus(allocatedDiscount), 0) : toAmountFormat(lineSellingTotal.div(productAmount).times(effectiveDiscount));
    allocatedDiscount = allocatedDiscount.plus(lineDiscount);
    const unitDiscount = quantity.lte(0) ? new import_decimal.default(0) : lineDiscount.div(quantity);
    const paymentUnit = import_decimal.default.max(sellingUnit.minus(unitDiscount), 0);
    const rate = sellingUnit.lte(0) ? new import_decimal.default(1) : toBcScale(paymentUnit.div(sellingUnit), 6);
    const mainSellingTotal = getMainAttachedBundleSellingTotal(product);
    const mainPaymentTotal = toAmountFormat(bcMul(mainSellingTotal, rate, 6));
    product.metadata = {
      ...product.metadata || {},
      average_discount_amount_rate: rate.toString(),
      main_product_attached_bundle_selling_price: mainSellingTotal.toFixed(2),
      main_product_attached_bundle_payment_price: mainPaymentTotal.toFixed(2)
    };
    for (const bundle of product.product_bundle || []) {
      if (isBundleOriginalPrice(bundle)) {
        const bundleSelling = toDecimal(
          bundle.bundle_selling_price ?? bundle.bundle_sum_price ?? bundle.price ?? 0
        );
        bundle.bundle_payment_price = toAmountFormat(bcMul(bundleSelling, rate, 6)).toFixed(2);
        continue;
      }
      if ((0, import_utils2.isMarkdownBundle)(bundle)) {
        const magnitude = (0, import_utils2.getBundleSellingMagnitude)(bundle);
        bundle.custom_price = bundle.custom_price ?? bundle.price;
        bundle.price = magnitude.toFixed(2);
        bundle.bundle_selling_price = magnitude.toFixed(2);
        bundle.bundle_payment_price = toAmountFormat(bcMul(magnitude, rate, 6)).toFixed(2);
      }
    }
    product.payment_price = paymentUnit.toFixed(2);
  });
}
function createEmptySalesSummary() {
  return {
    product_quantity: 0,
    product_original_amount: "0.00",
    product_amount: "0.00",
    product_expect_amount: "0.00",
    product_tax_fee: "0.00",
    shipping_fee: "0.00",
    shipping_tax_fee: "0.00",
    tax_fee: "0.00",
    surcharge_fee: "0.00",
    surcharges: [],
    discount_amount: "0.00",
    deposit_amount: "0.00",
    expect_amount: "0.00",
    total_amount: "0.00",
    total_refund_amount: "0.00",
    customer_paid_amount: "0.00",
    order_paid_amount: "0.00",
    amount_gap: "0.00",
    rounding_amount: "0.00",
    pay_service_charge_amount: "0.00"
  };
}
function calculateSalesSummary(params) {
  const {
    products,
    isPriceIncludeTax,
    taxRate,
    surchargeList,
    scheduleById = {},
    isInScheduleByDate,
    shopDiscount
  } = params;
  if (!(products == null ? void 0 : products.length))
    return createEmptySalesSummary();
  const summaryProducts = products.filter((product) => !isGeneratedVoucherProduct(product));
  if (!summaryProducts.length)
    return createEmptySalesSummary();
  const productQuantity = summaryProducts.reduce(
    (sum, item) => sum + getSafeNum(item.num),
    0
  );
  const productOriginalAmount = summaryProducts.reduce(
    (sum, item) => sum.plus(getUnitOriginalTotal(item).times(getSafeNum(item.num))),
    new import_decimal.default(0)
  );
  const productAmount = summaryProducts.reduce(
    (sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))),
    new import_decimal.default(0)
  );
  const shopDiscountAmount = import_decimal.default.max(new import_decimal.default(Number(shopDiscount) || 0), 0);
  const hasPersistedSurchargeSnapshot = summaryProducts.some((product) => {
    var _a;
    return (_a = getPersistedMainSurchargeFee(product)) == null ? void 0 : _a.gt(0);
  });
  if (!hasPersistedSurchargeSnapshot) {
    allocateShopDiscountToPayment(summaryProducts, productAmount, shopDiscountAmount);
  }
  const surchargeServiceItems = buildSurchargeServiceItems(summaryProducts);
  (0, import_utils.getSurcharge)(
    {
      service: surchargeServiceItems,
      addons: [],
      bookingDetail: null,
      bookingId: void 0
    },
    {
      isEdit: false,
      isInScheduleByDate,
      surcharge_list: surchargeList,
      scheduleById
    }
  );
  const surcharge = calculateBackendProductSurcharges({
    products: summaryProducts,
    sourceItems: surchargeServiceItems,
    surchargeList
  });
  const surchargeAmount = new import_decimal.default(
    (0, import_utils.getSurchargeAmount)(
      { bookingDetail: null, bookingId: void 0 },
      surcharge,
      { isEdit: false }
    ) || 0
  );
  const hasTaxRate = taxRate !== void 0 && taxRate !== null && taxRate > 0;
  let productTaxFee;
  if (hasTaxRate) {
    const taxResult = calculateProductsTax(summaryProducts, taxRate, isPriceIncludeTax);
    productTaxFee = taxResult.tax;
  } else {
    productTaxFee = summaryProducts.reduce(
      (sum, item) => sum.plus(toDecimal(item.tax_fee).times(getSafeNum(item.num))),
      new import_decimal.default(0)
    );
  }
  const orderAmountBeforeDiscount = productAmount.plus(surchargeAmount).plus(isPriceIncludeTax === 1 ? 0 : productTaxFee);
  const totalAmount = import_decimal.default.max(0, orderAmountBeforeDiscount.minus(shopDiscountAmount));
  const deposit = calculateProductsDeposit(summaryProducts);
  return {
    product_quantity: productQuantity,
    product_original_amount: toFixed2(productOriginalAmount),
    product_amount: toFixed2(productAmount),
    product_expect_amount: toFixed2(productAmount),
    product_tax_fee: toFixed2(productTaxFee),
    shipping_fee: "0.00",
    shipping_tax_fee: "0.00",
    tax_fee: toFixed2(productTaxFee),
    surcharge_fee: toFixed2(surchargeAmount),
    surcharges: surcharge,
    discount_amount: toFixed2(shopDiscountAmount),
    deposit_amount: deposit ? deposit.total : "0.00",
    deposit,
    expect_amount: toFixed2(totalAmount),
    total_amount: toFixed2(totalAmount),
    total_refund_amount: "0.00",
    customer_paid_amount: "0.00",
    order_paid_amount: "0.00",
    amount_gap: "0.00",
    rounding_amount: "0.00",
    pay_service_charge_amount: "0.00",
    is_price_include_tax: isPriceIncludeTax
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  calculateSalesSummary,
  createEmptySalesSummary
});
