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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
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/Sales/index.ts
var Sales_exports = {};
__export(Sales_exports, {
  Sales: () => SalesImpl,
  SalesImpl: () => SalesImpl,
  default: () => Sales_default
});
module.exports = __toCommonJS(Sales_exports);
var import_dayjs = __toESM(require("dayjs"));
var import_BaseModule = require("../../modules/BaseModule");
var import_types = require("./types");
__reExport(Sales_exports, require("./types"), module.exports);
var SalesImpl = class extends import_BaseModule.BaseModule {
  // LoggerManager 实例
  constructor(name, version) {
    super(name, version);
    this.defaultName = "sales";
    this.defaultVersion = "1.0.0";
    this.defaultTimelineBucketMinutes = 15;
    this.isSolution = true;
    this.options = {};
    this.otherParams = {};
  }
  async initialize(core, options = {}) {
    this.core = core;
    this.options = options;
    this.otherParams = options.otherParams || {};
    const appPlugin = this.core.getPlugin("app");
    this.request = appPlugin == null ? void 0 : appPlugin.getApp().request;
    if (!this.request) {
      throw new Error("Sales 解决方案需要 request 插件支持");
    }
    this.store = {
      currentDay: (0, import_dayjs.default)().startOf("day"),
      reservationList: []
    };
    this.logger = appPlugin == null ? void 0 : appPlugin.getApp().logger;
    await this.core.effects.emit(`${this.name}:onInited`, {});
  }
  // -------------------------------------------------------------------------
  // SalesModuleAPI 实现
  // -------------------------------------------------------------------------
  /** 获取当前 store 快照 */
  getState() {
    return { ...this.store };
  }
  /** 获取当前选择日期 */
  getCurrentDay() {
    return this.store.currentDay;
  }
  /** 设置当前选择日期，会自动归一到当天 00:00:00 */
  setCurrentDay(currentDay) {
    const normalized = (0, import_dayjs.default)(currentDay).startOf("day");
    this.store.currentDay = normalized;
    this.core.effects.emit(import_types.SalesHooks.onCurrentDayChanged, { currentDay: normalized });
    return normalized;
  }
  /** 获取当前预约列表 */
  getReservationList() {
    return [...this.store.reservationList];
  }
  /** 覆盖设置当前预约列表 */
  setReservationList(reservationList) {
    this.store.reservationList = reservationList;
    this.core.effects.emit(import_types.SalesHooks.onReservationListChanged, { reservationList });
    return reservationList;
  }
  /** 重置预约列表为空 */
  resetReservationList() {
    this.store.reservationList = [];
    this.core.effects.emit(import_types.SalesHooks.onReservationListChanged, { reservationList: [] });
    return [];
  }
  async cancelOrder(orderIds) {
    const orderModule = this.core.getModule("order");
    if (!orderModule) {
      throw new Error("Sales 取消订单失败：Order 模块未注册");
    }
    return orderModule.cancelOrder({ order_ids: orderIds });
  }
  async changeBookingStatus(params) {
    const orderModule = this.core.getModule("order");
    if (!orderModule) {
      throw new Error("Sales 变更预约状态失败：Order 模块未注册");
    }
    return orderModule.changeBookingStatus(params);
  }
  // -------------------------------------------------------------------------
  // 生命周期
  // -------------------------------------------------------------------------
  async destroy() {
    await this.core.effects.emit(`${this.name}:onDestroy`, {});
    super.destroy();
  }
  /**
   * 时间轴粒度（分钟）
   * - 默认 15 分钟
   * - 可通过 registerModule 时的 options.otherParams.timelineBucketMinutes 覆盖
   */
  getTimelineBucketMinutes() {
    var _a;
    const dynamicBucket = Number((_a = this.otherParams) == null ? void 0 : _a.timelineBucketMinutes);
    if (!Number.isFinite(dynamicBucket) || dynamicBucket <= 0)
      return this.defaultTimelineBucketMinutes;
    return Math.floor(dynamicBucket);
  }
  /**
   * 解析营业日统计窗口：
   * - 当 operating_day_boundary.type === 'start_time'
   *   使用「今天 + boundary.time」到「明天 + boundary.time」
   * - 否则回退自然日（00:00 到次日 00:00）
   */
  getTimelineRangeByOperatingBoundary() {
    var _a, _b, _c, _d, _e, _f, _g;
    const today = (0, import_dayjs.default)();
    const defaultStart = today.startOf("day");
    const defaultEndExclusive = defaultStart.add(1, "day");
    const appPlugin = this.core.getPlugin("app");
    const coreData = (_f = (_d = (_c = (_b = (_a = appPlugin == null ? void 0 : appPlugin.getApp()) == null ? void 0 : _a.data) == null ? void 0 : _b.store) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core");
    const operatingDayBoundary = (_g = coreData == null ? void 0 : coreData.core) == null ? void 0 : _g.operating_day_boundary;
    if ((operatingDayBoundary == null ? void 0 : operatingDayBoundary.type) !== "start_time") {
      return { startAt: defaultStart, endExclusiveAt: defaultEndExclusive };
    }
    const boundaryTime = String(operatingDayBoundary.time || "").trim();
    const startAt = (0, import_dayjs.default)(`${today.format("YYYY-MM-DD")} ${boundaryTime}`);
    if (!startAt.isValid()) {
      return { startAt: defaultStart, endExclusiveAt: defaultEndExclusive };
    }
    return { startAt, endExclusiveAt: startAt.add(1, "day") };
  }
  /**
   * 统计时间轴每个时间片的预约数量。
   * 算法使用差分数组，复杂度 O(n + s):
   * - n = booking 数量
   * - s = 时间片数量
   */
  getTimelineHighlights(bookingList = [], startDateTime, endDateTime) {
    const bucketMinutes = this.getTimelineBucketMinutes();
    const bucketMs = bucketMinutes * 60 * 1e3;
    const customStartAt = startDateTime ? (0, import_dayjs.default)(startDateTime) : (0, import_dayjs.default)("");
    const customEndExclusiveAt = endDateTime ? (0, import_dayjs.default)(endDateTime) : (0, import_dayjs.default)("");
    const hasValidCustomRange = customStartAt.isValid() && customEndExclusiveAt.isValid();
    const { startAt, endExclusiveAt } = hasValidCustomRange ? { startAt: customStartAt, endExclusiveAt: customEndExclusiveAt } : this.getTimelineRangeByOperatingBoundary();
    const startAtMs = startAt.valueOf();
    const endExclusiveAtMs = endExclusiveAt.valueOf();
    if (!startAt.isValid() || !endExclusiveAt.isValid() || endExclusiveAtMs <= startAtMs)
      return [];
    const slotCount = Math.ceil((endExclusiveAtMs - startAtMs) / bucketMs);
    if (slotCount <= 0)
      return [];
    const diff = new Int32Array(slotCount + 1);
    for (let i = 0; i < bookingList.length; i++) {
      const booking = bookingList[i];
      const appointmentStatus = String(booking.appointment_status ?? booking.status ?? "");
      if (appointmentStatus === "new" || appointmentStatus === "rejected" || appointmentStatus === "cancelled")
        continue;
      const bookingStartAt = this.toBookingDateTime(booking.start_date, booking.start_time);
      const bookingEndAt = this.toBookingDateTime(booking.end_date, booking.end_time);
      if (!bookingStartAt.isValid() || !bookingEndAt.isValid())
        continue;
      const overlapStartMs = Math.max(bookingStartAt.valueOf(), startAtMs);
      const overlapEndExclusiveMs = Math.min(bookingEndAt.valueOf() + 1, endExclusiveAtMs);
      if (overlapStartMs >= overlapEndExclusiveMs)
        continue;
      const startIdx = Math.max(0, Math.ceil((overlapStartMs - startAtMs) / bucketMs));
      const endIdx = Math.min(
        slotCount - 1,
        Math.floor((overlapEndExclusiveMs - 1 - startAtMs) / bucketMs)
      );
      if (startIdx > endIdx)
        continue;
      diff[startIdx] += 1;
      diff[endIdx + 1] -= 1;
    }
    const timeline = [];
    let runningCount = 0;
    for (let i = 0; i < slotCount; i++) {
      runningCount += diff[i];
      timeline.push(runningCount);
    }
    return timeline;
  }
  /** dayjs 未启用插件时，手动封装 >= 判断 */
  isSameOrAfter(left, right) {
    return left.isAfter(right) || left.isSame(right);
  }
  /** dayjs 未启用插件时，手动封装 <= 判断 */
  isSameOrBefore(left, right) {
    return left.isBefore(right) || left.isSame(right);
  }
  /**
   * 将 booking 的日期/时间字段统一组装为 dayjs
   * - date + time 都有：按完整时间解析
   * - 只有一个字段：按单字段解析（兼容历史数据）
   * - 都没有：返回 invalid
   */
  toBookingDateTime(date, time) {
    if (!date && !time)
      return (0, import_dayjs.default)("");
    if (date && time)
      return (0, import_dayjs.default)(`${date} ${time}`);
    return (0, import_dayjs.default)(date || time);
  }
  /**
   * 预约状态映射（面向 UI 的统一状态）
   * 说明：locked 逻辑后续会补业务规则，这里先保留分支占位。
   */
  getBookingStatus(appointmentStatus) {
    if (appointmentStatus === "started")
      return "occupied";
    if (appointmentStatus === "confirmed" || appointmentStatus === "arrived") {
      return "reserved";
    }
    if (appointmentStatus === "locked")
      return "locked";
    return void 0;
  }
  getResourceId(resource) {
    return resource.id ?? resource.form_record_id ?? "";
  }
  getBookingAppointmentStatus(booking) {
    return String(booking.appointment_status ?? booking.status ?? "");
  }
  isBookingIncludedInStats(booking) {
    const appointmentStatus = this.getBookingAppointmentStatus(booking);
    return appointmentStatus !== "new" && appointmentStatus !== "rejected" && appointmentStatus !== "cancelled";
  }
  getBookingOrderPaymentStatus(booking) {
    var _a;
    return String(((_a = booking.order) == null ? void 0 : _a.payment_status) ?? "");
  }
  countBookingOrders(bookings) {
    const orderIds = /* @__PURE__ */ new Set();
    bookings.forEach((booking) => {
      var _a;
      const orderId = booking.order_id ?? ((_a = booking.order) == null ? void 0 : _a.order_id);
      if (orderId === void 0 || orderId === null)
        return;
      orderIds.add(String(orderId));
    });
    return orderIds.size;
  }
  countCompletedBookings(bookings) {
    return bookings.filter((booking) => this.getBookingAppointmentStatus(booking) === "completed").length;
  }
  groupBookingsByResource(bookingList) {
    const bookingMap = /* @__PURE__ */ new Map();
    bookingList.forEach((booking) => {
      if (!Array.isArray(booking.resources))
        return;
      booking.resources.forEach((resource) => {
        const relationId = resource == null ? void 0 : resource.relation_id;
        if (relationId === void 0 || relationId === null)
          return;
        const key = String(relationId);
        const list = bookingMap.get(key) || [];
        list.push(booking);
        bookingMap.set(key, list);
      });
    });
    return bookingMap;
  }
  isBookingMatchedResource(booking, resourceId) {
    if (!Array.isArray(booking.resources))
      return false;
    return booking.resources.some((resource) => {
      const relationId = resource == null ? void 0 : resource.relation_id;
      if (relationId === void 0 || relationId === null)
        return false;
      return String(relationId) === String(resourceId);
    });
  }
  sortMatchedBookings(bookings) {
    return [...bookings].sort((left, right) => {
      const leftStartAt = this.toBookingDateTime(left.start_date, left.start_time).valueOf();
      const rightStartAt = this.toBookingDateTime(right.start_date, right.start_time).valueOf();
      return leftStartAt - rightStartAt;
    });
  }
  /**
   * 资源下 bookings 的返回裁剪策略：
   * 1) 优先返回当前时刻正在进行中的预约（允许并发返回多条）
   * 2) 若无 active，返回已超时且仍占用中的预约（允许并发多条）
   * 3) 若仍无，返回最近一组未来预约（同 start_time 的并发预约全部返回）
   * 4) 最后兜底返回一条（避免资源有历史预约时完全无反馈）
   */
  pickBookingsForCurrentPoint(current, bookings) {
    if (bookings.length === 0)
      return [];
    const currentDayStart = current.startOf("day");
    const currentDayEnd = current.endOf("day");
    const dayScopedBookings = bookings.filter((booking) => {
      const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
      const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
      if (!startAt.isValid() || !endAt.isValid())
        return false;
      return this.isSameOrBefore(startAt, currentDayEnd) && this.isSameOrAfter(endAt, currentDayStart);
    });
    if (dayScopedBookings.length === 0)
      return [];
    const appendNextStartGroupIfNeeded = (selectedBookings) => {
      if (selectedBookings.length === 0)
        return selectedBookings;
      const shouldAppendNextGroup = selectedBookings.some(
        (booking) => booking.status === "reserved" || booking.status === "occupied"
      );
      if (!shouldAppendNextGroup)
        return selectedBookings;
      const selectedStartValues = new Set(
        selectedBookings.map((booking) => this.toBookingDateTime(booking.start_date, booking.start_time)).filter((startAt) => startAt.isValid()).map((startAt) => startAt.valueOf())
      );
      const futureCandidates = dayScopedBookings.filter((booking) => {
        const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
        if (!startAt.isValid())
          return false;
        return startAt.isAfter(current) && !selectedStartValues.has(startAt.valueOf());
      });
      if (futureCandidates.length === 0)
        return selectedBookings;
      const nextStartAt = this.toBookingDateTime(
        futureCandidates[0].start_date,
        futureCandidates[0].start_time
      ).valueOf();
      const nextStartGroup = futureCandidates.filter((booking) => {
        const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
        return startAt.isValid() && startAt.valueOf() === nextStartAt;
      });
      if (nextStartGroup.length === 0)
        return selectedBookings;
      nextStartGroup.forEach((booking) => {
        booking.isNext = true;
      });
      return [...selectedBookings, ...nextStartGroup];
    };
    const activeBookings = dayScopedBookings.filter((booking) => {
      const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
      const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
      if (!startAt.isValid() || !endAt.isValid())
        return false;
      return this.isSameOrAfter(current, startAt) && this.isSameOrBefore(current, endAt);
    });
    if (activeBookings.length > 0)
      return appendNextStartGroupIfNeeded(activeBookings);
    const timeoutOccupied = dayScopedBookings.filter(
      (booking) => booking.status === "occupied" && booking.isTimeout
    );
    if (timeoutOccupied.length > 0)
      return appendNextStartGroupIfNeeded(timeoutOccupied);
    const upcoming = dayScopedBookings.filter((booking) => {
      const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
      return startAt.isValid() && startAt.isAfter(current) && startAt.isSame(current, "day");
    });
    if (upcoming.length > 0) {
      const firstStartAt = this.toBookingDateTime(upcoming[0].start_date, upcoming[0].start_time).valueOf();
      const upcomingStartGroup = upcoming.filter((booking) => {
        const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
        return startAt.valueOf() === firstStartAt;
      });
      return appendNextStartGroupIfNeeded(upcomingStartGroup);
    }
    const fallback = dayScopedBookings[dayScopedBookings.length - 1];
    return fallback ? [fallback] : [];
  }
  /**
   * 计算 booking 在 current 时刻的执行进度百分比（0-100）。
   * - startAt/endAt 非法或 totalMinutes <= 0 返回 0
   * - current 早于 startAt 返回 0，晚于 endAt 返回 100
   */
  calcProgressPercent(current, startAt, endAt) {
    if (!startAt.isValid() || !endAt.isValid())
      return 0;
    const totalMinutes = endAt.diff(startAt, "minute");
    if (totalMinutes <= 0)
      return 0;
    const elapsedMinutes = current.diff(startAt, "minute");
    if (elapsedMinutes <= 0)
      return 0;
    if (elapsedMinutes >= totalMinutes)
      return 100;
    return Math.floor(elapsedMinutes / totalMinutes * 100);
  }
  /**
   * 标准化单条 booking 的分发入口：
   * - 统一过滤 rejected / cancelled（视为没来过）
   * - current === deviceCurrent 走实时分支（信任 appointment_status）
   * - 否则走快照分支（纯时间窗判定，忽略 appointment_status 的 arrived/started/completed 差异）
   */
  normalizeMatchedBooking(current, deviceCurrent, booking, options = {}) {
    const appointmentStatus = this.getBookingAppointmentStatus(booking);
    if (appointmentStatus === "rejected" || appointmentStatus === "cancelled")
      return null;
    const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
    const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
    if (appointmentStatus === "completed" && options.includeCompleted) {
      return this.buildCompletedBooking(current, booking, startAt, endAt);
    }
    if (current.isSame(deviceCurrent)) {
      return this.buildRealtimeBooking(current, booking, appointmentStatus, startAt, endAt);
    }
    return this.buildSnapshotBooking(current, booking, appointmentStatus, startAt, endAt);
  }
  normalizeResourceBookings(current, deviceCurrent, bookingList, options = {}) {
    const normalizedBookings = bookingList.map((booking) => this.normalizeMatchedBooking(current, deviceCurrent, booking, options)).filter((booking) => Boolean(booking)).filter((booking) => booking.status);
    return this.sortMatchedBookings(normalizedBookings);
  }
  buildCompletedBooking(current, booking, startAt, endAt) {
    if (!startAt.isValid() || !endAt.isValid())
      return null;
    if (current.isBefore(startAt)) {
      return {
        ...booking,
        status: "reserved",
        isTimeout: false,
        timeoutTime: void 0,
        progressPercent: 0,
        lateTime: void 0,
        reserved_status: "not_arrived",
        remainingReserveTime: Math.max(startAt.diff(current, "minute"), 0)
      };
    }
    return {
      ...booking,
      status: "occupied",
      isTimeout: false,
      timeoutTime: void 0,
      progressPercent: this.isSameOrAfter(current, endAt) ? 100 : this.calcProgressPercent(current, startAt, endAt),
      lateTime: void 0,
      reserved_status: void 0,
      remainingReserveTime: void 0
    };
  }
  /**
   * 实时模式（current === deviceCurrent）：信任 appointment_status
   * - 过滤 new / completed（实时视角下视为非活跃数据）
   * - status 由 getBookingStatus 映射
   * - occupied 且 current > endAt 标记 isTimeout + timeoutTime
   * - reserved 且 current < startAt 标记 not_arrived，否则标记 late
   */
  buildRealtimeBooking(current, booking, appointmentStatus, startAt, endAt) {
    if (appointmentStatus === "new" || appointmentStatus === "completed")
      return null;
    const bookingStatus = this.getBookingStatus(appointmentStatus);
    const isTimeout = bookingStatus === "occupied" && endAt.isValid() && current.isAfter(endAt);
    const timeoutTime = isTimeout ? current.diff(endAt, "minute") : void 0;
    const progressPercent = bookingStatus === "occupied" ? this.calcProgressPercent(current, startAt, endAt) : 0;
    let reservedStatus;
    let lateTime;
    let remainingReserveTime;
    if (bookingStatus === "reserved" && startAt.isValid()) {
      if (current.isBefore(startAt)) {
        reservedStatus = "not_arrived";
        remainingReserveTime = startAt.diff(current, "minute");
      } else {
        reservedStatus = "late";
        lateTime = Math.max(current.diff(startAt, "minute"), 0);
      }
    }
    return {
      ...booking,
      status: bookingStatus,
      isTimeout,
      timeoutTime,
      progressPercent,
      lateTime,
      reserved_status: reservedStatus,
      remainingReserveTime
    };
  }
  /**
   * 快照模式（current !== deviceCurrent，过去或未来）：忽略 appointment_status
   * 的实时态差异，仅按 booking 时间窗判定，为 current 提供时间点快照视图。
   *
   * - new：视作尚未成为真实预约，过滤
   * - locked：保留 status=locked，不计算 timeout/late/progress
   * - 其他非终态：
   *   - startAt/endAt 非法 → 过滤
   *   - current > endAt → 过滤（已结束，不入池）
   *   - current ∈ [startAt, endAt] → occupied，附带 progressPercent
   *   - current < startAt → reserved + not_arrived，附带 remainingReserveTime
   *
   * 快照模式下 isTimeout 恒为 false，lateTime / timeoutTime 始终置空。
   */
  buildSnapshotBooking(current, booking, appointmentStatus, startAt, endAt) {
    if (appointmentStatus === "new")
      return null;
    if (appointmentStatus === "locked") {
      return {
        ...booking,
        status: "locked",
        isTimeout: false,
        timeoutTime: void 0,
        progressPercent: 0,
        lateTime: void 0,
        reserved_status: void 0,
        remainingReserveTime: void 0
      };
    }
    if (!startAt.isValid() || !endAt.isValid())
      return null;
    if (current.isAfter(endAt))
      return null;
    if (this.isSameOrAfter(current, startAt) && this.isSameOrBefore(current, endAt)) {
      return {
        ...booking,
        status: "occupied",
        isTimeout: false,
        timeoutTime: void 0,
        progressPercent: this.calcProgressPercent(current, startAt, endAt),
        lateTime: void 0,
        reserved_status: void 0,
        remainingReserveTime: void 0
      };
    }
    return {
      ...booking,
      status: "reserved",
      isTimeout: false,
      timeoutTime: void 0,
      progressPercent: 0,
      lateTime: void 0,
      reserved_status: "not_arrived",
      remainingReserveTime: Math.max(startAt.diff(current, "minute"), 0)
    };
  }
  async getResourceBookingList(currentTime, bookingList = [], deviceTime = currentTime) {
    var _a;
    const current = (0, import_dayjs.default)(currentTime);
    if (!current.isValid())
      return [];
    const deviceCurrent = (0, import_dayjs.default)(deviceTime);
    if (!deviceCurrent.isValid())
      return [];
    const resourceResponse = await this.request.get(
      "/shop/form/resource/page",
      { skip: 1, num: 999 },
      // @ts-ignore
      { osServer: true, isShopApi: true }
    );
    const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
    if (!Array.isArray(resourceList) || resourceList.length === 0)
      return [];
    const normalizedBookings = this.normalizeResourceBookings(current, deviceCurrent, bookingList);
    const rawBookingMap = this.groupBookingsByResource(bookingList);
    const bookingMap = this.groupBookingsByResource(normalizedBookings);
    const list = resourceList.map((resource) => {
      const resourceId = this.getResourceId(resource);
      const rawMatchedBookings = rawBookingMap.get(String(resourceId)) || [];
      const matchedBookings = bookingMap.get(String(resourceId)) || [];
      const statsBookings = rawMatchedBookings.filter((booking) => this.isBookingIncludedInStats(booking));
      const orderCount = this.countBookingOrders(statsBookings);
      const bookingCount = statsBookings.length;
      const compeleteBookingCount = this.countCompletedBookings(statsBookings);
      const bookings = this.pickBookingsForCurrentPoint(current, matchedBookings);
      return {
        ...resource,
        resource_id: resourceId,
        orderCount,
        bookingCount,
        compeleteBookingCount,
        bookings
      };
    });
    this.logger.addLog({
      type: "info",
      title: "getResourceBookingList",
      metadata: {
        currentTime,
        bookingList: bookingList == null ? void 0 : bookingList.length,
        deviceTime,
        list: list == null ? void 0 : list.length
      }
    });
    return list;
  }
  async getResourceBookingItem(params) {
    var _a, _b;
    const current = (0, import_dayjs.default)(params.currentTime);
    if (!current.isValid())
      return null;
    const deviceCurrent = (0, import_dayjs.default)(params.deviceTime || params.currentTime);
    if (!deviceCurrent.isValid())
      return null;
    const resourceResponse = await this.request.get(
      "/shop/form/resource/page",
      { skip: 1, num: 999 },
      // @ts-ignore
      { osServer: true, isShopApi: true }
    );
    const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
    if (!Array.isArray(resourceList) || resourceList.length === 0)
      return null;
    const targetResource = resourceList.find(
      (resource) => String(this.getResourceId(resource)) === String(params.resourceId)
    );
    if (!targetResource)
      return null;
    const resourceId = this.getResourceId(targetResource);
    const matchedBookingList = params.bookingList.filter(
      (booking) => this.isBookingMatchedResource(booking, resourceId)
    );
    const statsBookingList = matchedBookingList.filter((booking) => this.isBookingIncludedInStats(booking));
    const completedBookingList = matchedBookingList.filter(
      (booking) => this.getBookingAppointmentStatus(booking) === "completed"
    );
    const unpaidBookingList = matchedBookingList.filter(
      (booking) => this.getBookingOrderPaymentStatus(booking) === "unpaid" || this.getBookingOrderPaymentStatus(booking) === "payment_processing"
    );
    const bookings = this.pickBookingsForCurrentPoint(
      current,
      this.normalizeResourceBookings(current, deviceCurrent, matchedBookingList)
    );
    const completedBookings = completedBookingList.map((booking) => {
      return {
        ...booking,
        status: "compelete",
        isTimeout: false,
        timeoutTime: void 0,
        progressPercent: 100,
        lateTime: void 0,
        reserved_status: void 0,
        remainingReserveTime: void 0
      };
    });
    const unpaidBookings = this.pickBookingsForCurrentPoint(
      current,
      this.normalizeResourceBookings(current, deviceCurrent, unpaidBookingList)
    );
    const orderCount = this.countBookingOrders(statsBookingList);
    const bookingCount = statsBookingList.length;
    const compeleteBookingCount = this.countCompletedBookings(statsBookingList);
    this.logger.addLog({
      type: "info",
      title: "getResourceBookingItem",
      metadata: {
        currentTime: params.currentTime,
        deviceTime: params.deviceTime || params.currentTime,
        resourceId,
        bookingList: (_b = params.bookingList) == null ? void 0 : _b.length,
        bookings: bookings.length,
        completedBookings: completedBookings.length,
        unpaidBookings: unpaidBookings.length,
        orderCount,
        bookingCount,
        compeleteBookingCount
      }
    });
    return {
      ...targetResource,
      resource_id: resourceId,
      orderCount,
      bookingCount,
      compeleteBookingCount,
      bookings,
      completedBookings,
      unpaidBookings
    };
  }
};
var Sales_default = SalesImpl;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Sales,
  SalesImpl,
  ...require("./types")
});
