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); }
import dayjs from 'dayjs';
import Decimal from 'decimal.js';
function toFiniteNumber(value) {
  var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  var parsedValue = Number(value);
  if (!Number.isFinite(parsedValue)) return fallback;
  return parsedValue;
}
function toPositiveInt(value) {
  var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  var parsedValue = Math.floor(Number(value));
  if (!Number.isFinite(parsedValue) || parsedValue < 1) return fallback;
  return parsedValue;
}
function toPriceString(value) {
  return new Decimal(Number(value) || 0).toDecimalPlaces(2).toFixed(2);
}
function normalizeDateTime(value) {
  if (typeof value !== 'string' || !value.trim()) return null;
  var normalized = value.includes(':') ? value : "".concat(value, " 00:00:00");
  var datetime = dayjs(normalized);
  if (!datetime.isValid()) return null;
  return datetime;
}
function buildBookingDateTime(date, time) {
  if (typeof date !== 'string' || !date.trim()) return null;
  var timeText = typeof time === 'string' && time.trim() ? time.trim() : '00:00';
  var datetime = dayjs("".concat(date.trim(), " ").concat(timeText));
  if (!datetime.isValid()) return null;
  return datetime;
}
function getDurationUnit(type) {
  var normalizedType = String(type || '').toLowerCase();
  if (normalizedType === 'day' || normalizedType === 'days') return 'day';
  if (normalizedType === 'minute' || normalizedType === 'minutes') return 'minute';
  return null;
}
function getProductId(product) {
  var _product$product_id;
  var productId = toFiniteNumber((_product$product_id = product.product_id) !== null && _product$product_id !== void 0 ? _product$product_id : product.id, NaN);
  if (!Number.isFinite(productId)) return null;
  return productId;
}
function getProductVariantId(product) {
  var _product$product_vari;
  var variantId = toFiniteNumber((_product$product_vari = product.product_variant_id) !== null && _product$product_vari !== void 0 ? _product$product_vari : product.variant_id, 0);
  if (!Number.isFinite(variantId) || variantId <= 0) return undefined;
  return variantId;
}
function getFallbackPrice(params) {
  var _ref, _ref2, _ref3, _params$fallback_pric;
  var product = params.product || {};
  return toPriceString((_ref = (_ref2 = (_ref3 = (_params$fallback_pric = params.fallback_price) !== null && _params$fallback_pric !== void 0 ? _params$fallback_pric : product.price) !== null && _ref3 !== void 0 ? _ref3 : product.selling_price) !== null && _ref2 !== void 0 ? _ref2 : product.original_price) !== null && _ref !== void 0 ? _ref : 0);
}
function getProductQuantity(product) {
  var _product$num;
  return toPositiveInt((_product$num = product.num) !== null && _product$num !== void 0 ? _product$num : product.quantity, 1);
}
function getBundleProductId(bundle) {
  var _bundle$bundle_produc;
  var productId = toFiniteNumber((_bundle$bundle_produc = bundle.bundle_product_id) !== null && _bundle$bundle_produc !== void 0 ? _bundle$bundle_produc : bundle._bundle_product_id, NaN);
  if (!Number.isFinite(productId)) return null;
  return productId;
}
function getBundleVariantId(bundle) {
  var _bundle$bundle_varian;
  var variantId = toFiniteNumber((_bundle$bundle_varian = bundle.bundle_variant_id) !== null && _bundle$bundle_varian !== void 0 ? _bundle$bundle_varian : bundle.variant_id, 0);
  if (!Number.isFinite(variantId) || variantId <= 0) return undefined;
  return variantId;
}
function getBundleFallbackPrice(bundle) {
  var _ref4, _ref5, _ref6, _bundle$bundle_sellin;
  return toPriceString((_ref4 = (_ref5 = (_ref6 = (_bundle$bundle_sellin = bundle.bundle_selling_price) !== null && _bundle$bundle_sellin !== void 0 ? _bundle$bundle_sellin : bundle.price) !== null && _ref6 !== void 0 ? _ref6 : bundle.original_price) !== null && _ref5 !== void 0 ? _ref5 : bundle.base_price) !== null && _ref4 !== void 0 ? _ref4 : 0);
}
function shouldSplitByDuration(duration, start, end) {
  if (!duration) return false;
  if (!start || !end || !end.isAfter(start)) return false;
  var unit = getDurationUnit(duration.type);
  var value = toFiniteNumber(duration.value);
  return !!unit && value > 0;
}
function buildTimeSegments(params) {
  var booking = params.booking || {};
  var explicitDatetime = normalizeDateTime(params.datetime);
  var bookingStart = buildBookingDateTime(booking.start_date, booking.start_time);
  var start = bookingStart || explicitDatetime || dayjs();
  var bookingEnd = buildBookingDateTime(booking.end_date, booking.end_time);
  if (!shouldSplitByDuration(params.duration, start, bookingEnd)) {
    return [{
      start: start
    }];
  }
  var unit = getDurationUnit(params.duration.type);
  var value = toFiniteNumber(params.duration.value);
  var segments = [];
  var cursor = start;
  var guard = 0;
  while (cursor.isBefore(bookingEnd) && guard < 10000) {
    var next = cursor.add(value, unit);
    segments.push({
      start: cursor,
      end: next.isBefore(bookingEnd) ? next : bookingEnd !== null && bookingEnd !== void 0 ? bookingEnd : undefined
    });
    cursor = next;
    guard += 1;
  }
  return segments.length ? segments : [{
    start: start
  }];
}
function formatTimePoint(datetime) {
  return datetime.format('YYYY-MM-DD HH:mm:ss');
}
function buildPriceSegment(params) {
  var timePoint = formatTimePoint(params.segment.start);
  var quotedPrice = params.quotation && params.productId !== null ? params.quotation.getPriceForProduct({
    productId: params.productId,
    variantId: params.variantId,
    datetime: timePoint,
    customer_id: params.customerId
  }) : null;
  var unitPrice = toPriceString(quotedPrice !== null && quotedPrice !== void 0 ? quotedPrice : params.fallbackPrice);
  var quotationShelfId = quotedPrice !== null && params.quotation && params.productId !== null ? params.quotation.getQuotationShelfId({
    productId: params.productId,
    variantId: params.variantId,
    datetime: timePoint,
    customer_id: params.customerId
  }) : 0;
  return {
    start_datetime: timePoint,
    end_datetime: params.segment.end ? formatTimePoint(params.segment.end) : undefined,
    time_point: timePoint,
    unit_price: unitPrice,
    quantity: 1,
    total_price: unitPrice,
    quotation_shelf_id: quotationShelfId,
    source: quotedPrice !== null ? 'quotation' : 'fallback'
  };
}
function calculatePriceForProduct(params) {
  var _segments$find;
  var segments = params.segments.map(function (segment) {
    return buildPriceSegment({
      quotation: params.quotation,
      productId: params.productId,
      variantId: params.variantId,
      customerId: params.customerId,
      fallbackPrice: params.fallbackPrice,
      segment: segment
    });
  });
  var unitPrice = segments.reduce(function (total, segment) {
    return total.plus(segment.total_price);
  }, new Decimal(0));
  var totalPrice = unitPrice.times(params.quantity);
  var quotationShelfId = ((_segments$find = segments.find(function (segment) {
    return segment.quotation_shelf_id;
  })) === null || _segments$find === void 0 ? void 0 : _segments$find.quotation_shelf_id) || 0;
  return {
    unitPrice: unitPrice,
    totalPrice: totalPrice,
    quotationShelfId: quotationShelfId,
    segments: segments
  };
}
function calculateBundlePrices(params, segments) {
  var _params$product;
  var bundleList = ((_params$product = params.product) === null || _params$product === void 0 ? void 0 : _params$product.product_bundle) || [];
  if (!bundleList.length) return undefined;
  return bundleList.map(function (bundle) {
    var _bundle$bundle_id;
    var productId = getBundleProductId(bundle);
    var variantId = getBundleVariantId(bundle);
    var quantity = getProductQuantity(bundle);
    var price = calculatePriceForProduct({
      quotation: params.quotation,
      productId: productId,
      variantId: variantId,
      customerId: params.customer_id,
      quantity: quantity,
      fallbackPrice: getBundleFallbackPrice(bundle),
      segments: segments
    });
    return {
      bundle_id: (_bundle$bundle_id = bundle.bundle_id) !== null && _bundle$bundle_id !== void 0 ? _bundle$bundle_id : bundle.id,
      group_id: bundle.group_id,
      bundle_group_id: bundle.bundle_group_id,
      bundle_product_id: productId,
      bundle_variant_id: variantId !== null && variantId !== void 0 ? variantId : 0,
      unit_price: price.unitPrice.toDecimalPlaces(2).toFixed(2),
      total_price: price.totalPrice.toDecimalPlaces(2).toFixed(2),
      quantity: quantity,
      quotation_shelf_id: price.quotationShelfId,
      source: price.segments.some(function (segment) {
        return segment.source === 'quotation';
      }) ? 'quotation' : 'fallback',
      segments: price.segments
    };
  });
}
export function calculateBaseSalesProductBookingPrice(params) {
  var product = params.product || {};
  var productId = getProductId(product);
  var variantId = getProductVariantId(product);
  var productQuantity = getProductQuantity(product);
  var fallbackPrice = getFallbackPrice(params);
  var timeSegments = buildTimeSegments(params);
  var price = calculatePriceForProduct({
    quotation: params.quotation,
    productId: productId,
    variantId: variantId,
    customerId: params.customer_id,
    quantity: productQuantity,
    fallbackPrice: fallbackPrice,
    segments: timeSegments
  });
  var bundlePrices = calculateBundlePrices(params, timeSegments);
  return _objectSpread({
    product_id: productId,
    product_variant_id: variantId !== null && variantId !== void 0 ? variantId : 0,
    customer_id: params.customer_id,
    unit_price: price.unitPrice.toDecimalPlaces(2).toFixed(2),
    total_price: price.totalPrice.toDecimalPlaces(2).toFixed(2),
    quantity: productQuantity,
    duration: params.duration,
    quotation_shelf_id: price.quotationShelfId,
    segments: price.segments
  }, bundlePrices ? {
    product_bundle: bundlePrices
  } : {});
}