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/ScanOrder/index.ts
var ScanOrder_exports = {};
__export(ScanOrder_exports, {
  ScanOrderImpl: () => ScanOrderImpl
});
module.exports = __toCommonJS(ScanOrder_exports);
var import_BaseModule = require("../../modules/BaseModule");
var import_types = require("./types");
var import_Order = require("../../modules/Order");
var import_types2 = require("../../modules/Account/types");
var import_types3 = require("../RegisterAndLogin/types");
var import_decimal = __toESM(require("decimal.js"));
var import_utils = require("./utils");
var import_types4 = require("../BookingByStep/types");
var import_ProductList = require("../../modules/ProductList");
var import_Schedule = require("../../modules/Schedule");
var import_getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
var import_utils2 = require("../../modules/Order/utils");
var import_dayjs = __toESM(require("dayjs"));
var import_itemRule = require("../../model/strategy/adapter/itemRule");
__reExport(ScanOrder_exports, require("./types"), module.exports);
var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
  constructor(name, version) {
    super(name, version);
    this.defaultName = "scanOrder";
    this.defaultVersion = "1.0.0";
    this.isSolution = true;
    this.initializeOptions = {};
    this.store = {
      entryContext: null,
      status: "idle",
      config: null,
      resource: null,
      flow: {},
      error: null,
      products: void 0,
      itemRuleQuantityLimits: [],
      cartValidation: {
        passed: null,
        failures: []
      },
      entryPaxNumber: 1
    };
    this.otherParams = {};
    this.itemRuleEvaluator = new import_itemRule.ItemRuleEvaluator();
    this.itemRuleConfigs = [];
    this.itemRuleConfigsPromise = null;
    this.itemRulePrefillApplied = false;
    this.itemRuleRuntimeConfig = {};
    /** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
    this.enabledReservationRuleProducts = [];
    this.loginEffectDisposers = [];
    this.customerLoginRefreshInFlight = null;
    this.customerLoginRefreshIdInFlight = null;
  }
  getScanOrderLoggerContext() {
    return {
      cacheId: this.cacheId,
      solutionName: this.name,
      moduleName: "scanOrder"
    };
  }
  safeStringify(value) {
    try {
      return JSON.stringify(value);
    } catch {
      return void 0;
    }
  }
  pickErrorMessage(error) {
    var _a, _b, _c, _d;
    const candidates = [
      error.message,
      (_a = error.data) == null ? void 0 : _a.message,
      (_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.message,
      (_d = error.error) == null ? void 0 : _d.message
    ];
    for (const candidate of candidates) {
      if (typeof candidate === "string" && candidate.trim())
        return candidate;
    }
    return void 0;
  }
  serializeError(error) {
    if (error instanceof Error) {
      return {
        name: error.name,
        message: error.message,
        stack: error.stack
      };
    }
    if (error && typeof error === "object") {
      const raw = error;
      const message = this.pickErrorMessage(raw) || this.safeStringify(raw) || String(error);
      return {
        ...typeof raw.name === "string" ? { name: raw.name } : {},
        message,
        ..."code" in raw ? { code: raw.code } : {},
        ..."status" in raw ? { status: raw.status } : {},
        ...this.safeStringify(raw) ? { raw: this.safeStringify(raw) } : {}
      };
    }
    return {
      message: String(error)
    };
  }
  async addScanOrderLog(params) {
    const payload = {
      cacheId: this.cacheId,
      ...params.payload || {}
    };
    const extra = {
      ...params.extra || {}
    };
    const logger = this.store.scanOrderLogger;
    if (!logger) {
      if ((params.level || "info") === "error") {
        console.error("[ScanOrder][log-fallback]", params.title, { payload, extra });
      } else {
        console.log("[ScanOrder][log-fallback]", params.title, { payload, extra });
      }
      return;
    }
    await logger.addLog({
      ...params,
      payload,
      extra
    });
  }
  logMethodStart(method, payload = {}) {
    void this.addScanOrderLog({
      level: "info",
      title: `[ScanOrder] ${method} start`,
      payload: {
        method,
        ...payload
      }
    });
  }
  logMethodSuccess(method, payload = {}) {
    void this.addScanOrderLog({
      level: "info",
      title: `[ScanOrder] ${method} success`,
      payload: {
        method,
        ...payload
      }
    });
  }
  logMethodError(method, error, payload = {}) {
    void this.addScanOrderLog({
      level: "error",
      title: `[ScanOrder] ${method} failed`,
      payload: {
        method,
        ...payload,
        error: this.serializeError(error)
      }
    });
  }
  assertProductListLoaded(method, result, payload = {}) {
    if (Array.isArray(result))
      return result;
    const error = result instanceof Error ? result : new Error("商品列表接口返回异常");
    this.logMethodError(method, error, payload);
    error.__scanOrderLogged = true;
    throw error;
  }
  async addLog(params) {
    await this.addScanOrderLog({
      ...params,
      payload: {
        source: "ui-bridge",
        ...params.payload || {}
      }
    });
  }
  normalizeCustomerId(value) {
    const customerId = Number(value);
    if (!Number.isFinite(customerId) || customerId <= 0)
      return null;
    return customerId;
  }
  resolveCustomerIdFromLoginPayload(payload) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i;
    const candidates = [
      payload == null ? void 0 : payload.customerId,
      payload == null ? void 0 : payload.customer_id,
      payload == null ? void 0 : payload.id,
      (_a = payload == null ? void 0 : payload.user) == null ? void 0 : _a.customerId,
      (_b = payload == null ? void 0 : payload.user) == null ? void 0 : _b.customer_id,
      (_c = payload == null ? void 0 : payload.user) == null ? void 0 : _c.id,
      (_e = (_d = payload == null ? void 0 : payload.user) == null ? void 0 : _d._origin) == null ? void 0 : _e.customer_id,
      (_f = payload == null ? void 0 : payload.account) == null ? void 0 : _f.customerId,
      (_g = payload == null ? void 0 : payload.account) == null ? void 0 : _g.customer_id,
      (_h = payload == null ? void 0 : payload.account) == null ? void 0 : _h.id,
      (_i = payload == null ? void 0 : payload._origin) == null ? void 0 : _i.customer_id
    ];
    for (const candidate of candidates) {
      const customerId = this.normalizeCustomerId(candidate);
      if (customerId)
        return customerId;
    }
    return null;
  }
  clearLoginEffectListeners() {
    for (const dispose of this.loginEffectDisposers) {
      dispose();
    }
    this.loginEffectDisposers = [];
  }
  registerLoginEffect(event, callback) {
    var _a;
    const effects = (_a = this.core) == null ? void 0 : _a.effects;
    if (!(effects == null ? void 0 : effects.on))
      return;
    effects.on(event, callback);
    this.loginEffectDisposers.push(() => {
      if (typeof effects.off === "function") {
        effects.off(event, callback);
      }
    });
  }
  registerCustomerLoginListeners() {
    this.clearLoginEffectListeners();
    const createHandleLogin = () => async (payload) => {
      const customerId = this.resolveCustomerIdFromLoginPayload(payload);
      if (!customerId)
        return;
      await this.refreshOrderMarketingAfterLogin({ customerId });
    };
    this.registerLoginEffect(
      _ScanOrderImpl.PISELL1_LOGIN_SUCCESS,
      createHandleLogin()
    );
    this.registerLoginEffect(import_types2.AccountHooks.OnLogin, createHandleLogin());
    this.registerLoginEffect(
      import_types3.RegisterAndLoginHooks.onLoginSuccess,
      createHandleLogin()
    );
  }
  async refreshOrderMarketingAfterLogin(params) {
    if (!this.store.order)
      throw new Error("order 模块未初始化");
    if (this.customerLoginRefreshInFlight) {
      if (this.customerLoginRefreshIdInFlight === params.customerId) {
        await this.customerLoginRefreshInFlight;
        return;
      }
      await this.customerLoginRefreshInFlight;
    }
    this.customerLoginRefreshIdInFlight = params.customerId;
    const refreshTask = (async () => {
      await this.store.order.loadDiscountConfig({
        customerId: params.customerId
      });
      await this.store.order.recalculateSummary({ createIfMissing: true });
      this.store.order.persistTempOrder();
      await this.refreshItemRuleQuantityLimits();
      await this.refreshCartValidationPassed();
    })();
    this.customerLoginRefreshInFlight = refreshTask;
    try {
      await refreshTask;
    } catch (error) {
      throw error;
    } finally {
      if (this.customerLoginRefreshInFlight === refreshTask) {
        this.customerLoginRefreshInFlight = null;
        this.customerLoginRefreshIdInFlight = null;
      }
    }
  }
  /** 与 `otherParams.cacheId` 一致，供宿主在 URL 变化时判断是否需要重新注册模块 */
  getCacheId() {
    return this.cacheId;
  }
  async destroyRegisteredChildModules() {
    const modules = [
      this.store.schedule,
      this.store.salesSummary,
      this.store.order,
      this.store.products,
      this.store.scanOrderLogger
    ];
    for (const mod of modules) {
      if (mod && typeof mod.destroy === "function")
        await Promise.resolve(mod.destroy());
    }
  }
  async initialize(core, options = {}) {
    var _a, _b, _c, _d, _e, _f;
    this.logMethodStart("initialize");
    this.core = core;
    this.initializeOptions = options || {};
    this.store = { ...this.store, ...options.store };
    this.store.entryContext = ((_a = options.otherParams) == null ? void 0 : _a.entryContext) || this.store.entryContext;
    this.store.status = "initializing";
    this.store.error = null;
    this.otherParams = options.otherParams || {};
    this.cacheId = (_b = this.otherParams) == null ? void 0 : _b.cacheId;
    this.itemRuleRuntimeConfig = ((_c = this.otherParams) == null ? void 0 : _c.scanOrderItemRule) || ((_d = this.otherParams) == null ? void 0 : _d.itemRule) || {};
    this.itemRuleConfigs = [];
    this.itemRuleConfigsPromise = null;
    this.itemRulePrefillApplied = false;
    this.store.itemRuleQuantityLimits = [];
    this.store.cartValidation = {
      passed: null,
      failures: []
    };
    this.window = core.getPlugin("window");
    this.request = core.getPlugin("request");
    if (!this.window) {
      this.logMethodError("initialize", "window plugin missing");
      throw new Error("scanOrder解决方案需要 window 插件支持");
    }
    if (!this.request) {
      this.logMethodError("initialize", "request plugin missing");
      throw new Error("scanOrder解决方案需要 request 插件支持");
    }
    const moduleArr = [
      "scanOrderLogger",
      "products",
      "order",
      "salesSummary"
    ];
    moduleArr.forEach((step) => {
      var _a2, _b2, _c2, _d2, _e2, _f2;
      const targetModule = (0, import_types4.createModule)(step, this.name);
      if (targetModule) {
        this.store[step] = targetModule;
        const initialState = step === "salesSummary" ? {
          summary: ((_b2 = (_a2 = this.store.order) == null ? void 0 : _a2.getTempOrder()) == null ? void 0 : _b2.summary) || (0, import_utils.createEmptySummary)()
        } : {};
        const loggerProvider = ((_c2 = this.otherParams) == null ? void 0 : _c2.scanOrderLoggerProvider) || "feishu";
        const loggerConfig = ((_d2 = this.otherParams) == null ? void 0 : _d2.scanOrderLoggerConfig) || {
          feishu: {
            webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed",
            errorHook: "https://open.feishu.cn/open-apis/bot/v2/hook/015b7c2a-dd3c-4c30-9898-ef0f5253111f"
          }
        };
        this.core.registerModule(targetModule, {
          initialState,
          otherParams: {
            ...this.otherParams,
            fatherModule: this.name,
            openCache: ((_e2 = this.otherParams) == null ? void 0 : _e2.cacheId) ? true : false,
            cacheId: (_f2 = this.otherParams) == null ? void 0 : _f2.cacheId,
            salesSummaryModuleName: `${this.name}_salesSummary`,
            provider: loggerProvider,
            providerConfig: loggerConfig,
            context: this.getScanOrderLoggerContext()
          }
        });
      } else {
        this.logMethodError("initialize", `module ${step} missing`);
        throw new Error(`模块 ${step} 不存在`);
      }
    });
    if (this.store.scanOrderLogger) {
      this.store.scanOrderLogger.setContext(this.getScanOrderLoggerContext());
    }
    const scheduleModule = new import_Schedule.ScheduleModule(`${this.name}_schedule`);
    this.store.schedule = scheduleModule;
    this.core.registerModule(scheduleModule, {
      otherParams: {
        ...this.otherParams,
        fatherModule: this.name
      }
    });
    this.registerCustomerLoginListeners();
    console.log("[ScanOrder] 初始化开始");
    try {
      await ((_e = this.store.order) == null ? void 0 : _e.recalculateSummary({ createIfMissing: false }));
      (_f = this.store.order) == null ? void 0 : _f.persistTempOrder();
      await this.loadRuntimeConfigs();
      if (this.store.schedule) {
        try {
          await this.store.schedule.loadAllSchedule();
        } catch (scheduleError) {
          console.warn("[ScanOrder] loadAllSchedule 失败，operating_hours 判定将跳过", scheduleError);
        }
      }
      await this.refreshItemRuleQuantityLimits();
      this.store.status = "ready";
      console.log("[ScanOrder] 初始化完成");
      await this.core.effects.emit(import_types.ScanOrderHooks.onInited, {
        status: this.store.status
      });
      this.logMethodSuccess("initialize", {
        status: this.store.status
      });
    } catch (error) {
      this.store.status = "error";
      this.store.error = error instanceof Error ? error.message : "初始化失败";
      console.error("[ScanOrder] 初始化失败", error);
      this.logMethodError("initialize", error, {
        status: this.store.status
      });
      throw error;
    }
  }
  async destroy() {
    this.logMethodStart("destroy");
    this.clearLoginEffectListeners();
    await this.core.effects.emit(import_types.ScanOrderHooks.onDestroy, {});
    await this.destroyRegisteredChildModules();
    super.destroy();
    console.log("[ScanOrder] 已销毁");
    this.logMethodSuccess("destroy");
  }
  async retryInit() {
    this.logMethodStart("retryInit");
    console.log("[ScanOrder] retryInit 调用");
    await this.core.effects.emit(import_types.ScanOrderHooks.onRetryInit, {});
    try {
      await this.initialize(this.core, this.initializeOptions);
      this.logMethodSuccess("retryInit");
    } catch (error) {
      this.logMethodError("retryInit", error);
      throw error;
    }
  }
  async refresh() {
    this.logMethodStart("refresh");
    console.log("[ScanOrder] refresh 调用");
    try {
      this.store.status = "initializing";
      await this.loadRuntimeConfigs();
      await this.refreshItemRuleQuantityLimits();
      this.store.status = "ready";
      await this.core.effects.emit(import_types.ScanOrderHooks.onRefresh, {
        status: this.store.status
      });
      this.logMethodSuccess("refresh", {
        status: this.store.status
      });
    } catch (error) {
      this.logMethodError("refresh", error);
      throw error;
    }
  }
  getStatus() {
    this.logMethodStart("getStatus");
    const result = this.store.status;
    this.logMethodSuccess("getStatus", {
      status: result
    });
    return result;
  }
  getEntryContext() {
    this.logMethodStart("getEntryContext");
    const result = this.store.entryContext;
    this.logMethodSuccess("getEntryContext", {
      hasEntryContext: Boolean(result)
    });
    return result;
  }
  getConfig() {
    this.logMethodStart("getConfig");
    const result = this.store.config || {};
    this.logMethodSuccess("getConfig", {
      configKeys: Object.keys(result || {})
    });
    return result;
  }
  getItemRuleQuantityLimits() {
    this.logMethodStart("getItemRuleQuantityLimits");
    const result = this.store.itemRuleQuantityLimits || [];
    this.logMethodSuccess("getItemRuleQuantityLimits", {
      limitCount: result.length
    });
    return result;
  }
  getCartValidationPassed() {
    var _a;
    this.logMethodStart("getCartValidationPassed");
    const result = ((_a = this.store.cartValidation) == null ? void 0 : _a.passed) ?? null;
    this.logMethodSuccess("getCartValidationPassed", {
      cartValidationPassed: result
    });
    return result;
  }
  getCartValidation() {
    this.logMethodStart("getCartValidation");
    const result = this.store.cartValidation || {
      passed: null,
      failures: []
    };
    this.logMethodSuccess("getCartValidation", {
      cartValidationPassed: result.passed,
      failureCount: Array.isArray(result.failures) ? result.failures.length : 0
    });
    return result;
  }
  getTempOrder() {
    var _a, _b, _c;
    this.logMethodStart("getTempOrder");
    const result = ((_a = this.store.order) == null ? void 0 : _a.getTempOrder()) || null;
    this.logMethodSuccess("getTempOrder", {
      hasTempOrder: Boolean(result),
      productCount: ((_b = result == null ? void 0 : result.products) == null ? void 0 : _b.length) || 0,
      noteLength: ((_c = result == null ? void 0 : result.note) == null ? void 0 : _c.length) || 0
    });
    return result;
  }
  updateTempOrderNote(note) {
    this.logMethodStart("updateTempOrderNote", {
      noteLength: String(note || "").length
    });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const result = this.store.order.updateTempOrderNote(note);
      this.logMethodSuccess("updateTempOrderNote", {
        noteLength: result.length
      });
      return result;
    } catch (error) {
      this.logMethodError("updateTempOrderNote", error);
      throw error;
    }
  }
  // 存储 UI 层选择的取餐方式到 tempOrder.metadata.shop_service_data
  // service_type 在扫码点餐场景固定为 dine_in
  setPickupReferenceMode(mode) {
    this.logMethodStart("setPickupReferenceMode", { mode });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const tempOrder = this.store.order.ensureTempOrder();
      tempOrder.metadata = {
        ...tempOrder.metadata || {},
        shop_service_data: {
          ...(tempOrder.metadata || {}).shop_service_data || {},
          service_type: "dine_in",
          pickup_reference_mode: mode
        }
      };
      this.store.order.persistTempOrder();
      this.logMethodSuccess("setPickupReferenceMode", {
        mode
      });
      return tempOrder.metadata.shop_service_data;
    } catch (error) {
      this.logMethodError("setPickupReferenceMode", error, { mode });
      throw error;
    }
  }
  // 存储用户自定义取餐标识到 tempOrder.buzzer
  setPickupRef(buzzer) {
    this.logMethodStart("setPickupRef", {
      buzzerLength: String(buzzer || "").length
    });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const result = this.store.order.updateTempOrderBuzzer(buzzer);
      this.logMethodSuccess("setPickupRef", {
        buzzerLength: result.length
      });
      return result;
    } catch (error) {
      this.logMethodError("setPickupRef", error);
      throw error;
    }
  }
  ensureTempOrder() {
    if (!this.store.order)
      throw new Error("order 模块未初始化");
    return this.store.order.ensureTempOrder();
  }
  // 主动创建临时订单；若已存在则直接返回已有订单
  async addNewOrder() {
    this.logMethodStart("addNewOrder");
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const tempOrder = await this.store.order.addNewOrder();
      this.logMethodSuccess("addNewOrder", {
        productCount: tempOrder.products.length
      });
      return tempOrder;
    } catch (error) {
      this.logMethodError("addNewOrder", error);
      throw error;
    }
  }
  // 重置 tempOrder 与与上一单强相关的运行态（resource/entryPaxNumber/enabledReservationRuleProducts），
  // 适用于从支付页通过 react-router 跳回继续下单时清理残留数据
  async restoreOrder() {
    this.logMethodStart("restoreOrder");
    try {
      if (!this.store.order) {
        throw new Error("scanOrder 解决方案需要 order 模块支持");
      }
      this.store.resource = null;
      this.store.entryPaxNumber = 1;
      this.enabledReservationRuleProducts = [];
      const tempOrder = this.store.order.restoreOrder();
      this.logMethodSuccess("restoreOrder");
      return tempOrder;
    } catch (error) {
      this.logMethodError("restoreOrder", error);
      throw error;
    }
  }
  getOrderProducts() {
    this.logMethodStart("getOrderProducts");
    if (!this.store.order)
      throw new Error("order 模块未初始化");
    const products = this.store.order.getOrderProducts();
    this.logMethodSuccess("getOrderProducts", {
      productCount: products.length
    });
    return products;
  }
  async getSummary() {
    this.logMethodStart("getSummary");
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const summary = await this.store.order.getOrderSummary();
      this.logMethodSuccess("getSummary", {
        totalAmount: summary.total_amount
      });
      return summary;
    } catch (error) {
      this.logMethodError("getSummary", error);
      throw error;
    }
  }
  getDiscountList() {
    if (!this.store.order)
      return [];
    return this.store.order.getDiscountList();
  }
  async scanCode(code, customerId) {
    this.logMethodStart("scanCode", { code });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const raw = await this.store.order.scanCode(code, customerId);
      if (raw.isAvailable) {
        await this.store.order.recalculateSummary({ createIfMissing: true });
        this.store.order.persistTempOrder();
      }
      this.logMethodSuccess("scanCode", { isAvailable: raw.isAvailable });
      return {
        isAvailable: raw.isAvailable,
        type: raw.type,
        unavailableReason: raw.unavailableReason
      };
    } catch (error) {
      this.logMethodError("scanCode", error);
      throw error;
    }
  }
  async setDiscountSelected(params) {
    var _a, _b, _c, _d, _e;
    this.logMethodStart("setDiscountSelected", params);
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const list = this.store.order.getDiscountList();
      const updated = list.map(
        (d) => d.id === params.discountId ? {
          ...d,
          isSelected: params.isSelected,
          isManualSelect: !params.isSelected
        } : d
      );
      const tempOrder = this.store.order.ensureTempOrder();
      const orderStore = this.store.order.store || {};
      const discountModule = orderStore.discount;
      const rulesModule = orderStore.rules;
      const holders = ((_a = tempOrder.holder) == null ? void 0 : _a.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
      let nextDiscountList = updated;
      await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
      if (rulesModule) {
        const result = rulesModule.calcDiscount(
          {
            productList: tempOrder.products,
            discountList: updated,
            holders,
            isFormSubject: !!((_b = tempOrder.holder) == null ? void 0 : _b.type) && tempOrder.holder.type === "form"
          },
          {
            discountId: params.discountId,
            isSelected: params.isSelected
          }
        ) || { productList: tempOrder.products, discountList: updated };
        if (result == null ? void 0 : result.productList) {
          tempOrder.products = result.productList;
        }
        if (result == null ? void 0 : result.discountList) {
          nextDiscountList = result.discountList;
          if (!params.isSelected) {
            const beforeSelectedIds = new Set(
              updated.filter((d) => d.isSelected).map((d) => d.id)
            );
            for (const d of nextDiscountList) {
              if (d.isSelected && !beforeSelectedIds.has(d.id)) {
                d.isSelected = false;
              }
            }
          }
        }
      }
      const selectedResourceIds = new Set(
        nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
      );
      for (const product of tempOrder.products) {
        if ((_c = product._origin) == null ? void 0 : _c.isManualDiscount)
          continue;
        product.discount_list = (product.discount_list || []).filter((pd) => {
          var _a2;
          const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
          return rid != null && selectedResourceIds.has(rid);
        });
        const totalPerUnitDiscount = (product.discount_list || []).reduce(
          (sum, pd) => sum + (pd.amount || 0),
          0
        );
        const optionSum = (0, import_utils2.sumOptionUnitPrice)(product.product_option_item);
        const sourcePrice = ((_d = product.metadata) == null ? void 0 : _d.source_product_price) ?? (((_e = product.metadata) == null ? void 0 : _e.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
        const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
        const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
        if (product.metadata) {
          product.metadata.main_product_selling_price = newMainSellingPrice;
          product.metadata.price_schema_version = 2;
        }
        product.selling_price = (0, import_utils2.composeLinePrice)({
          mainPrice: newMainSellingPrice,
          bundle: product.product_bundle
        });
      }
      import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
      await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
      tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
      await this.store.order.recalculateSummary({ createIfMissing: true });
      this.store.order.persistTempOrder();
      this.logMethodSuccess("setDiscountSelected", params);
    } catch (error) {
      this.logMethodError("setDiscountSelected", error);
      throw error;
    }
  }
  async onCustomerLogin(params) {
    this.logMethodStart("onCustomerLogin", { customerId: params.customerId });
    try {
      await this.refreshOrderMarketingAfterLogin({
        customerId: params.customerId
      });
      this.logMethodSuccess("onCustomerLogin", { customerId: params.customerId });
    } catch (error) {
      this.logMethodError("onCustomerLogin", error);
      throw error;
    }
  }
  findReservationRuleResource(formId) {
    var _a;
    if (formId == null)
      return void 0;
    const numericFormId = Number(formId);
    if (!Number.isFinite(numericFormId) || numericFormId <= 0)
      return void 0;
    for (const product of this.enabledReservationRuleProducts) {
      const resources = (_a = product == null ? void 0 : product.product_resource) == null ? void 0 : _a.resources;
      if (!Array.isArray(resources))
        continue;
      const matched = resources.find((resource) => Number(resource == null ? void 0 : resource.id) === numericFormId);
      if (matched)
        return matched;
    }
    return void 0;
  }
  buildScanOrderResourceMetadata(params) {
    const { resourceState, resourceName } = params;
    const ruleResource = this.findReservationRuleResource(resourceState.tableFormId);
    const combined = ruleResource == null ? void 0 : ruleResource.combined_resource;
    const isCombined = !!(combined && combined.status === 1 && Array.isArray(combined.resource_ids));
    return {
      form_name: (ruleResource == null ? void 0 : ruleResource.title) ?? "",
      resource_name: resourceName,
      combined_resource: isCombined ? combined : null
    };
  }
  // ScanOrder 提交 payload enhancer：
  // - 给所有 booking 注入 appointment_status: 'started'（扫码点餐语义）
  // - 给所有 booking 的 metadata 注入 resource_select_type（来自预约规则商品的 resource.type）
  // - 给第一条 booking 补 resources 与 product_uid（仅当存在 resource / rule product）
  // - 追加一条 is_rule=true 的 rule product，与 booking 互相关联
  buildSubmitPayloadEnhancer() {
    const ruleProduct = this.enabledReservationRuleProducts[0];
    const resourceState = this.store.resource;
    const resourceSelectType = resourceState == null ? void 0 : resourceState.resourceSelectType;
    const resolveResourceCapacity = () => {
      var _a;
      if (resourceSelectType === "single") {
        const raw = (_a = resourceState == null ? void 0 : resourceState.table_form_record) == null ? void 0 : _a.capacity;
        const num = Number(raw);
        if (Number.isFinite(num) && num > 0)
          return num;
        return 1;
      }
      return 1;
    };
    return (payload, { bookingUuid, tempOrder }) => {
      var _a, _b;
      const resourceId = tempOrder.resource_id ?? (resourceState == null ? void 0 : resourceState.relationId);
      const rawCollectPax = (_a = tempOrder.metadata) == null ? void 0 : _a.collect_pax;
      const hasCollectPaxForCapacity = rawCollectPax !== null && rawCollectPax !== void 0 && rawCollectPax !== "";
      const resourceCapacityValue = hasCollectPaxForCapacity ? (0, import_utils2.normalizeSubmitCollectPaxValue)(rawCollectPax) : resolveResourceCapacity();
      const pickOriginal = (value) => {
        if (value && typeof value === "object" && !Array.isArray(value)) {
          const original = value.original;
          return typeof original === "string" && original.length > 0 ? original : void 0;
        }
        return void 0;
      };
      const mainField = pickOriginal(tempOrder.table_number) ?? pickOriginal((_b = resourceState == null ? void 0 : resourceState.table_form_record) == null ? void 0 : _b.name) ?? "";
      const resourceEntry = resourceState && resourceId ? {
        relation_type: "form",
        like_status: "common",
        id: Number(resourceId),
        main_field: mainField,
        form_id: resourceState.tableFormId,
        relation_id: resourceState.relationId ?? resourceId,
        capacity: resourceCapacityValue,
        metadata: this.buildScanOrderResourceMetadata({
          resourceState,
          resourceName: mainField
        })
      } : void 0;
      const ruleProductUid = ruleProduct ? (0, import_utils2.createUuidV4)() : void 0;
      const bookingCapacityValue = resourceCapacityValue;
      const bookingCapacityDimensionId = (0, import_utils.pickFirstCustomCapacityDimensionId)(this.enabledReservationRuleProducts) ?? 0;
      const nextBookings = (payload.bookings || []).map((booking, idx) => ({
        ...booking,
        number: bookingCapacityValue,
        appointment_status: "started",
        metadata: {
          ...booking.metadata || {},
          ...resourceSelectType ? { resource_select_type: resourceSelectType } : {},
          ...resourceSelectType ? {
            capacity: [
              {
                id: bookingCapacityDimensionId,
                value: bookingCapacityValue,
                name: ""
              }
            ]
          } : {}
        },
        ...idx === 0 && resourceEntry ? { resources: [resourceEntry] } : {},
        ...idx === 0 && ruleProductUid ? { product_uid: ruleProductUid } : {}
      }));
      const nextProducts = [...payload.products || []];
      if (ruleProduct && ruleProductUid && !tempOrder.order_id) {
        const sellingPrice = String(ruleProduct.price ?? "0.00");
        const originalPrice = String(
          ruleProduct.original_price ?? ruleProduct.price ?? "0.00"
        );
        nextProducts.push({
          product_id: ruleProduct.id,
          product_variant_id: 0,
          num: 1,
          selling_price: sellingPrice,
          original_price: originalPrice,
          payment_price: sellingPrice,
          is_charge_tax: ruleProduct.is_gst ?? 0,
          product_option_item: [],
          discount_list: [],
          product_bundle: [],
          booking_uid: bookingUuid,
          metadata: {
            is_rule: true,
            unique_identification_number: ruleProductUid,
            booking_uid: bookingUuid
          }
        });
      }
      return { ...payload, bookings: nextBookings, products: nextProducts };
    };
  }
  async submitScanOrder() {
    var _a, _b, _c, _d, _e, _f, _g;
    this.logMethodStart("submitScanOrder");
    try {
      await this.validateBeforeSubmitByItemRule();
      if (!this.store.order) {
        throw new Error("scanOrder解决方案需要 order 模块支持");
      }
      const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(this.store.entryPaxNumber);
      this.store.entryPaxNumber = pax;
      const tempOrderForSubmit = this.store.order.ensureTempOrder();
      tempOrderForSubmit.metadata = { ...tempOrderForSubmit.metadata, collect_pax: pax };
      tempOrderForSubmit.delivery_type = "shop_service";
      const resourceTableName = (_b = (_a = this.store.resource) == null ? void 0 : _a.table_form_record) == null ? void 0 : _b.name;
      if (resourceTableName && typeof resourceTableName === "object") {
        tempOrderForSubmit.table_number = resourceTableName;
      } else {
        delete tempOrderForSubmit.table_number;
      }
      this.store.order.persistTempOrder();
      const enhancePayload = this.buildSubmitPayloadEnhancer();
      const result = await this.store.order.submitTempOrder({
        cacheId: this.cacheId,
        platform: (_c = this.otherParams) == null ? void 0 : _c.platform,
        businessCode: (_d = this.otherParams) == null ? void 0 : _d.businessCode,
        channel: (_e = this.otherParams) == null ? void 0 : _e.channel,
        type: (_f = this.otherParams) == null ? void 0 : _f.type,
        enhancePayload
      });
      const tempOrder = this.store.order.getTempOrder();
      this.logMethodSuccess("submitScanOrder", {
        productCount: ((_g = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _g.length) || 0
      });
      return result;
    } catch (error) {
      this.logMethodError("submitScanOrder", error);
      throw error;
    }
  }
  async addProductToOrder(product) {
    this.logMethodStart("addProductToOrder", {
      product_id: product.product_id,
      product_variant_id: product.product_variant_id
    });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const products = await this.store.order.addProductToOrder(product);
      await this.refreshItemRuleQuantityLimits();
      await this.refreshCartValidationPassed();
      this.logMethodSuccess("addProductToOrder", {
        productCount: products.length
      });
      return products;
    } catch (error) {
      this.logMethodError("addProductToOrder", error);
      throw error;
    }
  }
  async updateOrderProduct(params) {
    this.logMethodStart("updateOrderProduct", {
      product_id: params.product_id,
      product_variant_id: params.product_variant_id
    });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const products = await this.store.order.updateOrderProduct(params);
      await this.refreshItemRuleQuantityLimits();
      await this.refreshCartValidationPassed();
      this.logMethodSuccess("updateOrderProduct", {
        productCount: products.length
      });
      return products;
    } catch (error) {
      this.logMethodError("updateOrderProduct", error);
      throw error;
    }
  }
  /**
   * 设置单行商品备注（与整单 `updateTempOrderNote` 区分）。
   * 多行同 SKU 时必须传入与删除/更新一致的 identity（如 `identity_key`）。
   */
  async setOrderProductLineNote(identity, note) {
    this.logMethodStart("setOrderProductLineNote", {
      product_id: identity.product_id,
      product_variant_id: identity.product_variant_id
    });
    try {
      const params = {
        product_id: identity.product_id,
        product_variant_id: identity.product_variant_id,
        updates: { note: String(note || "") }
      };
      if (identity.identity_key !== void 0)
        params.identity_key = identity.identity_key;
      if (identity.product_option_item !== void 0) {
        params.product_option_item = identity.product_option_item;
      }
      if (identity.product_bundle !== void 0)
        params.product_bundle = identity.product_bundle;
      const products = await this.updateOrderProduct(params);
      this.logMethodSuccess("setOrderProductLineNote", { productCount: products.length });
      return products;
    } catch (error) {
      this.logMethodError("setOrderProductLineNote", error);
      throw error;
    }
  }
  async removeProductFromOrder(identity) {
    this.logMethodStart("removeProductFromOrder", {
      product_id: identity.product_id,
      product_variant_id: identity.product_variant_id
    });
    try {
      if (!this.store.order)
        throw new Error("order 模块未初始化");
      const products = await this.store.order.removeProductFromOrder(identity);
      await this.refreshItemRuleQuantityLimits();
      await this.refreshCartValidationPassed();
      this.logMethodSuccess("removeProductFromOrder", {
        productCount: products.length
      });
      return products;
    } catch (error) {
      this.logMethodError("removeProductFromOrder", error);
      throw error;
    }
  }
  async loadRuntimeConfigs() {
    const itemRuleConfigs = await this.ensureItemRuleConfigsLoaded();
    this.logMethodSuccess("loadRuntimeConfigs", {
      itemRuleCount: itemRuleConfigs.length
    });
    return {
      itemRuleConfigs
    };
  }
  async syncItemRuleConfigsFromDineInConfig(dineInConfig) {
    const enableItemRules = (0, import_utils.toBoolean)(dineInConfig == null ? void 0 : dineInConfig["sale.enable_item_rules"]);
    const strategyModelIds = (0, import_utils.normalizeEnabledItemRuleIds)(
      dineInConfig == null ? void 0 : dineInConfig["sale.enabled_item_rules"]
    );
    if (!enableItemRules || !strategyModelIds.length) {
      this.itemRuleConfigs = [];
      this.itemRuleConfigsPromise = Promise.resolve([]);
      this.itemRuleEvaluator.setStrategyConfigs([]);
      this.logMethodSuccess("syncItemRuleConfigsFromDineInConfig", {
        enabled: enableItemRules,
        strategyModelIds: [],
        itemRuleCount: 0
      });
      return [];
    }
    const itemRuleConfigs = await this.fetchItemRuleConfigsByModelIds(
      strategyModelIds
    );
    this.itemRuleConfigs = itemRuleConfigs;
    this.itemRuleConfigsPromise = Promise.resolve(itemRuleConfigs);
    this.itemRuleEvaluator.setStrategyConfigs(itemRuleConfigs);
    this.logMethodSuccess("syncItemRuleConfigsFromDineInConfig", {
      enabled: enableItemRules,
      strategyModelIds,
      itemRuleCount: itemRuleConfigs.length
    });
    return itemRuleConfigs;
  }
  async fetchItemRuleConfigsByModelIds(strategyModelIds) {
    this.logMethodStart("fetchItemRuleConfigsByModelIds", {
      strategyModelIds
    });
    if (!strategyModelIds.length)
      return [];
    try {
      const result = await this.request.get("/promotion", {
        skip: 1,
        num: 99,
        status: "active",
        ids: strategyModelIds
      });
      let configs = [];
      if (result.code === 200) {
        configs = result.data.list.map((item) => {
          return item.metadata;
        });
      }
      this.logMethodSuccess("fetchItemRuleConfigsByModelIds", {
        strategyModelIds,
        strategyCount: configs.length
      });
      return configs;
    } catch (error) {
      this.logMethodError("fetchItemRuleConfigsByModelIds", error, {
        strategyModelIds
      });
      return [];
    }
  }
  async buildPrefillProductSourceMap() {
    const sourceMap = /* @__PURE__ */ new Map();
    try {
      const productList = await this.getProductList();
      if (!Array.isArray(productList))
        return sourceMap;
      const visited = /* @__PURE__ */ new Set();
      const collectFromValue = (value) => {
        if (!value || typeof value !== "object")
          return;
        if (visited.has(value))
          return;
        visited.add(value);
        if (Array.isArray(value)) {
          for (const item of value)
            collectFromValue(item);
          return;
        }
        const node = value;
        const rawProductId = node.product_id ?? node.id;
        const productId = Number(rawProductId);
        if (Number.isFinite(productId) && productId > 0) {
          const productVariantId = Number(
            node.product_variant_id ?? node.variant_id ?? 0
          );
          const normalizedVariantId = Number.isNaN(productVariantId) ? 0 : productVariantId;
          const key = (0, import_utils.buildProductKey)(productId, normalizedVariantId);
          if (!sourceMap.has(key)) {
            sourceMap.set(key, node);
          }
        }
        for (const childValue of Object.values(node)) {
          if (childValue && typeof childValue === "object") {
            collectFromValue(childValue);
          }
        }
      };
      collectFromValue(productList);
    } catch (error) {
      this.logMethodError("buildPrefillProductSourceMap", error);
    }
    return sourceMap;
  }
  getItemRuleRuntimeConfig() {
    return this.itemRuleRuntimeConfig || {};
  }
  async ensureItemRuleConfigsLoaded() {
    if (this.itemRuleConfigs.length > 0)
      return this.itemRuleConfigs;
    if (this.itemRuleConfigsPromise)
      return this.itemRuleConfigsPromise;
    this.itemRuleConfigsPromise = (async () => {
      const runtimeConfig = this.getItemRuleRuntimeConfig();
      const staticConfigs = (0, import_utils.normalizeItemRuleStrategies)(runtimeConfig.strategyConfigs);
      if (staticConfigs.length > 0) {
        this.itemRuleConfigs = staticConfigs;
        this.itemRuleEvaluator.setStrategyConfigs(staticConfigs);
        return this.itemRuleConfigs;
      }
      this.itemRuleConfigs = [];
      this.itemRuleEvaluator.setStrategyConfigs([]);
      return this.itemRuleConfigs;
    })();
    const loadedConfigs = await this.itemRuleConfigsPromise;
    return loadedConfigs;
  }
  async refreshItemRuleQuantityLimits() {
    try {
      const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
      if (!strategyConfigs.length) {
        this.store.itemRuleQuantityLimits = [];
        return [];
      }
      const businessData = (0, import_utils.buildItemRuleBusinessData)({
        tempOrder: this.ensureTempOrder(),
        runtimeConfig: this.getItemRuleRuntimeConfig(),
        itemRuleConfigs: this.itemRuleConfigs
      });
      const limits = this.itemRuleEvaluator.getQuantityLimits(businessData);
      this.store.itemRuleQuantityLimits = limits;
      this.logMethodSuccess("refreshItemRuleQuantityLimits", {
        limitCount: limits.length
      });
      return limits;
    } catch (error) {
      this.store.itemRuleQuantityLimits = [];
      this.logMethodError("refreshItemRuleQuantityLimits", error);
      return [];
    }
  }
  async applyPrefillByItemRule() {
    var _a, _b, _c;
    if (this.itemRulePrefillApplied)
      return;
    if (!this.store.order)
      return;
    const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
    if (!strategyConfigs.length)
      return;
    const businessData = (0, import_utils.buildItemRuleBusinessData)({
      tempOrder: this.ensureTempOrder(),
      runtimeConfig: this.getItemRuleRuntimeConfig(),
      itemRuleConfigs: this.itemRuleConfigs
    });
    const prefillItems = this.itemRuleEvaluator.getPrefillItems(businessData);
    if (!prefillItems.length) {
      this.itemRulePrefillApplied = true;
      return;
    }
    const productSourceMap = await this.buildPrefillProductSourceMap();
    const tempOrder = this.ensureTempOrder();
    let hasChanges = false;
    for (const prefillItem of prefillItems) {
      const productId = Number(prefillItem.product_id);
      const productVariantId = Number(prefillItem.product_variant_id ?? 0);
      const targetQuantity = (0, import_utils.toNonNegativeInt)(prefillItem.quantity);
      if (!Number.isFinite(productId) || targetQuantity <= 0)
        continue;
      if (Number.isNaN(productVariantId))
        continue;
      const sourceItem = productSourceMap.get(
        (0, import_utils.buildProductKey)(productId, productVariantId)
      ) || productSourceMap.get((0, import_utils.buildProductKey)(productId, 0)) || null;
      const productIndex = (0, import_utils.getProductIdentityIndex)(tempOrder.products, {
        product_id: productId,
        product_variant_id: productVariantId
      });
      if (productIndex === -1) {
        const sellingPrice = (0, import_utils.toPriceString)(
          (sourceItem == null ? void 0 : sourceItem.price) ?? (sourceItem == null ? void 0 : sourceItem.selling_price),
          "0.00"
        );
        tempOrder.products.push(
          (0, import_utils.normalizeOrderProduct)({
            ...sourceItem,
            product_id: productId,
            product_variant_id: productVariantId,
            num: targetQuantity,
            selling_price: sellingPrice,
            original_price: sellingPrice,
            metadata: {
              item_rule_prefill: true,
              item_rule_id: prefillItem.ruleId
            },
            _origin: {
              ...sourceItem || {},
              item_rule_prefill: true,
              item_rule_id: prefillItem.ruleId
            }
          })
        );
        hasChanges = true;
        continue;
      }
      const targetProduct = tempOrder.products[productIndex];
      const existedQuantity = (0, import_utils.toNonNegativeInt)(targetProduct.num);
      const delta = targetQuantity - existedQuantity;
      const nextProduct = {
        ...targetProduct,
        ...delta > 0 ? { num: (0, import_utils.getSafeProductNum)(existedQuantity + delta) } : {},
        metadata: {
          ...targetProduct.metadata || {},
          item_rule_prefill: true,
          item_rule_id: prefillItem.ruleId
        },
        _origin: sourceItem ? {
          ...targetProduct._origin || {},
          ...sourceItem
        } : targetProduct._origin
      };
      const hasQuantityChanged = delta > 0;
      const hasOriginChanged = Boolean(
        sourceItem && (!targetProduct._origin || ((_a = targetProduct._origin) == null ? void 0 : _a.name) !== (sourceItem == null ? void 0 : sourceItem.name) || ((_b = targetProduct._origin) == null ? void 0 : _b.title) !== (sourceItem == null ? void 0 : sourceItem.title) || ((_c = targetProduct._origin) == null ? void 0 : _c.price) !== (sourceItem == null ? void 0 : sourceItem.price))
      );
      if (hasQuantityChanged || hasOriginChanged) {
        tempOrder.products[productIndex] = nextProduct;
        hasChanges = true;
      }
    }
    if (hasChanges) {
      this.store.order.applyDiscount();
      await this.store.order.recalculateSummary({ createIfMissing: true });
      this.store.order.persistTempOrder();
    }
    await this.refreshItemRuleQuantityLimits();
    this.itemRulePrefillApplied = true;
    this.logMethodSuccess("applyPrefillByItemRule", {
      prefillCount: prefillItems.length,
      hasChanges
    });
  }
  async applyItemRulePrefill() {
    var _a, _b;
    if ((_b = (_a = this.store.order) == null ? void 0 : _a.getLastOrderInfo) == null ? void 0 : _b.call(_a)) {
      return;
    }
    this.logMethodStart("applyItemRulePrefill");
    await this.applyPrefillByItemRule();
    await this.refreshItemRuleQuantityLimits();
    await this.refreshCartValidationPassed();
  }
  async evaluateCartValidationByItemRule() {
    const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
    if (!strategyConfigs.length) {
      return {
        passed: true,
        failures: []
      };
    }
    const businessData = (0, import_utils.buildItemRuleBusinessData)({
      tempOrder: this.ensureTempOrder(),
      runtimeConfig: this.getItemRuleRuntimeConfig(),
      itemRuleConfigs: this.itemRuleConfigs
    });
    return this.itemRuleEvaluator.validateCart(businessData);
  }
  async validateBeforeSubmitByItemRule() {
    const validationResult = await this.evaluateCartValidationByItemRule();
    if (validationResult.passed)
      return;
    const firstFailure = validationResult.failures[0];
    const errorMessage = (firstFailure == null ? void 0 : firstFailure.validationMessage) || "当前购物车未满足商品规则，请调整后再提交";
    const error = new Error(String(errorMessage));
    error.failures = validationResult.failures;
    throw error;
  }
  async refreshCartValidationPassed() {
    const previous = this.store.cartValidation || {
      passed: null,
      failures: []
    };
    let nextState = {
      passed: null,
      failures: []
    };
    try {
      const validationResult = await this.evaluateCartValidationByItemRule();
      nextState = {
        passed: validationResult.passed,
        failures: validationResult.failures || []
      };
    } catch (error) {
      nextState = {
        passed: false,
        failures: []
      };
    }
    this.store.cartValidation = nextState;
    const changed = previous.passed !== nextState.passed || previous.failures !== nextState.failures;
    if (changed) {
      await this.core.effects.emit(import_types.ScanOrderHooks.onCartValidationChanged, {
        cartValidation: nextState,
        cartValidationPassed: nextState.passed
      });
    }
    return nextState.passed;
  }
  async setItemRuleRuntimeConfig(config = {}) {
    var _a, _b;
    this.logMethodStart("setItemRuleRuntimeConfig");
    this.itemRuleRuntimeConfig = {
      ...this.itemRuleRuntimeConfig,
      ...config,
      pax: {
        ...((_a = this.itemRuleRuntimeConfig) == null ? void 0 : _a.pax) || {},
        ...(config == null ? void 0 : config.pax) || {}
      },
      custom: {
        ...((_b = this.itemRuleRuntimeConfig) == null ? void 0 : _b.custom) || {},
        ...(config == null ? void 0 : config.custom) || {}
      }
    };
    if ("strategyConfigs" in config) {
      this.itemRuleConfigs = [];
      this.itemRuleConfigsPromise = null;
      this.itemRuleEvaluator.setStrategyConfigs([]);
    }
    this.itemRulePrefillApplied = false;
    await this.refreshItemRuleQuantityLimits();
    await this.refreshCartValidationPassed();
    this.logMethodSuccess("setItemRuleRuntimeConfig", {
      strategyCount: Array.isArray(this.itemRuleRuntimeConfig.strategyConfigs) ? this.itemRuleRuntimeConfig.strategyConfigs.length : 0
    });
  }
  normalizeResourceState(detail, resourceSelectType, hasOrderId) {
    var _a, _b, _c, _d;
    const currentOrderId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.order_id);
    const lastOrderId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.last_order_id);
    const relationId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.form_record_id);
    const tableFormId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.form_id);
    const formRecord = (detail == null ? void 0 : detail.form_record) ?? null;
    const allowSnack = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["sale.allow_add_items"]) || false;
    const deskmateValid = false;
    const isExclusive = resourceSelectType === "single";
    const isFull = (0, import_utils.computeResourceIsFull)({
      resourceSelectType,
      lastOrderId,
      capacityList: ((_d = (_c = detail == null ? void 0 : detail.resource_capacity) == null ? void 0 : _c[0]) == null ? void 0 : _d.capacity_list) ?? [],
      capacity: formRecord == null ? void 0 : formRecord.capacity
    });
    let availabilityInfo = {
      mode: "idle",
      deskmate_valid: deskmateValid
    };
    if (currentOrderId) {
      if (!hasOrderId) {
        availabilityInfo = {
          mode: "resource_busy",
          order_id: currentOrderId,
          relation_id: relationId,
          table_form_id: tableFormId,
          deskmate_valid: deskmateValid
        };
      } else {
        availabilityInfo = {
          mode: allowSnack ? "additional_order" : "resource_busy",
          order_id: currentOrderId,
          relation_id: relationId,
          table_form_id: tableFormId,
          deskmate_valid: deskmateValid
        };
      }
    } else if (lastOrderId) {
      const canFallthroughToIdle = resourceSelectType === "multiple" && !isFull;
      if (!canFallthroughToIdle) {
        availabilityInfo = {
          mode: "resource_busy",
          order_id: "0",
          relation_id: relationId,
          table_form_id: tableFormId,
          deskmate_valid: deskmateValid
        };
      }
    }
    return {
      ...availabilityInfo,
      currentOrderId,
      lastOrderId,
      relationId,
      tableFormId,
      allowSnack,
      deskmateValid,
      isExclusive,
      isFull,
      resourceSelectType,
      raw: detail,
      table_form_record: formRecord
    };
  }
  // 从首个预约规则商品的 product_resource.resources 中，按 form_id 匹配返回 type
  resolveResourceSelectType(formId) {
    var _a;
    const firstProduct = this.enabledReservationRuleProducts[0];
    const resources = ((_a = firstProduct == null ? void 0 : firstProduct.product_resource) == null ? void 0 : _a.resources) || [];
    const numericFormId = Number(formId);
    if (!Number.isFinite(numericFormId) || numericFormId <= 0)
      return void 0;
    const matched = resources.find((r) => Number(r == null ? void 0 : r.id) === numericFormId);
    return matched == null ? void 0 : matched.type;
  }
  async fetchResourceOccupyDetailByResourceId(resourceId) {
    var _a, _b, _c, _d;
    const formRecordId = Number(resourceId);
    if (!Number.isFinite(formRecordId) || formRecordId <= 0) {
      throw new Error(`[ScanOrder] 非法桌台 resourceId: ${resourceId}`);
    }
    const shopId = (_b = (_a = this.otherParams) == null ? void 0 : _a.getStateData) == null ? void 0 : _b.call(_a, "shop_id");
    if (!shopId) {
      throw new Error("[ScanOrder] 无法获取 shop_id");
    }
    const response = await this.request.get(
      "/order/resource/occupy-detail",
      {
        shop_id: shopId,
        "form_record_ids[]": formRecordId,
        with_resource_capacity_info: 1,
        with_resource_order_info: 1,
        with_resource_form_info: 1
      }
    );
    if (!(response == null ? void 0 : response.status)) {
      throw new Error((response == null ? void 0 : response.message) || "获取资源占用详情失败");
    }
    return ((_d = (_c = response == null ? void 0 : response.data) == null ? void 0 : _c.occupy_details) == null ? void 0 : _d[0]) ?? null;
  }
  // 检测当前链接是否可用
  // 通过 resource_id + 店铺配置
  // hasOrderId 表示 url 上是否有 orderid，如果是的话，后续的流程会走加单
  async checkResourceAvailable(resourceId, hasOrderId) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
    this.logMethodStart("checkResourceAvailable", {
      resourceId
    });
    try {
      const businessCode = String(((_a = this.otherParams) == null ? void 0 : _a.businessCode) ?? "").trim();
      const channel = String(((_b = this.otherParams) == null ? void 0 : _b.channel) ?? "").trim();
      const openDataTarget = businessCode && channel ? `${businessCode}+${channel}` : "dine_in+scan_to_order";
      const openData = await ((_d = (_c = this.otherParams) == null ? void 0 : _c.getOpenData) == null ? void 0 : _d.call(_c, {
        scope: "board",
        target: openDataTarget,
        section_code: ["basic", "fulfillment", "reservation", "sale", "menu", "availability", "workflow"]
      }));
      if ((openData == null ? void 0 : openData.status) === false) {
        throw new Error((openData == null ? void 0 : openData.message) || "获取店铺配置失败");
      }
      const dineInConfig = (openData == null ? void 0 : openData.data) || {};
      this.otherParams.dineInConfig = dineInConfig;
      await this.syncItemRuleConfigsFromDineInConfig(dineInConfig);
      const closedBehaviorValue = dineInConfig == null ? void 0 : dineInConfig["availability.closed_behavior"];
      const closedMessage = (dineInConfig == null ? void 0 : dineInConfig["availability.closed_message"]) || (dineInConfig == null ? void 0 : dineInConfig["availability.message"]) || (dineInConfig == null ? void 0 : dineInConfig["basic.closed_message"]);
      const basicUnavailableMessage = (dineInConfig == null ? void 0 : dineInConfig["basic.unavailable_message"]) || closedMessage;
      const pauseMessage = (dineInConfig == null ? void 0 : dineInConfig["availability.pause_message"]) || closedMessage;
      const makeShopClosed = (errorTips, closed_behavior) => ({
        mode: "shop_closed",
        order_id: void 0,
        relation_id: void 0,
        table_form_id: void 0,
        deskmate_valid: false,
        errorTips,
        closed_behavior
      });
      if ((dineInConfig == null ? void 0 : dineInConfig["basic.enable"]) === false) {
        return makeShopClosed(basicUnavailableMessage);
      }
      if ((0, import_utils.toBoolean)(dineInConfig == null ? void 0 : dineInConfig["availability.paused"])) {
        if ((dineInConfig == null ? void 0 : dineInConfig["availability.pause_behavior"]) === "hide_all") {
          return makeShopClosed(pauseMessage);
        }
      }
      const operatingHourIds = Array.isArray(dineInConfig == null ? void 0 : dineInConfig["availability.operating_hours"]) ? dineInConfig["availability.operating_hours"].map((id) => Number(id)).filter((id) => Number.isFinite(id) && id > 0) : [];
      let outsideOperatingHours = false;
      if (operatingHourIds.length && this.store.schedule) {
        const scheduleList = this.store.schedule.getScheduleListByIds(operatingHourIds);
        if (scheduleList.length) {
          const now = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
          outsideOperatingHours = !(0, import_getDateIsInSchedule.getDateIsInSchedule)(now, scheduleList);
        }
      }
      if (outsideOperatingHours && closedBehaviorValue !== "show_menu_disabled") {
        return makeShopClosed(closedMessage, closedBehaviorValue);
      }
      const tempOrder = this.ensureTempOrder();
      const reservationLinkIds = (0, import_utils.collectLinkProductIdsFromReservationRules)(
        dineInConfig["fulfillment.enabled_resource_rules"]
      );
      let pendingRequestEntryPax;
      let pendingRequestPaxMin;
      let pendingRequestPaxMax;
      if (reservationLinkIds.length === 0) {
        this.enabledReservationRuleProducts = [];
      } else {
        tempOrder.metadata = { ...tempOrder.metadata || {} };
        delete tempOrder.metadata.table_occupancy_duration;
        const reservationProductList = new import_ProductList.ProductList(
          `${this.name}_reservationEnabledRules`,
          this.defaultVersion
        );
        await reservationProductList.initialize(this.core, {
          store: { list: [], selectProducts: [] },
          otherParams: {
            ...this.otherParams,
            fatherModule: this.name,
            openCache: Boolean(this.cacheId),
            cacheId: this.cacheId
          }
        });
        const scheduleDate = (0, import_dayjs.default)().format("YYYY-MM-DD");
        const scheduleDatetime = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
        const loaded = await reservationProductList.loadProducts({
          product_ids: reservationLinkIds,
          schedule_date: scheduleDate,
          schedule_datetime: scheduleDatetime,
          cacheId: this.cacheId
        });
        if (Array.isArray(loaded)) {
          this.enabledReservationRuleProducts = loaded;
          const occupancyMinutes = (0, import_utils.pickFirstDurationMinutesFromProducts)(loaded);
          if (occupancyMinutes !== void 0) {
            tempOrder.metadata.table_occupancy_duration = occupancyMinutes;
          }
          if ((0, import_utils.hasCustomCapacityProduct)(loaded)) {
            pendingRequestEntryPax = 1;
            const paxBounds = (0, import_utils.pickFirstCustomCapacityPaxBounds)(loaded);
            if ((paxBounds == null ? void 0 : paxBounds.min) !== void 0)
              pendingRequestPaxMin = paxBounds.min;
            if ((paxBounds == null ? void 0 : paxBounds.max) !== void 0)
              pendingRequestPaxMax = paxBounds.max;
          }
        } else {
          this.enabledReservationRuleProducts = [];
          const error = loaded instanceof Error ? loaded : new Error("预约规则商品列表接口返回异常");
          this.logMethodError("loadReservationRuleProducts", error, {
            resourceId,
            reservationLinkIds,
            scheduleDate,
            scheduleDatetime,
            cacheId: this.cacheId
          });
        }
      }
      const occupyDetail = await this.fetchResourceOccupyDetailByResourceId(resourceId);
      const resourceSelectType = this.resolveResourceSelectType(
        (0, import_utils.toPositiveString)(occupyDetail == null ? void 0 : occupyDetail.form_id)
      );
      const resourceState = this.normalizeResourceState(
        occupyDetail,
        resourceSelectType,
        hasOrderId
      );
      this.store.resource = resourceState;
      if (pendingRequestEntryPax !== void 0) {
        this.store.resource.requestEntryPax = pendingRequestEntryPax;
      }
      if (pendingRequestPaxMin !== void 0) {
        this.store.resource.requestPaxMin = pendingRequestPaxMin;
      }
      if (pendingRequestPaxMax !== void 0) {
        this.store.resource.requestPaxMax = pendingRequestPaxMax;
      }
      const availabilityInfo = {
        mode: resourceState.mode,
        order_id: resourceState.order_id,
        relation_id: resourceState.relationId,
        table_form_id: resourceState.tableFormId,
        deskmate_valid: resourceState.deskmate_valid,
        table_form_record: resourceState.table_form_record,
        policy: (_e = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _e.policy,
        partyroom_booking: (_f = occupyDetail == null ? void 0 : occupyDetail.form_record) == null ? void 0 : _f.partyroom_booking,
        ...this.store.resource.requestEntryPax !== void 0 ? { requestEntryPax: this.store.resource.requestEntryPax } : {},
        ...this.store.resource.requestPaxMin !== void 0 ? { requestPaxMin: this.store.resource.requestPaxMin } : {},
        ...this.store.resource.requestPaxMax !== void 0 ? { requestPaxMax: this.store.resource.requestPaxMax } : {}
      };
      tempOrder.relation_id = resourceId || ((_g = this.otherParams) == null ? void 0 : _g.relation_id);
      tempOrder.table_form_id = resourceState.tableFormId;
      tempOrder.resource_id = resourceId;
      (_h = this.store.order) == null ? void 0 : _h.persistTempOrder();
      if (availabilityInfo.mode === "idle") {
        await this.addNewOrder();
      }
      if (availabilityInfo.mode === "additional_order" || availabilityInfo.mode === "additional_order_with_code") {
        tempOrder.order_id = resourceState.lastOrderId;
      }
      if (tempOrder.order_id) {
        const res = await ((_i = this.store.order) == null ? void 0 : _i.getOrderInfoByRemote(tempOrder.order_id));
        const entryPaxNumber = (_m = (_l = (_k = (_j = res == null ? void 0 : res.data) == null ? void 0 : _j.bookings) == null ? void 0 : _k.find((p) => {
          var _a2;
          return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
        })) == null ? void 0 : _l.metadata) == null ? void 0 : _m.collect_pax;
        if (entryPaxNumber) {
          await this.setEntryPaxNumber(entryPaxNumber);
        }
      }
      const lastOrderInfo = (_o = (_n = this.store.order) == null ? void 0 : _n.getLastOrderInfo) == null ? void 0 : _o.call(_n);
      const historicalItems = hasOrderId && Array.isArray(lastOrderInfo == null ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce((acc, p) => {
        if (typeof (p == null ? void 0 : p.product_id) !== "number")
          return acc;
        acc.push({
          product_id: p.product_id,
          quantity: Number(p.product_quantity) || 0,
          ...typeof p.product_variant_id === "number" ? { product_variant_id: p.product_variant_id } : {}
        });
        return acc;
      }, []) : [];
      await this.setItemRuleRuntimeConfig({
        serviceType: (_p = this.otherParams) == null ? void 0 : _p.businessCode,
        submissionIndex: hasOrderId ? 1 : 0,
        historicalItems
      });
      if (outsideOperatingHours && closedBehaviorValue === "show_menu_disabled") {
        availabilityInfo.mode = "submit_disabled";
        availabilityInfo.errorTips = closedMessage;
        availabilityInfo.closed_behavior = closedBehaviorValue;
      }
      this.logMethodSuccess("checkResourceAvailable", {
        resourceId,
        mode: availabilityInfo.mode,
        orderId: availabilityInfo.order_id,
        relationId: availabilityInfo.relation_id,
        tableFormId: availabilityInfo.table_form_id,
        persistedRelationId: tempOrder.relation_id,
        persistedResourceId: tempOrder.resource_id,
        deskmateValid: availabilityInfo.deskmate_valid,
        resourceSelectType: resourceState.resourceSelectType,
        isExclusive: resourceState.isExclusive,
        isFull: resourceState.isFull
      });
      return availabilityInfo;
    } catch (error) {
      this.logMethodError("checkResourceAvailable", error.message, {
        resourceId
      });
      throw error;
    }
  }
  // 如果是加单的情况，提供返回当前订单相关信息的能力
  async getAdditionalOrderInfo() {
    this.logMethodStart("getAdditionalOrderInfo");
    const result = {
      orderId: "123567890",
      orderStatus: "pending",
      orderTime: "2026-03-31 10:00:00",
      orderAmount: 100,
      orderItems: []
    };
    this.logMethodSuccess("getAdditionalOrderInfo", {
      orderId: result.orderId,
      orderStatus: result.orderStatus
    });
    return result;
  }
  // 获取商品列表
  async getProductList() {
    var _a, _b;
    this.logMethodStart("getProductList");
    const menu_list_ids = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["menu.associated_menus"].map((n) => Number(n.value))) || [];
    try {
      if (!this.store.products)
        throw new Error("products 模块未初始化");
      const res = await this.store.products.loadProducts({
        menu_list_ids,
        cacheId: this.cacheId,
        schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
        schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
      });
      const productList = this.assertProductListLoaded("getProductList", res, {
        menu_list_ids,
        cacheId: this.cacheId
      });
      const formattedRes = (0, import_utils.attachItemRuleLimitsToTopLevelProducts)(
        productList,
        this.store.itemRuleQuantityLimits || []
      );
      this.logMethodSuccess("getProductList", {
        menuCount: menu_list_ids.length
      });
      return formattedRes;
    } catch (error) {
      if (!(error == null ? void 0 : error.__scanOrderLogged)) {
        this.logMethodError("getProductList", error, {
          menu_list_ids,
          cacheId: this.cacheId
        });
      }
      throw error;
    }
  }
  getOtherParams() {
    return this.otherParams;
  }
  async setOtherParams(params, { cover = false } = {}) {
    if (cover) {
      this.otherParams = params;
    } else {
      this.otherParams = { ...this.otherParams, ...params };
    }
  }
  getUIStateBucketKey() {
    if (!this.cacheId)
      return null;
    return `${_ScanOrderImpl.UI_STATE_KEY_PREFIX}${this.cacheId}`;
  }
  readUIStateBucket() {
    var _a;
    const key = this.getUIStateBucketKey();
    if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
      return {};
    try {
      const raw = this.window.localStorage.getItem(key) || "{}";
      const parsed = JSON.parse(raw);
      return parsed && typeof parsed === "object" ? parsed : {};
    } catch {
      return {};
    }
  }
  writeUIStateBucket(bucket) {
    var _a;
    const key = this.getUIStateBucketKey();
    if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
      return;
    try {
      this.window.localStorage.setItem(key, JSON.stringify(bucket));
    } catch (error) {
      console.warn("[ScanOrder] writeUIStateBucket failed", error);
    }
  }
  setUIState(key, value) {
    if (!this.getUIStateBucketKey())
      return;
    const bucket = this.readUIStateBucket();
    bucket[key] = value;
    this.writeUIStateBucket(bucket);
  }
  getUIState(key) {
    if (!this.getUIStateBucketKey())
      return void 0;
    const bucket = this.readUIStateBucket();
    return bucket[key];
  }
  deleteUIState(key) {
    if (!this.getUIStateBucketKey())
      return;
    const bucket = this.readUIStateBucket();
    if (key in bucket) {
      delete bucket[key];
      this.writeUIStateBucket(bucket);
    }
  }
  // 整桶清空（用于扫新桌、提交成功、restoreOrder 等场景）
  clearUIState() {
    var _a;
    const key = this.getUIStateBucketKey();
    if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
      return;
    try {
      this.window.localStorage.removeItem(key);
    } catch (error) {
      console.warn("[ScanOrder] clearUIState failed", error);
    }
  }
  async setEntryPaxNumber(number) {
    const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(number);
    this.store.entryPaxNumber = pax;
    if (this.store.order) {
      const t = this.store.order.ensureTempOrder();
      t.metadata = { ...t.metadata, collect_pax: pax };
      this.store.order.persistTempOrder();
    }
    this.itemRuleRuntimeConfig = {
      ...this.itemRuleRuntimeConfig,
      pax: { total: pax, adult: 0, child: 0 }
    };
    this.itemRulePrefillApplied = false;
    await this.refreshItemRuleQuantityLimits();
    await this.refreshCartValidationPassed();
  }
  getEntryPaxNumber() {
    return this.store.entryPaxNumber;
  }
  // 读取取餐/送餐开关
  // 依赖 checkResourceAvailable 已缓存的 dineInConfig
  getFulfillmentModes() {
    var _a;
    this.logMethodStart("getFulfillmentModes");
    const dineInConfig = ((_a = this.otherParams) == null ? void 0 : _a.dineInConfig) || {};
    const result = {
      enablePickup: Boolean(dineInConfig["fulfillment.enable_pickup"]),
      enableTableService: Boolean(dineInConfig["fulfillment.enable_table_service"])
    };
    this.logMethodSuccess("getFulfillmentModes", result);
    return result;
  }
  // 判定后台是否开启客户自定义取餐标识
  // 依赖 checkResourceAvailable 已缓存的 dineInConfig
  checkManualPickupRef() {
    var _a;
    this.logMethodStart("checkManualPickupRef");
    const dineInConfig = ((_a = this.otherParams) == null ? void 0 : _a.dineInConfig) || {};
    const refMode = dineInConfig["fulfillment.fulfillment_ref_mode"];
    const manualInputType = dineInConfig["fulfillment.manual_input_type"];
    const enabled = refMode === "manual_input";
    const result = enabled ? { enabled: true, manualInputType } : { enabled: false };
    this.logMethodSuccess("checkManualPickupRef", {
      enabled,
      manualInputType: enabled ? manualInputType : void 0
    });
    return result;
  }
};
var ScanOrderImpl = _ScanOrderImpl;
ScanOrderImpl.PISELL1_LOGIN_SUCCESS = "pisell1.login.success";
// ─── UI 状态缓存（按 cacheId 分桶，localStorage） ───
//
// 用于物料层持久化 UI 层面的轻量状态（如当前步骤、gate 标记、登录回跳意图等）。
// 桶键：pisell.scanOrder.uiState:<cacheId>；内部以 JSON object 形式存储多个字段。
// 无 cacheId 时所有方法自动降级为 no-op，上层不用判空。
//
// 之所以用 localStorage 而不是 sessionStorage：
//   1. 与 Order 模块 openCache 下的 tempOrder 同栈，购物车在 / UIState 在，行为对齐；
//   2. pisell1.login 整页 OAuth 跳转在 H5 壳 / iOS Safari 场景下可能丢 sessionStorage，
//      导致登录回跳后 gate 标记失效、pax 弹窗重开、落点错误；localStorage 稳定不受影响。
//   3. 失效由上层显式控制：提交成功 clearStepCache / entryContext 不一致 clearUIState /
//      pendingStep 登录回调 deleteUIState，足够约束生命周期。
ScanOrderImpl.UI_STATE_KEY_PREFIX = "pisell.scanOrder.uiState:";
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  ScanOrderImpl,
  ...require("./types")
});
