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");
function toDecimal(value) {
  return new import_decimal.default(value || 0);
}
function toFixed2(value) {
  return new import_decimal.default(value || 0).toFixed(2);
}
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 price = useOriginal ? toDecimal((item == null ? void 0 : item.original_price) ?? (item == null ? void 0 : item.product_price) ?? (item == null ? void 0 : item.price)) : toDecimal((item == null ? void 0 : item.bundle_selling_price) ?? (item == null ? void 0 : item.price));
    return sum.plus(price.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 buildSurchargeServiceItems(products) {
  return products.map((product) => {
    var _a, _b;
    const quantity = getSafeNum(product.num);
    const unitTotal = getUnitPaymentTotal(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_option_item: product.product_option_item || []
        }
      },
      bundle: product.product_bundle || [],
      option: product.product_option_item || [],
      options: product.product_option_item || [],
      relation_details: [],
      metadata: product.metadata || {},
      start_date: ((_a = product.metadata) == null ? void 0 : _a.start_date) || "",
      start_time: ((_b = product.metadata) == null ? void 0 : _b.start_time) || ""
    };
  });
}
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 getMainProductPaymentTotal(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 = toDecimal(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
      const qty = getSafeNum(bundleItem.num ?? bundleItem.quantity);
      total = total.plus(unit.times(qty));
    }
  }
  return import_decimal.default.max(total, 0);
}
function calculateProductsTax(products, taxRate, isPriceIncludeTax) {
  const rate = new import_decimal.default(taxRate);
  let preciseTax = new import_decimal.default(0);
  let roundedTax = new import_decimal.default(0);
  let preciseOriginTax = new import_decimal.default(0);
  let roundedOriginTax = new import_decimal.default(0);
  let lastTaxableItem = null;
  for (const product of products) {
    const quantity = new import_decimal.default(getSafeNum(product.num));
    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 = mainTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
    if (mainTaxPrecise.gt(0)) {
      lastTaxableItem = { type: "main", item: product };
    }
    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
    });
    let bundlePreciseTax = new import_decimal.default(0);
    let bundleRoundedTax = new import_decimal.default(0);
    let bundlePreciseOriginTax = new import_decimal.default(0);
    let bundleRoundedOriginTax = 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 bundlePrice = toDecimal(bundleItem.bundle_selling_price ?? bundleItem.price ?? 0);
      const bundleOriginalPrice = toDecimal(bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? 0);
      const bundleTaxPrecise = calculateSingleItemTax({
        price: bundlePrice,
        taxRate: rate,
        isPriceIncludeTax,
        isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
      });
      const bundleTaxRounded = bundleTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
      const bundleOrigTaxPrecise = calculateSingleItemTax({
        price: bundleOriginalPrice,
        taxRate: rate,
        isPriceIncludeTax,
        isChargeTax: bundleItem.is_charge_tax ?? product.is_charge_tax ?? 0
      });
      const bundleOrigTaxRounded = bundleOrigTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
      bundleItem.tax_fee = bundleTaxRounded.toNumber();
      bundleItem.original_tax_fee = bundleOrigTaxRounded.toNumber();
      bundlePreciseTax = bundlePreciseTax.plus(bundleTaxPrecise.times(bundleQuantity));
      bundleRoundedTax = bundleRoundedTax.plus(bundleTaxRounded.times(bundleQuantity));
      bundlePreciseOriginTax = bundlePreciseOriginTax.plus(bundleOrigTaxPrecise.times(bundleQuantity));
      bundleRoundedOriginTax = bundleRoundedOriginTax.plus(bundleOrigTaxRounded.times(bundleQuantity));
      if (bundleTaxPrecise.gt(0)) {
        lastTaxableItem = { type: "bundle", item: bundleItem };
      }
    }
    const itemTaxPrecise = mainTaxPrecise.plus(bundlePreciseTax);
    const itemTaxRounded = mainTaxRounded.plus(bundleRoundedTax);
    const itemOriginTaxPrecise = originalTaxPrecise.plus(bundlePreciseOriginTax);
    const itemOriginTaxRounded = originalTaxPrecise.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).plus(bundleRoundedOriginTax);
    product.tax_fee = itemTaxRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toFixed(2);
    product.original_tax_fee = itemOriginTaxRounded.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP).toNumber();
    preciseTax = preciseTax.plus(itemTaxPrecise.times(quantity));
    roundedTax = roundedTax.plus(itemTaxRounded.times(quantity));
    preciseOriginTax = preciseOriginTax.plus(itemOriginTaxPrecise.times(quantity));
    roundedOriginTax = roundedOriginTax.plus(itemOriginTaxRounded.times(quantity));
  }
  const expectedTax = preciseTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
  const expectedOriginTax = preciseOriginTax.toDecimalPlaces(2, import_decimal.default.ROUND_HALF_UP);
  const taxRemainder = expectedTax.minus(roundedTax).toNumber();
  const originTaxRemainder = expectedOriginTax.minus(roundedOriginTax).toNumber();
  if (lastTaxableItem) {
    if (taxRemainder !== 0) {
      lastTaxableItem.item.tax_fee_rounding_remainder = taxRemainder;
    }
    if (originTaxRemainder !== 0) {
      lastTaxableItem.item.original_tax_fee_rounding_remainder = originTaxRemainder;
    }
  }
  return { tax: expectedTax, originTax: expectedOriginTax };
}
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) {
  var _a;
  const {
    products,
    isPriceIncludeTax,
    taxRate,
    surchargeList,
    scheduleById = {},
    isInScheduleByDate,
    shopDiscount
  } = params;
  if (!(products == null ? void 0 : products.length))
    return createEmptySalesSummary();
  const productQuantity = products.reduce(
    (sum, item) => sum + getSafeNum(item.num),
    0
  );
  const productOriginalAmount = products.reduce(
    (sum, item) => sum.plus(getUnitOriginalTotal(item).times(getSafeNum(item.num))),
    new import_decimal.default(0)
  );
  const productAmount = products.reduce(
    (sum, item) => sum.plus(getUnitPaymentTotal(item).times(getSafeNum(item.num))),
    new import_decimal.default(0)
  );
  const surchargeServiceItems = buildSurchargeServiceItems(products);
  const surcharge = (0, import_utils.getSurcharge)(
    {
      service: surchargeServiceItems,
      addons: [],
      bookingDetail: null,
      bookingId: void 0
    },
    {
      isEdit: false,
      isInScheduleByDate,
      surcharge_list: surchargeList,
      scheduleById
    }
  );
  const surchargeAmount = new import_decimal.default(
    (0, import_utils.getSurchargeAmount)(
      { bookingDetail: null, bookingId: void 0 },
      surcharge,
      { isEdit: false }
    ) || 0
  );
  for (let i = 0; i < products.length; i++) {
    products[i].surcharge_fee = ((_a = surchargeServiceItems[i]) == null ? void 0 : _a.surcharge_fee) || 0;
  }
  const hasTaxRate = taxRate !== void 0 && taxRate !== null && taxRate > 0;
  let productTaxFee;
  if (hasTaxRate) {
    const taxResult = calculateProductsTax(products, taxRate, isPriceIncludeTax);
    productTaxFee = taxResult.tax;
  } else {
    productTaxFee = products.reduce(
      (sum, item) => sum.plus(toDecimal(item.tax_fee).times(getSafeNum(item.num))),
      new import_decimal.default(0)
    );
  }
  const shopDiscountAmount = import_decimal.default.max(new import_decimal.default(Number(shopDiscount) || 0), 0);
  const expectAmount = import_decimal.default.max(0, productAmount.plus(surchargeAmount).minus(shopDiscountAmount));
  const totalAmount = isPriceIncludeTax === 1 ? expectAmount : expectAmount.plus(productTaxFee);
  const deposit = calculateProductsDeposit(products);
  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(
      import_decimal.default.max(productOriginalAmount.minus(productAmount), 0).plus(shopDiscountAmount)
    ),
    deposit_amount: deposit ? deposit.total : "0.00",
    deposit,
    expect_amount: toFixed2(expectAmount),
    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
});
