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/BookingTicket/index.ts
var BookingTicket_exports = {};
__export(BookingTicket_exports, {
  BookingTicket: () => BookingTicketImpl,
  BookingTicketImpl: () => BookingTicketImpl
});
module.exports = __toCommonJS(BookingTicket_exports);
var import_types = require("./types");
var import_BookingContext = require("../../modules/BookingContext");
var import_BaseSales = require("../BaseSales");
var import_scan = __toESM(require("./utils/scan"));
var import_orderCustomer = require("./utils/orderCustomer");
var import_handleScan = require("./utils/scan/handleScan");
var import_scanCache = __toESM(require("./utils/scan/scanCache"));
var import_cartView = require("./utils/cartView");
var import_addProductDecision = require("./utils/addProductDecision");
var import_buildCacheItemFromOrderLine = require("../../modules/BookingContext/utils/buildCacheItemFromOrderLine");
var import_buildNormalProductCacheItemFromOrderLine = require("../../modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine");
var import_bookingStatus = require("./utils/bookingStatus");
__reExport(BookingTicket_exports, require("./types"), module.exports);
var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
  constructor() {
    super(...arguments);
    this.defaultName = "bookingTicket";
    this.defaultVersion = "1.0.0";
    /**
     * 子类覆盖 store 类型为 BookingTicket 子模块清单（在父类基础上追加 customer）。
     * 父类按 `getRegisteredModuleNames` 注入成员到该 store。
     */
    this.store = {};
    this.productCatalog = [];
    this.orderCustomerDiscountRefreshInFlight = null;
    this.orderCustomerDiscountRefreshCustomerId = null;
  }
  /**
   * 在 BaseSales 默认模块清单（products/order/salesSummary/schedule）基础上追加 customer + bookingContext。
   * bookingContext 是 SalesSdk 加车下沉所需的「预约 UI 上下文」（bookingConfig / resourcesOrigin / date）。
   */
  getRegisteredModuleNames() {
    return [...super.getRegisteredModuleNames(), "customer", "bookingContext"];
  }
  getSubmitOrderSalesChannel() {
    return "pos";
  }
  /**
   * 业务侧子模块工厂：BookingTicket 自带的 createBookingTicketModule 优先匹配；
   * 未识别的模块名（如 BookingByStep 公共类型）回退到父类工厂。
   */
  createSubModule(moduleName) {
    const localModule = (0, import_types.createBookingTicketModule)(
      moduleName,
      this.name
    );
    if (localModule)
      return localModule;
    return super.createSubModule(moduleName);
  }
  async initialize(core, options = {}) {
    var _a;
    this.scan = new import_scan.default(this, "BOOKING_TICKET_SCAN");
    await super.initialize(core, options);
    if (!this.request) {
      throw new Error("bookingTicket解决方案需要 request 插件支持");
    }
    this.platform = (_a = this.otherParams) == null ? void 0 : _a.platform;
    console.log("[BookingTicket] 初始化完成");
  }
  /**
   * 加载销售详情，并在父类基础上把 customer 信息装配到 CustomerModule。
   *
   * 业务上 ticketBooking 进入「编辑/查看」时需要 active customer 状态，因此从
   * sales.customer / sales.header / tempOrder 顶层字段中拼装 ICustomer 后调 setSelectedCustomer，
   * 让现有 setActiveCustomer / getActiveCustomer 调用方零成本拿到详情态客户。
   */
  async loadSalesDetail(orderIdOrParams) {
    const sales = await super.loadSalesDetail(orderIdOrParams);
    console.log(sales, "1234sales");
    const customerModule = this.store.customer;
    const detailCustomer = sales == null ? void 0 : sales.customer;
    const orderCustomerSnapshot = this.store.order.getOrderCustomerSnapshot();
    const protocolCustomerId = sales == null ? void 0 : sales.customer_id;
    const protocolCustomer = protocolCustomerId !== void 0 && protocolCustomerId !== null ? {
      id: protocolCustomerId,
      name: String((sales == null ? void 0 : sales.customer_name) || ""),
      phone: sales == null ? void 0 : sales.phone,
      email: sales == null ? void 0 : sales.email,
      country_calling_code: sales == null ? void 0 : sales.country_calling_code
    } : null;
    const selectedCustomer = detailCustomer ?? orderCustomerSnapshot ?? protocolCustomer;
    if (customerModule && selectedCustomer) {
      const { id: detailCustomerId, ...detailCustomerRest } = selectedCustomer ?? {};
      const rawId = detailCustomerId ?? "";
      const customer = {
        ...detailCustomerRest,
        id: rawId == null ? "" : rawId,
        name: (selectedCustomer == null ? void 0 : selectedCustomer.name) ?? "",
        phone: selectedCustomer == null ? void 0 : selectedCustomer.phone,
        email: selectedCustomer == null ? void 0 : selectedCustomer.email,
        country_calling_code: selectedCustomer == null ? void 0 : selectedCustomer.country_calling_code
      };
      customerModule.setSelectedCustomer(customer);
      this.setOrderCustomer(customer);
      await this.store.order.saveDraft();
    }
    return sales;
  }
  async scanPromotionCode(code, customerId) {
    if (!this.store.order)
      throw new Error("order 模块未初始化");
    const raw = await this.store.order.scanCode(code, customerId);
    if (raw.isAvailable) {
      await this.hydrateOrderCustomerFromScanDiscounts(raw.scannedDiscountList);
      await this.store.order.recalculateSummary({ createIfMissing: true });
      this.store.order.persistTempOrder();
    }
    return {
      isAvailable: raw.isAvailable,
      type: raw.type,
      unavailableReason: raw.unavailableReason
    };
  }
  async hydrateOrderCustomerFromScanDiscounts(discounts) {
    const currentOrderCustomer = this.store.order.getOrderCustomer();
    if (currentOrderCustomer)
      return;
    const customerId = this.getDiscountCustomerId(discounts);
    if (!customerId)
      return;
    const customer = await this.resolveCustomerByDiscountCustomerId(customerId);
    if (!customer)
      return;
    this.store.customer.setSelectedCustomer(customer);
    this.setOrderCustomer(customer);
  }
  getDiscountCustomerId(discounts) {
    const discount = discounts.find((item) => item.customer_id != null);
    const customerId = Number(discount == null ? void 0 : discount.customer_id);
    if (!Number.isFinite(customerId) || customerId <= 0)
      return null;
    return customerId;
  }
  async resolveCustomerByDiscountCustomerId(customerId) {
    var _a;
    const localCustomers = this.store.customer.getCustomers();
    const localCustomer = this.findCustomerById(localCustomers, customerId);
    const normalizedLocalCustomer = localCustomer ? this.normalizeCustomer(localCustomer) : null;
    if (normalizedLocalCustomer && this.hasUsableCustomerDetails(normalizedLocalCustomer)) {
      return normalizedLocalCustomer;
    }
    const result = await this.store.customer.queryCustomerList({
      ids: [customerId],
      skip: 1,
      num: 1
    });
    const remoteCustomer = this.findCustomerById((result == null ? void 0 : result.list) || [], customerId) || ((_a = result == null ? void 0 : result.list) == null ? void 0 : _a[0]) || null;
    return remoteCustomer ? this.normalizeCustomer(remoteCustomer) : null;
  }
  findCustomerById(customers = [], customerId) {
    return customers.find((customer) => {
      const rawId = this.getRawCustomerId(customer);
      return rawId !== null && String(rawId) === String(customerId);
    }) || null;
  }
  normalizeCustomer(customer) {
    const raw = customer;
    const rawId = this.getRawCustomerId(customer);
    const name = customer.name || raw.display_name || raw.nickname || raw.customer_name || [raw.first_name, raw.last_name].filter(Boolean).join(" ") || "";
    return {
      ...customer,
      id: rawId ?? customer.id,
      name,
      phone: customer.phone ?? raw.phone ?? raw.mobile ?? "",
      email: customer.email ?? raw.email ?? "",
      country_calling_code: customer.country_calling_code ?? raw.country_calling_code ?? ""
    };
  }
  getRawCustomerId(customer) {
    const raw = customer;
    return customer.id ?? raw.customer_id ?? raw.customerId ?? null;
  }
  hasUsableCustomerDetails(customer) {
    return !!(customer.name || customer.phone || customer.email || customer.display_name || customer.customer_name);
  }
  /**
   * 更新当前预约的 appointment_status。
   *
   * 数据源：从 OrderModule.tempOrder 内部读取，调用方无需传 orderId / scheduleId。
   * schedule id 解析优先级：
   *   1. `tempOrder.metadata.appointment_booking_parent_schedule_id`
   *   2. `tempOrder.bookings` 中 `parent_id === 0` 的 `schedule_event_id`
   *
   * 流程：先乐观更新本地 bookings 的 appointment_status，再调 PUT 接口，
   * 接口成功后强制刷新销售详情；任一步失败都回滚本地状态并抛错。
   *
   * @param status 目标状态（如 'confirmed'）
   * @returns 接口返回的 data
   */
  async setBookingStatus(status) {
    var _a, _b;
    const tempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
    if (!tempOrder) {
      throw new Error("setBookingStatus: tempOrder 未加载");
    }
    const orderId = tempOrder.order_id;
    if (orderId === void 0 || orderId === null) {
      throw new Error("setBookingStatus: tempOrder.order_id 缺失");
    }
    const scheduleId = (0, import_bookingStatus.resolveScheduleId)(tempOrder);
    if (scheduleId === null) {
      throw new Error(
        "setBookingStatus: 无法解析 schedule id（metadata 与 root booking 均缺失）"
      );
    }
    const bookings = Array.isArray(tempOrder.bookings) ? tempOrder.bookings : [];
    const previous = (0, import_bookingStatus.applyBookingsStatus)(bookings, status);
    try {
      const res = await this.request.put(
        `/schedule/booking/appointment-status/${scheduleId}`,
        { appointment_status: status }
      );
      await this.refreshSalesDetail();
      this.core.effects.emit(`${this.name}:onBookingStatusChange`, {
        orderId,
        status
      });
      return (res == null ? void 0 : res.data) ?? res;
    } catch (error) {
      (0, import_bookingStatus.restoreBookingsStatus)(bookings, previous);
      throw error;
    }
  }
  /**
   * 基于当前 tempOrder.order_id 强制从远端重新拉取销售详情。
   *
   * 适用场景：在 BookingTicket 内执行了「修改服务端订单状态」的动作（如改预约状态、
   * 改下单客户、改商品行等）后，统一刷新本地销售详情，保证 UI 与服务端一致。
   *
   * 约束：调用前必须已有 tempOrder 且 order_id 存在，否则视为非法调用并抛错。
   *
   * @returns loadSalesDetail 的返回值
   */
  async refreshSalesDetail() {
    var _a, _b;
    const tempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
    if (!tempOrder) {
      throw new Error("refreshSalesDetail: tempOrder 未加载");
    }
    const orderId = tempOrder.order_id;
    if (orderId === void 0 || orderId === null) {
      throw new Error("refreshSalesDetail: tempOrder.order_id 缺失");
    }
    return this.loadSalesDetail({
      orderId: Number(orderId),
      forceRemote: true
    });
  }
  /**
   * 获取商品列表
   * @param params 包含 schedule_date 的参数
   * @returns 商品列表
   */
  async loadProducts(params = {}, options) {
    const { schedule_date, customer_id, menu_list_ids, schedule_datetime } = params;
    const bookingDate = schedule_datetime || schedule_date || "";
    if (bookingDate) {
      this.setBookingDate(bookingDate);
    }
    try {
      const result = await this.store.products.loadProducts({
        with_count: ["bundleGroup", "optionGroup"],
        with_schedule: 1,
        ...params,
        cacheId: this.cacheId
      }, options);
      this.productCatalog = Array.isArray(result) ? [...result] : [];
      this.core.effects.emit(`${this.name}:onProductsLoaded`, result);
      return result;
    } catch (error) {
      console.error("Failed to load products:", error);
      throw error;
    }
  }
  /**
   * 按预约时间加载单个商品详情。
   * 价格仍由 server products 的报价单桥接统一计算，避免 solution 实例重复请求报价单。
   */
  async loadProductDetail(params, options) {
    const { product_id, ...queryParams } = params;
    const products = await this.loadProducts({
      ...queryParams,
      product_ids: [product_id]
    }, options);
    return products.find(
      (product) => Number(product.id) === Number(product_id)
    );
  }
  /**
   * 取消商品查询订阅
   * @param subscriberId 订阅时传入的 subscriberId
   */
  unsubscribeProductQuery(subscriberId) {
    var _a;
    (_a = this.core.server) == null ? void 0 : _a.removeProductQuerySubscriber(subscriberId);
  }
  /**
   * 初始化外设扫码结果监听
   */
  initPeripheralsListener() {
    this.scan.initPeripheralsListener();
  }
  /**
   * 获取商品列表（不加载到模块中）
   * @returns 商品列表
   */
  async getProducts() {
    return this.store.products.getProducts();
  }
  /**
   * 获取当前已加载的商品池 UI 视图。
   *
   * ProductList.getProducts 是异步 API；BookingTicket 维护最近一次 loadProducts 结果，
   * 供 UI 同步 getter 使用。未加载时返回空列表。
   */
  getProductCatalog() {
    return {
      products: [...this.productCatalog]
    };
  }
  /**
   * 获取购物车 UI 视图。
   *
   * tempOrder 仍是 checkout 协议对象；商品行直接透传 products，bookings 附带关联商品。
   */
  getCart() {
    var _a;
    const tempOrder = ((_a = this.store.order) == null ? void 0 : _a.getTempOrder()) ?? null;
    const salesDetail = this.getSalesOrder();
    const bookings = (salesDetail == null ? void 0 : salesDetail.bookings) ?? ((tempOrder == null ? void 0 : tempOrder.bookings) || []);
    return (0, import_cartView.buildCartView)((tempOrder == null ? void 0 : tempOrder.products) || [], bookings);
  }
  /**
   * 获取当前下单客户（与 OrderModule.tempOrder snapshot 一致）。
   */
  getCustomer() {
    return this.getOrderCustomerSnapshot();
  }
  /**
   * 通过 ids 获取商品列表（不加载到模块中）
   * @returns 商品列表
   */
  async getProductByIds(ids) {
    return this.store.products.getProductByIds(ids);
  }
  /**
   * 获取日程时间段点
   * @param params 参数
   * @returns 日程时间段点
   */
  async getScheduleTimePoints(params) {
    const result = await this.request.post("/menu/schedule-time-points", {
      menu_list_ids: params.menu_list_ids
    }, {
      osServer: true
    });
    return result.data || [];
  }
  /**
   * 获取客户列表
   * @param params 查询参数
   * @returns 客户列表响应
   */
  async getCustomerList(params = {}) {
    try {
      const result = await this.store.customer.getCustomerList(params);
      return result;
    } catch (error) {
      console.error("Failed to get customer list:", error);
      throw error;
    }
  }
  /**
   * 设置活跃客户
   * @param customer 客户信息
   */
  setActiveCustomer(customer) {
    this.store.customer.setSelectedCustomer(customer);
    this.core.effects.emit(`${this.name}:onCustomerSelected`, {
      customer
    });
  }
  /**
   * 获取当前活跃客户
   * @returns 当前活跃客户
   */
  getActiveCustomer() {
    return this.store.customer.getSelectedCustomer();
  }
  /**
   * 根据ID设置选中的客户
   * @param customerId 客户ID
   */
  setSelectedCustomerById(customerId) {
    const customer = this.store.customer.getCustomerById(customerId);
    if (customer) {
      this.store.customer.setSelectedCustomer(customer);
      this.core.effects.emit(`${this.name}:onCustomerSelected`, {
        customer
      });
    }
  }
  /**
   * 获取所有客户
   * @returns 客户列表
   */
  getCustomers() {
    return this.store.customer.getCustomers();
  }
  /**
   * 根据ID获取客户
   * @param customerId 客户ID
   * @returns 客户信息
   */
  getCustomerById(customerId) {
    return this.store.customer.getCustomerById(customerId);
  }
  /**
   * 清空客户列表
   */
  clearCustomers() {
    this.store.customer.clearCustomers();
  }
  /**
   * 添加客户到列表第一位
   * @param customer 要添加的客户信息
   */
  addCustomerToFirst(customer) {
    this.store.customer.addCustomerToFirst(customer);
  }
  // ─── 下单客户（基于 OrderModule.tempOrder，单一真源）───
  // 与老的 setActiveCustomer/getActiveCustomer 解耦：
  //  - 老路：写入 CustomerModule.selectedCustomer（保留兼容，存量调用方不动）
  //  - 新路：写入 tempOrder 的 customer 协议字段 + _extend.customerSnapshot
  // 新业务（如 SalesSdk）应优先使用本组方法。
  /**
   * 设置当前下单客户。
   *
   * @param customer 完整客户对象；null 表示清空
   *
   * 内部将 customer 格式化为 tempOrder 协议字段后写入 OrderModule，
   * 并以 customer 作为 snapshot 保存富字段。
   *
   * 同时透传 OrderModule 内部 emit 的 `order:onOrderCustomerChange` 之外，
   * 在 BookingTicket 命名空间也 emit 一次，方便上层统一从 Solution 订阅。
   */
  setOrderCustomer(customer) {
    if (!customer) {
      this.clearOrderCustomer();
      return;
    }
    const patch = (0, import_orderCustomer.formatOrderCustomerPatch)(customer);
    this.store.order.setOrderCustomer(patch, customer);
    const next = this.buildOrderCustomerPayload();
    this.core.effects.emit(`${this.name}:onOrderCustomerChange`, next);
    this.refreshDiscountConfigAfterOrderCustomerChange(patch.customer_id);
  }
  /**
   * 读取 tempOrder 上的下单客户协议字段；customer_id 缺失时返回 null。
   */
  getOrderCustomer() {
    return this.store.order.getOrderCustomer();
  }
  /**
   * 读取 tempOrder._extend.customerSnapshot 中的完整客户对象。
   */
  getOrderCustomerSnapshot() {
    return this.store.order.getOrderCustomerSnapshot();
  }
  /**
   * 清空下单客户（协议字段 + snapshot）。
   */
  clearOrderCustomer() {
    var _a, _b;
    this.store.order.clearOrderCustomer();
    const orderStore = this.store.order.store || {};
    const discountModule = orderStore.discount;
    void ((_a = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _a.call(discountModule, []));
    void ((_b = discountModule == null ? void 0 : discountModule.setDiscountList) == null ? void 0 : _b.call(discountModule, []));
    this.store.order.applyDiscount();
    void this.store.order.recalculateSummary({ createIfMissing: true }).then(() => this.store.order.persistTempOrder()).catch((error) => {
      console.error("Failed to recalculate summary after clearing customer:", error);
    });
    this.core.effects.emit(`${this.name}:onOrderCustomerChange`, null);
  }
  /**
   * 重置 tempOrder，并同步清空下单客户运行态。
   *
   * OrderModule.restoreOrder 会重建空单（customer_id 已为 null），但不会：
   *  - emit BookingTicket `onOrderCustomerChange`
   *  - 重置 CustomerModule.selectedCustomer（老路 getActiveCustomer）
   *
   * 因此在 super.restoreOrder 之后显式清客户，保证 SalesSdk / ticketBooking 订阅方与 tempOrder 一致。
   */
  async restoreOrder() {
    var _a;
    const tempOrder = await super.restoreOrder();
    this.clearOrderCustomer();
    (_a = this.store.customer) == null ? void 0 : _a.setSelectedCustomer(null);
    return tempOrder;
  }
  /** 内部：基于 OrderModule 当前状态构造一份 OrderCustomerChangePayload。 */
  buildOrderCustomerPayload() {
    const patch = this.store.order.getOrderCustomer();
    if (!patch)
      return null;
    return {
      patch,
      snapshot: this.store.order.getOrderCustomerSnapshot()
    };
  }
  refreshDiscountConfigAfterOrderCustomerChange(customerId) {
    if (!customerId || customerId === 1)
      return;
    if (this.orderCustomerDiscountRefreshInFlight && this.orderCustomerDiscountRefreshCustomerId === customerId) {
      return;
    }
    const previousRefresh = this.orderCustomerDiscountRefreshInFlight;
    const refreshTask = (async () => {
      if (previousRefresh) {
        await previousRefresh.catch(() => void 0);
      }
      const currentCustomer = this.store.order.getOrderCustomer();
      if (!currentCustomer || Number(currentCustomer.customer_id) !== customerId) {
        return;
      }
      await this.loadDiscountConfig({ customerId });
    })();
    this.orderCustomerDiscountRefreshInFlight = refreshTask;
    this.orderCustomerDiscountRefreshCustomerId = customerId;
    refreshTask.catch((error) => {
      console.error("Failed to load discount config after customer change:", error);
    }).finally(() => {
      if (this.orderCustomerDiscountRefreshInFlight !== refreshTask)
        return;
      this.orderCustomerDiscountRefreshInFlight = null;
      this.orderCustomerDiscountRefreshCustomerId = null;
    });
  }
  /**
   * 获取客户分页信息
   * @returns 分页信息
   */
  getCustomerPaginationInfo() {
    return this.store.customer.getPaginationInfo();
  }
  /**
   * 获取客户列表总数
   * @returns 总数
   */
  getCustomerTotal() {
    return this.store.customer.getState().total;
  }
  /**
   * 设置客户分页信息
   * @param page 页码
   * @param pageSize 每页数量
   */
  setCustomerPaginationInfo(page, pageSize) {
    this.store.customer.setPaginationInfo(page, pageSize);
  }
  /**
   * 便捷方法：切换客户分页并自动获取数据
   * @param page 页码
   * @param pageSize 每页数量（可选）
   * @returns 客户列表响应
   */
  async changeCustomerPage(page, pageSize) {
    try {
      const result = await this.store.customer.changeCustomerPage(
        page,
        pageSize
      );
      return result;
    } catch (error) {
      console.error("Failed to change customer page:", error);
      throw error;
    }
  }
  /**
   * 滚动加载更多客户数据 - 数据会追加到现有列表中
   * @returns 客户列表响应
   */
  async loadMoreCustomers() {
    try {
      const result = await this.store.customer.loadMoreCustomers();
      this.core.effects.emit(`${this.name}:onCustomerListUpdate`, result);
      return result;
    } catch (error) {
      console.error("Failed to load more customers:", error);
      throw error;
    }
  }
  /**
   * 重置并重新开始滚动加载客户数据
   * @param params 查询参数
   * @returns 客户列表响应
   */
  async resetAndLoadCustomers(params = {}) {
    try {
      const result = await this.store.customer.resetAndLoadCustomers(params);
      this.core.effects.emit(`${this.name}:onCustomerListReset`, result);
      return result;
    } catch (error) {
      console.error("Failed to reset and load customers:", error);
      throw error;
    }
  }
  /**
   * 检查是否还有更多客户数据可以加载
   * @returns 是否还有更多数据
   */
  hasMoreCustomers() {
    return this.store.customer.hasMoreCustomers();
  }
  /**
   * 获取当前的客户搜索条件
   * @returns 当前搜索条件
   */
  getCurrentCustomerSearchParams() {
    return this.store.customer.getCurrentSearchParams();
  }
  /**
   * 获取客户列表状态（包含滚动加载相关状态）
   * @returns 客户状态
   */
  getCustomerState() {
    return this.store.customer.getState();
  }
  /**
   * 全局扫描监听
   * @param callback 回调
   */
  scanGlobalListener(callback) {
    const localSearch = (v) => this.store.products.findProductsByCodeOrBarcode(v);
    const scanCallback = (0, import_handleScan.handleGlobalScan)(this.request, localSearch);
    const safeCallback = (d) => {
      try {
        callback(d);
      } catch (error) {
        console.error("scanGlobalListener传入的回调函数异常", error);
      }
    };
    const listener = { key: "global", callback: safeCallback };
    const removeListener = this.scan.addListener(listener, scanCallback);
    return removeListener;
  }
  /**
   * 客户扫描监听
   * @param callback 回调
   */
  scanCustomerListener(callback) {
    const scanCallback = (0, import_handleScan.handleCustomerScan)();
    const safeCallback = (d) => {
      try {
        callback(d);
      } catch (error) {
        console.error("scanCustomerListener传入的回调函数异常", error);
      }
    };
    const listener = { key: "customer", callback: safeCallback };
    const removeListener = this.scan.addListener(listener, scanCallback);
    return removeListener;
  }
  /**
   * @title 通用扫描监听
   * @description 直接将扫描结果返回给调用方
   * @param callback 回调
   */
  scanUniversalListener(callback, key) {
    const scanCallback = (0, import_handleScan.handleUniversalScan)();
    const safeCallback = (d) => {
      try {
        callback(d);
      } catch (error) {
        console.error(
          `scanUniversalListener传入的回调函数异常, key: ${key}`,
          error
        );
      }
    };
    const listener = { key, callback: safeCallback };
    const removeListener = this.scan.addListener(listener, scanCallback);
    return removeListener;
  }
  /**
   * 调用摄像头
   * @param data 用户自定义数据
   */
  activateCamera(data) {
    var _a, _b, _c, _d;
    (_d = (_c = (_b = (_a = this.window) == null ? void 0 : _a.interaction) == null ? void 0 : _b.utils) == null ? void 0 : _c.postMessageToApp) == null ? void 0 : _d.call(_c, {
      module: "global",
      key: "active_native_scanner",
      data
    });
  }
  /**
   * 禁用所有扫描监听
   */
  disableAllScanListeners() {
    this.scan.disableAllListeners();
  }
  /**
   * 启用所有扫描监听
   */
  enableAllScanListeners() {
    this.scan.enableAllListeners();
  }
  /**
   * 清空所有扫描监听对应的任务执行队列
   */
  clearAllScanListenersTaskQueue() {
    this.scan.clearTaskQueue();
  }
  /**
   * 设置其他参数
   * @param params 参数
   * @param options 选项
   */
  async setOtherParams(params, { cover = false } = {}) {
    if (cover) {
      this.otherParams = params;
    } else {
      this.otherParams = { ...this.otherParams, ...params };
    }
  }
  /**
   * 获取其他参数
   * @returns 其他参数
   */
  async getOtherParams() {
    return this.otherParams;
  }
  // ─── BookingContext API（透传给 BookingContextModule） ──────────────────────
  // SalesSdkProvider 挂载时默认调 initBookingContext；也可由 UI 显式 set* 灌入已有数据。
  /** 拉取 board config 并写入 BookingContext。 */
  loadBookingConfig(params) {
    return this.store.bookingContext.loadBookingConfig(params);
  }
  /** 拉取资源全集并写入 BookingContext。 */
  loadBookingResources(params) {
    return this.store.bookingContext.loadResources(params);
  }
  /** 初始化 BookingContext（date + config + resources）。 */
  initBookingContext(params) {
    return this.store.bookingContext.initBookingContext(params);
  }
  /** 当前 store 是否已具备与入参等价的 config / resources（无需再请求接口）。 */
  isBookingContextReady(params) {
    return this.store.bookingContext.isBookingContextReady(params);
  }
  /** 写入 booking config（来源：`/core/board/management/config`）。 */
  setBookingConfig(config) {
    this.store.bookingContext.setBookingConfig(config);
  }
  /** 读取当前 booking config。 */
  getBookingConfig() {
    return this.store.bookingContext.getBookingConfig();
  }
  /** 写入资源全集（来源：`/form/schedule`），同步派生 resourcesOriginMap。 */
  setResources(resources) {
    this.store.bookingContext.setResources(resources);
  }
  /** 读取资源全集（浅克隆）。 */
  getResourcesOrigin() {
    return this.store.bookingContext.getResourcesOrigin();
  }
  /** 读取资源全集 map（id → resource）。 */
  getResourcesOriginMap() {
    return this.store.bookingContext.getResourcesOriginMap();
  }
  /** 写入当前选择的日期；支持 dayjs / Date / string。 */
  setBookingDate(date) {
    this.store.bookingContext.setDate(date);
  }
  /** 读取当前选择的日期（统一 string）。 */
  getBookingDate() {
    return this.store.bookingContext.getDate();
  }
  /** 读取 BookingContext 完整 store（调试 / 测试 / 透传给 SDK 使用）。 */
  getBookingContextState() {
    return this.store.bookingContext.getState();
  }
  /** 清空 BookingContext（切租户 / destroy 场景）。 */
  clearBookingContext() {
    this.store.bookingContext.clear();
  }
  /**
   * 构造 BookingContext 计算上下文（供 getProductExtend / getResourceByIds 等读 API 复用）。
   */
  buildBookingCalcContext(extra) {
    const state = this.store.bookingContext.getState();
    const date = (extra == null ? void 0 : extra.date) ?? state.date;
    return {
      bookingConfig: state.bookingConfig,
      resourcesOrigin: state.resourcesOrigin,
      resourcesOriginMap: state.resourcesOriginMap,
      date,
      presetStartTime: (extra == null ? void 0 : extra.presetStartTime) ?? (0, import_BookingContext.derivePresetStartTimeFromDate)(date),
      ...extra || {}
    };
  }
  /**
   * 取商品当前可选资源列表（透传 OS BookingContext utils#getResourceByIds）。
   * `extraResources` 用于把拖入未绑定的资源也展示出来。
   */
  getResourcesForProduct(product, options) {
    var _a, _b;
    const ctx = this.buildBookingCalcContext();
    return (0, import_BookingContext.getResourceByIds)(ctx.resourcesOriginMap || {}, product, {
      resourceTab: (_b = (_a = ctx.bookingConfig) == null ? void 0 : _a.config) == null ? void 0 : _b.resource_tab,
      resourcesOrigin: ctx.resourcesOrigin,
      extraResources: (options == null ? void 0 : options.extraResources) || []
    });
  }
  /**
   * 拼装 cacheItem 的 _extend / _data（资源 / 容量 / timeObj），与 info2 `getProductExtend` 等价。
   */
  getProductExtend(cacheItem, extra) {
    return (0, import_BookingContext.getProductExtend)({
      cacheItem,
      ctx: this.buildBookingCalcContext(extra)
    });
  }
  /**
   * 取资源不可用原因列表（结构化 enum + params，i18n 文案由 UI 渲染）。
   */
  getResourceErrors(resource, cacheItem) {
    return (0, import_BookingContext.getResourceErrors)(resource, cacheItem);
  }
  // ─── addProduct 决策 / 转换 API（SDK 加车下沉所需） ─────────────────────────
  // 这一组方法是 SalesSdkCartContext.addProduct / confirmDetail 的 OS 后端。
  // 调用方传入 ProductData，OS 自取 bookingContext / customer / date 等上下文，
  // 输出 (a) autoClose 决策结果或 (b) `{ product, booking }` 协议入参。
  /**
   * 拼装 addProductDecision 通用上下文（从 store 自取）。
   */
  buildAddProductCtx(extra) {
    var _a, _b;
    const bookingContextState = this.store.bookingContext.getState();
    const date = (extra == null ? void 0 : extra.date) ?? bookingContextState.date;
    const orderCustomerId = ((_a = this.getOrderCustomerSnapshot()) == null ? void 0 : _a.id) ?? ((_b = this.store.order.getTempOrder()) == null ? void 0 : _b.customer_id) ?? void 0;
    return {
      bookingConfig: bookingContextState.bookingConfig,
      resourcesOrigin: bookingContextState.resourcesOrigin,
      resourcesOriginMap: bookingContextState.resourcesOriginMap,
      date,
      presetStartTime: (extra == null ? void 0 : extra.presetStartTime) ?? (0, import_BookingContext.derivePresetStartTimeFromDate)(date),
      customerId: orderCustomerId,
      ...extra || {}
    };
  }
  /**
   * 加车两阶段主决策（规格弹窗 / 资源编辑 / 直接加车）。
   * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
   */
  decideAddProduct(item, options) {
    return (0, import_addProductDecision.decideAddProduct)(item, this.buildAddProductCtx(options));
  }
  /** 规格弹窗 callback 后的第二段决策。 */
  decideAfterDetail(cacheItem, options) {
    return (0, import_addProductDecision.decideAfterDetail)(cacheItem, this.buildAddProductCtx(options));
  }
  /**
   * @deprecated 请用 `decideAddProduct`；`autoClose=true` 仅当 action=add。
   */
  decideAutoClose(item, options) {
    return (0, import_addProductDecision.decideAutoClose)(item, this.buildAddProductCtx(options));
  }
  /** 替代 info2 `getIsEject`：商品是否需要弹窗（0/1）。 */
  getIsEject(item, type = "select") {
    return (0, import_addProductDecision.getIsEject)(item, type);
  }
  /** 仅 session 商品（无 variant/option/package）→ true。 */
  getIsOnlySession(item) {
    return (0, import_addProductDecision.getIsOnlySession)(item);
  }
  /**
   * 拼装 requiresDetail payload（给 SDK 直接 return 给 UI 用）。
   */
  buildRequiresDetailPayload(item, options) {
    return (0, import_addProductDecision.buildRequiresDetailPayload)(item, this.buildAddProductCtx(options));
  }
  /**
   * 把 detail 弹窗回调结果（e, extension_type, detail）转换为 `(product, booking)` 入参。
   * 内部会先拼 cacheItem，再走 cacheItemToBookingInput 严格协议对齐。
   */
  transformDetailToProductAndBooking(input) {
    const { item, cacheItem: preparedCacheItem, detailResult, options } = input;
    const ctx = this.buildAddProductCtx(options);
    const cacheItem = preparedCacheItem || (detailResult ? (0, import_addProductDecision.buildCacheItemFromDetail)(item, detailResult, ctx) : (0, import_addProductDecision.buildCacheItemFromCartDetail)(item, ctx));
    return (0, import_addProductDecision.transformDetailToProductAndBooking)(cacheItem, ctx);
  }
  /**
   * 从已加车的 order line + booking 反查资源编辑抽屉所需的 cacheItem。
   * 供 SalesSdk「编辑资源」等场景使用；字段语义与 buildCacheItemFromDetail 产出对齐。
   */
  buildCacheItemFromOrderLine(input) {
    return (0, import_buildCacheItemFromOrderLine.buildCacheItemFromOrderLine)(input);
  }
  /**
   * 从已加车的普通商品 order line 反查 SkuDetailModal edit 所需的 cacheItem。
   */
  buildNormalProductCacheItemFromOrderLine(input) {
    return (0, import_buildNormalProductCacheItemFromOrderLine.buildNormalProductCacheItemFromOrderLine)(input);
  }
  /** 文档别名：与 OrderModule.updateOrderProduct 一致。 */
  async updateProductInOrder(params) {
    return this.updateOrderProduct(params);
  }
  /**
   * 销毁模块：先调用父类（销毁所有 store 内子模块 + emit destroy + super.destroy()），
   * 再清理 BookingTicket 自有资源（scan 监听 + scan 内存缓存）。
   */
  async destroy() {
    var _a;
    await super.destroy();
    try {
      (_a = this.scan) == null ? void 0 : _a.removeAllListeners();
    } catch (error) {
      console.warn("[BookingTicket] scan removeAllListeners 失败", error);
    }
    import_scanCache.default.clear();
  }
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  BookingTicket,
  BookingTicketImpl,
  ...require("./types")
});
