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/solution/BookingByStep/utils/resources.ts
var resources_exports = {};
__export(resources_exports, {
  checkSessionProductLeadTime: () => checkSessionProductLeadTime,
  checkTwoResourcesIntersection: () => checkTwoResourcesIntersection,
  filterResourcesByFormItem: () => filterResourcesByFormItem,
  filterScheduleByDateRange: () => filterScheduleByDateRange,
  formatResources: () => formatResources,
  getIsUsableByTimeItem: () => getIsUsableByTimeItem,
  getOthersCartSelectedResources: () => getOthersCartSelectedResources,
  getOthersSelectedResources: () => getOthersSelectedResources,
  getResourcesByIds: () => getResourcesByIds,
  getResourcesByProduct: () => getResourcesByProduct,
  getResourcesIdsByProduct: () => getResourcesIdsByProduct,
  getTimeSlicesByResource: () => getTimeSlicesByResource,
  getTimeSlicesByResources: () => getTimeSlicesByResources,
  getTimesIntersection: () => getTimesIntersection,
  isConflict: () => isConflict,
  mergeSubResourcesTimeSlices: () => mergeSubResourcesTimeSlices,
  sortCombinedResources: () => sortCombinedResources
});
module.exports = __toCommonJS(resources_exports);
var import_dayjs = __toESM(require("dayjs"));
var getUseableEventCount = (eventList, current) => {
  return (eventList || []).reduce((pre, event) => {
    return pre - event.pax;
  }, current || 0);
};
var isConflict = (event, current) => {
  const eventStart = (0, import_dayjs.default)(event.start_at);
  const eventEnd = (0, import_dayjs.default)(event.end_at);
  const currentStart = (0, import_dayjs.default)(current.start_at);
  const _isBefore = currentStart.isBefore(eventEnd);
  let _isAfter = true;
  if (current.end_at) {
    const currentEnd = (0, import_dayjs.default)(current.end_at);
    _isAfter = currentEnd.isAfter(eventStart);
  }
  return _isBefore && _isAfter;
};
var checkAfterToDay = (date, today = (0, import_dayjs.default)()) => {
  return (0, import_dayjs.default)(date).isAfter((0, import_dayjs.default)(today));
};
var formatResource = (resourceItem, booking) => {
  let _resourceItem = { ...resourceItem };
  _resourceItem.timeSlices = getTimeSlicesByResource({
    resource: _resourceItem,
    duration: booking.duration,
    split: 10,
    currentDate: (0, import_dayjs.default)().format("YYYY-MM-DD")
  });
  _resourceItem.labelText = _resourceItem.main_field;
  return _resourceItem;
};
var checkCapacity = ({
  event_list,
  timeSlice,
  resource,
  currentCount = 1
}) => {
  const isMultipleBooking = resource.resourceType === "multiple";
  if (currentCount > resource.capacity && (isMultipleBooking || !isMultipleBooking && event_list.length === 0)) {
    return {
      status: false,
      capacity: resource.capacity,
      reason: "capacityOnly"
    };
  }
  let conflict = (event_list || []).filter((d) => {
    return isConflict(
      { start_at: d.start_at, end_at: d.end_at },
      { start_at: timeSlice.start_at, end_at: timeSlice.end_at }
    );
  });
  let conflictCount = getUseableEventCount(conflict, resource.capacity);
  if (resource.resourceType === "single") {
    if (conflict.length === 0) {
      return {
        status: true,
        capacity: conflictCount
      };
    } else {
      return {
        status: false,
        capacity: conflictCount
      };
    }
  } else {
    if (currentCount <= conflictCount) {
      return {
        status: true,
        capacity: conflictCount
      };
    } else {
      return {
        status: false,
        capacity: conflictCount
      };
    }
  }
};
var getIsUsableByTimeItem = ({
  timeSlice,
  time,
  resource,
  currentCount = 1,
  resourcesUseableMap = {},
  cut_off_time
}) => {
  var _a;
  let status = {
    afterToDay: false,
    capacity: false,
    usable: false,
    remainingCapacity: 0,
    // 剩余容量
    reason: ""
  };
  let earliest = (0, import_dayjs.default)();
  let canBookingForOngoing = false;
  const { unit, unit_type, type, ongoing } = cut_off_time || {};
  if (type === "ongoing" && (ongoing == null ? void 0 : ongoing.type) === "after_start") {
    if ((0, import_dayjs.default)(timeSlice.start_at).isBefore((0, import_dayjs.default)())) {
      if (earliest.isBefore((0, import_dayjs.default)(timeSlice.start_at).add(ongoing.unit, "minute"))) {
        canBookingForOngoing = true;
      }
    }
  } else if (type === "ongoing" && (ongoing == null ? void 0 : ongoing.type) === "before_end") {
    if ((0, import_dayjs.default)(timeSlice.end_at).isAfter(earliest)) {
      canBookingForOngoing = true;
    }
  } else {
    if (unit) {
      earliest = earliest.add(unit, unit_type);
    }
  }
  if (!checkAfterToDay(timeSlice.start_at, earliest) && !canBookingForOngoing) {
    return status;
  }
  status.afterToDay = true;
  const checkCapacityResult = checkCapacity({
    event_list: time == null ? void 0 : time.event_list,
    timeSlice,
    resource,
    currentCount
  });
  if ((_a = resource.combined_resource) == null ? void 0 : _a.status) {
    const resourceIds = resource.combined_resource.resource_ids;
    resourceIds.forEach((id) => {
      if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[id]) === false) {
        checkCapacityResult.status = false;
      }
    });
  }
  status.reason = checkCapacityResult.reason || "";
  if (!checkCapacityResult.status) {
    return status;
  }
  status.remainingCapacity = checkCapacityResult.capacity;
  status.capacity = true;
  status.usable = true;
  return status;
};
var getResourcesByProduct = (resourcesMap, resources, selectedResources, capacity = 1) => {
  return (resources || []).reduce((acc, item) => {
    if ((item == null ? void 0 : item.status) == 1) {
      const form_id = item.id;
      item.optional_resource = (item.optional_resource || []).filter(
        (d) => item.default_resource.indexOf(d) == -1
      );
      let optional_resource = item.optional_resource.reduce(
        (childAcc, d) => {
          var _a;
          const isSelectSingleResources = ((_a = resourcesMap[d]) == null ? void 0 : _a.resourceType) === "single" && selectedResources.includes(resourcesMap[d].id);
          if (resourcesMap[d] && !isSelectSingleResources) {
            const combiningResources = [];
            if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
              resourcesMap[d].combined_resource.resource_ids.forEach(
                (id) => {
                  if (resourcesMap[id]) {
                    combiningResources.push(resourcesMap[id]);
                    childAcc.push(
                      Object.assign({}, resourcesMap[id], {
                        form_id,
                        resourceType: item.type,
                        children: combiningResources,
                        onlyComputed: true,
                        // 是否是只用来计算用，组合资源里，假设商品只关联了组合资源没关联子资源，需要通过这个计算来在后面从 renderList 里删除这个资源
                        metadata: {
                          ...resourcesMap[id].metadata,
                          combined_resource: resourcesMap[id].combined_resource,
                          form_name: item.title,
                          resource_name: resourcesMap[id].main_field
                        }
                      })
                    );
                  }
                }
              );
            }
            childAcc.push(
              Object.assign({}, resourcesMap[d], {
                form_id,
                resourceType: item.type,
                children: combiningResources,
                metadata: {
                  ...resourcesMap[d].metadata,
                  combined_resource: resourcesMap[d].combined_resource,
                  form_name: item.title,
                  resource_name: resourcesMap[d].main_field
                }
              })
            );
          }
          return childAcc;
        },
        []
      );
      let default_resource = item.default_resource.reduce(
        (childAcc, d) => {
          var _a;
          const isSelectSingleResources = ((_a = resourcesMap[d]) == null ? void 0 : _a.resourceType) === "single" && selectedResources.includes(resourcesMap[d].id);
          if (resourcesMap[d] && !isSelectSingleResources) {
            const combiningResources = [];
            if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
              resourcesMap[d].combined_resource.resource_ids.forEach(
                (id) => {
                  if (resourcesMap[id]) {
                    combiningResources.push(resourcesMap[id]);
                    childAcc.push(
                      Object.assign({}, resourcesMap[id], {
                        form_id,
                        resourceType: item.type,
                        children: combiningResources,
                        onlyComputed: true,
                        // 是否是只用来计算用，组合资源里，假设商品只关联了组合资源没关联子资源，需要通过这个计算来在后面从 renderList 里删除这个资源
                        metadata: {
                          ...resourcesMap[id].metadata,
                          combined_resource: resourcesMap[id].combined_resource,
                          form_name: item.title,
                          resource_name: resourcesMap[id].main_field
                        }
                      })
                    );
                  }
                }
              );
            }
            childAcc.push(
              Object.assign({}, resourcesMap[d], {
                form_id,
                resourceType: item.type,
                is_default: 1,
                children: combiningResources,
                metadata: {
                  ...resourcesMap[d].metadata,
                  combined_resource: resourcesMap[d].combined_resource,
                  form_name: item.title,
                  resource_name: resourcesMap[d].main_field
                }
              })
            );
          }
          return childAcc;
        },
        []
      );
      item.renderList = optional_resource.concat(default_resource);
      item.renderList = item.renderList.filter((d) => {
        const latestTime = d.times.reduce((latest, current) => {
          return (0, import_dayjs.default)(current.end_at).isAfter((0, import_dayjs.default)(latest.end_at)) ? current : latest;
        }, d.times[0]);
        return (0, import_dayjs.default)(latestTime.end_at).isAfter((0, import_dayjs.default)()) && d.capacity >= capacity;
      });
      item.form_id = form_id;
      acc.push(item);
    }
    return acc;
  }, []);
};
var formatResources = ({
  booking,
  resources
}) => {
  try {
    let _list = [...resources];
    let maps = {};
    for (let item of _list) {
      let renderListMaps = {};
      item.renderList = item.renderList.map((d) => {
        let res = formatResource(d, booking);
        renderListMaps[res.id] = res;
        return res;
      });
      maps[item.form_id] = {
        ...item,
        renderListMaps
      };
    }
    return { list: _list, maps };
  } catch (err) {
    console.log("formatResourcesErr", err);
  }
  return {
    list: [],
    maps: {}
  };
};
var getTimeSlicesByResource = ({
  resource,
  duration,
  split = 10,
  currentDate = (0, import_dayjs.default)(),
  capacity,
  resourcesUseableMap = {},
  cut_off_time,
  hasFlexibleDuration,
  operating_day_boundary,
  maxBlockThreshold
}) => {
  let { times } = resource;
  const timeSlices = [];
  times.sort((a, b) => {
    return (0, import_dayjs.default)(a.start_at).diff((0, import_dayjs.default)(b.start_at), "minute");
  });
  times.forEach((time) => {
    const startTime = (0, import_dayjs.default)(`${time.start_at}`);
    let endTime = (0, import_dayjs.default)(`${time.end_at}`);
    if (endTime.isAfter((0, import_dayjs.default)(currentDate).endOf("day"))) {
      endTime = (0, import_dayjs.default)(currentDate).endOf("day");
    }
    let currentStart = startTime;
    while (true) {
      const currentEnd = currentStart.add(duration, "minute");
      if (currentEnd.isAfter(endTime)) {
        break;
      }
      const timeSlice = {
        start_time: currentStart.format("HH:mm"),
        end_time: currentEnd.format("HH:mm"),
        start_at: currentStart,
        end_at: currentEnd
      };
      const _status = getIsUsableByTimeItem({
        timeSlice,
        time,
        resource,
        currentCount: capacity || 1,
        resourcesUseableMap,
        cut_off_time
      });
      if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[resource.id]) !== false) {
        resourcesUseableMap[resource.id] = _status.usable;
      }
      if (_status.usable) {
        const operatingBoundaryDateTime = (operating_day_boundary == null ? void 0 : operating_day_boundary.type) === "start_time" ? "23:59" : operating_day_boundary == null ? void 0 : operating_day_boundary.time;
        if (hasFlexibleDuration && operating_day_boundary && timeSlice.start_time >= (operatingBoundaryDateTime || "23:59")) {
          break;
        }
        const operatingBoundaryDateTimeObj = (0, import_dayjs.default)(`${endTime.format("YYYY-MM-DD")} ${operatingBoundaryDateTime}`);
        const earlyTime = endTime.isBefore(operatingBoundaryDateTimeObj) ? endTime : operatingBoundaryDateTimeObj;
        if (hasFlexibleDuration && operating_day_boundary && maxBlockThreshold && timeSlice.start_at.add(maxBlockThreshold || 0, "minutes").isAfter(earlyTime)) {
          break;
        }
        timeSlices.push({
          ...timeSlice,
          // 这里需要补充这个时间段内是否可预约
          _status
        });
      }
      currentStart = currentStart.add(split, "minute");
    }
  });
  return timeSlices;
};
var getTimesIntersection = (times, count) => {
  let obj = times.reduce((acc, item) => {
    let _key = `${item.start_time}-${item.end_time}`;
    if (!acc[_key]) {
      acc[_key] = {
        item,
        count: 1
      };
    } else {
      acc[_key].count += 1;
    }
    return acc;
  }, {});
  return Object.values(obj).filter((d) => d.count >= count).map((d) => d.item);
};
var getResourcesByIds = (resourcesMap, ids) => {
  return (ids || []).map((id) => resourcesMap[id]);
};
var mergeSubResourcesTimeSlices = (resources, resourcesMap) => {
  return resources.forEach((item) => {
    var _a, _b;
    if (((_a = item == null ? void 0 : item.combined_resource) == null ? void 0 : _a.status) === 1) {
      (_b = item == null ? void 0 : item.combined_resource) == null ? void 0 : _b.resource_ids.forEach((id) => {
        const subResource = resourcesMap[id];
        if (subResource) {
          subResource.times.forEach((time) => {
            const fatherResourcesTime = item.times.find(
              (n) => n.start_at === time.start_at && n.end_at === time.end_at
            );
            if (fatherResourcesTime) {
              fatherResourcesTime.event_list.push(...time.event_list || []);
            }
          });
        }
      });
    }
  });
};
var getTimeSlicesByResources = ({
  resourceIds,
  resourcesMap,
  duration,
  currentDate,
  split,
  capacity,
  resourcesUseableMap,
  cut_off_time,
  hasFlexibleDuration,
  operating_day_boundary,
  maxBlockThreshold
}) => {
  let resources = getResourcesByIds(resourcesMap, resourceIds);
  mergeSubResourcesTimeSlices(resources, resourcesMap);
  resources.sort((a, b) => {
    var _a, _b, _c, _d;
    const aIsCombined = ((_b = (_a = a.metadata) == null ? void 0 : _a.combined_resource) == null ? void 0 : _b.status) === 1;
    const bIsCombined = ((_d = (_c = b.metadata) == null ? void 0 : _c.combined_resource) == null ? void 0 : _d.status) === 1;
    if (aIsCombined && !bIsCombined)
      return 1;
    if (!aIsCombined && bIsCombined)
      return -1;
    return 0;
  });
  let timeSliceList = resources.reduce(
    (acc, item) => {
      return acc.concat(
        getTimeSlicesByResource({
          resource: item,
          duration,
          split,
          currentDate,
          capacity,
          resourcesUseableMap,
          cut_off_time,
          hasFlexibleDuration,
          operating_day_boundary,
          maxBlockThreshold
        })
      );
    },
    []
  );
  let intersection = getTimesIntersection(timeSliceList, resources.length);
  return intersection;
};
var getOthersSelectedResources = (cartItems, accountId, resourcesMap) => {
  return cartItems.reduce((acc, d) => {
    var _a;
    if (d.holder_id !== accountId) {
      if ((_a = d._origin) == null ? void 0 : _a.resources) {
        d._origin.resources.forEach((n) => {
          if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) {
            if (n.metadata.combined_resource.resource_ids.some(
              (m) => acc.includes(m)
            )) {
              return acc;
            }
            acc.push(...n.metadata.combined_resource.resource_ids);
          } else {
            Object.values(resourcesMap).forEach((m) => {
              if (m.combined_resource && m.combined_resource.status === 1) {
                if (m.combined_resource.resource_ids.includes(n.id)) {
                  acc.push(m.id);
                }
              }
            });
          }
          acc.push(n.id);
        });
      }
    }
    return acc;
  }, []);
};
var getOthersCartSelectedResources = (cartItems, cartItemId, resourcesMap) => {
  return cartItems.reduce((acc, d) => {
    var _a;
    if (d._id !== cartItemId) {
      if ((_a = d._origin) == null ? void 0 : _a.resources) {
        d._origin.resources.forEach((n) => {
          if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) {
            if (n.metadata.combined_resource.resource_ids.some(
              (m) => acc.includes(m)
            )) {
              return acc;
            }
            acc.push(...n.metadata.combined_resource.resource_ids);
          } else {
            Object.values(resourcesMap).forEach((m) => {
              if (m.combined_resource && m.combined_resource.status === 1) {
                if (m.combined_resource.resource_ids.includes(n.id)) {
                  acc.push(m.id);
                }
              }
            });
          }
          acc.push(n.id);
        });
      }
    }
    return acc;
  }, []);
};
function filterScheduleByDateRange(schedule, startDate, endDate) {
  if (!(schedule == null ? void 0 : schedule.length))
    return [];
  const start = new Date(startDate);
  const end = new Date(endDate);
  return schedule.filter((item) => {
    const itemDate = new Date(item.date);
    return itemDate >= start && itemDate <= end;
  });
}
function checkSessionProductLeadTime(product) {
  let latestStartDate = "";
  let earliestEndDate = "";
  const { future_day, unit, unit_type } = product.cut_off_time;
  if (future_day) {
    const endDate = (0, import_dayjs.default)().add(future_day, "day");
    if (!earliestEndDate || endDate.isBefore((0, import_dayjs.default)(earliestEndDate), "day")) {
      earliestEndDate = endDate.format("YYYY-MM-DD");
    }
  } else if (future_day === 0) {
    const endDate = (0, import_dayjs.default)();
    if (!earliestEndDate || endDate.isBefore((0, import_dayjs.default)(earliestEndDate), "day")) {
      earliestEndDate = endDate.format("YYYY-MM-DD");
    }
  }
  if (unit && unit_type) {
    const startDate = (0, import_dayjs.default)(
      (0, import_dayjs.default)().add(unit, unit_type).format("YYYY-MM-DD")
    );
    if (!latestStartDate || startDate.isAfter((0, import_dayjs.default)(latestStartDate), "day")) {
      latestStartDate = startDate.format("YYYY-MM-DD");
    }
  }
  return {
    latestStartDate,
    earliestEndDate
  };
}
function getResourcesIdsByProduct(product) {
  var _a, _b, _c;
  const tempResourceIds = [];
  (_c = (_b = (_a = product == null ? void 0 : product.product_resource) == null ? void 0 : _a.resources) == null ? void 0 : _b.forEach) == null ? void 0 : _c.call(_b, (resource) => {
    var _a2, _b2;
    if ((resource == null ? void 0 : resource.status) == 1) {
      if ((_a2 = resource == null ? void 0 : resource.default_resource) == null ? void 0 : _a2.length) {
        tempResourceIds.push(...resource == null ? void 0 : resource.default_resource);
      } else if ((_b2 = resource == null ? void 0 : resource.optional_resource) == null ? void 0 : _b2.length) {
        tempResourceIds.push(...resource == null ? void 0 : resource.optional_resource);
      }
    }
  });
  return tempResourceIds;
}
function sortCombinedResources(resourcesList) {
  const newResourcesList = [...resourcesList];
  newResourcesList.sort((a, b) => {
    var _a, _b, _c, _d;
    const aIsCombined = ((_b = (_a = a.metadata) == null ? void 0 : _a.combined_resource) == null ? void 0 : _b.status) === 1;
    const bIsCombined = ((_d = (_c = b.metadata) == null ? void 0 : _c.combined_resource) == null ? void 0 : _d.status) === 1;
    return aIsCombined === bIsCombined ? 0 : aIsCombined ? 1 : -1;
  });
  return newResourcesList;
}
function filterResourcesByFormItem(resources, form_id) {
  return resources.filter((n) => n.form_id === form_id);
}
function checkTwoResourcesIntersection(resource1, resource2) {
  var _a, _b;
  if (resource1.id === resource2.id)
    return true;
  if (((_a = resource1.metadata.combined_resource) == null ? void 0 : _a.status) === 1 && // 如果现在选择的是组合资源，需要判断
  // 1、当前其他购物车里是否选了当前组合资源的子资源
  // 2、如果其他购物车里的商品也是组合资源，出了组合资源本身的 id 需要判断，还需要判断子资源的 id 是否有交集
  (resource1.metadata.combined_resource.resource_ids.includes(resource2.id) || resource1.metadata.combined_resource.resource_ids.some((n) => {
    return resource2.metadata.combined_resource.resource_ids.includes(n);
  })))
    return true;
  if (((_b = resource2.metadata.combined_resource) == null ? void 0 : _b.status) === 1 && resource2.metadata.combined_resource.resource_ids.includes(resource2.id))
    return true;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  checkSessionProductLeadTime,
  checkTwoResourcesIntersection,
  filterResourcesByFormItem,
  filterScheduleByDateRange,
  formatResources,
  getIsUsableByTimeItem,
  getOthersCartSelectedResources,
  getOthersSelectedResources,
  getResourcesByIds,
  getResourcesByProduct,
  getResourcesIdsByProduct,
  getTimeSlicesByResource,
  getTimeSlicesByResources,
  getTimesIntersection,
  isConflict,
  mergeSubResourcesTimeSlices,
  sortCombinedResources
});
