import { Module, ModuleOptions, PisellCore } from '../../../types';
import { BaseModule } from '../../../modules/BaseModule';
import type { RouteDefinition } from '../../types';
import { OrderData, OrderId } from './types';
/**
 * Order 模块 - 基础框架
 */
export declare class OrderModule extends BaseModule implements Module {
    protected defaultName: string;
    protected defaultVersion: string;
    private store;
    private dbManager;
    private orderDataSource;
    private pendingSyncMessages;
    private syncTimer?;
    private isProcessingSyncBatch;
    private isIdlePhase;
    private resourceIdIndex;
    private logger;
    private storage;
    private orderSQLiteSaveQueue; /** 按 storageKey 记录最近一次 SQLite 写入来源与时间，用于去重 */
    private recentSqliteWriteByStorageKey;
    /** 最近一次 SSE 全量拉取完成时间 */
    private lastServerFullFetchAtMs;
    constructor(name?: string, version?: string);
    /**
     * 广播订单变更事件，兼容全量列表订阅并额外携带本次变更订单。
     *
     * @example
     * await this.emitOrdersChanged([freshOrder], 'pubsub.bodyUpsert')
     */
    private emitOrdersChanged;
    initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
    /**
   * 记录信息日志
   * @param title 日志标题
   * @param metadata 日志元数据
   */
    private logInfo;
    /**
     * 记录错误日志
     * @param title 日志标题
     * @param metadata 日志元数据
     */
    private logError;
    /**
     * 记录订单最近一次 SQLite 写入，供 pubsub 回声去重使用。
     *
     * @example
     * this.recordRecentSqliteWrite('upsertOrdersFromRemote', orders)
     */
    private recordRecentSqliteWrite;
    /**
     * 过滤 pubsub 触发的冗余 SQLite patch（业务 API 刚写入过的 update 回声）。
     *
     * @example
     * const { toWrite, skipped } = this.filterRedundantPatchOrders('pubsub.bodyUpsert', orders, mergeActions)
     */
    private filterRedundantPatchOrders;
    /**
     * 过滤 pubsub HTTP 增量拉取 ids：本地刚由业务 API 写入的单可跳过 HTTP。
     *
     * @example
     * const ids = this.filterRedundantHttpRefreshIds([99331, 99332])
     */
    private filterRedundantHttpRefreshIds;
    /**
     * 解析 pubsub 消息会走哪条同步分支，便于对照为何触发 HTTP 重拉或 body 直写。
     *
     * @example
     * this.resolveSyncMessageRoute(msg)
     * // => { route: 'httpRefresh.batchIds', ... }
     */
    private resolveSyncMessageRoute;
    private getOrderSyncThrottleMs;
    preload(): Promise<void>;
    getOrders(): OrderData[];
    getOrderById(id: OrderId): OrderData | undefined;
    /** 按 order_id 查询内存订单。 */
    getOrderByOrderId(orderId: OrderId): OrderData | undefined;
    getLocalOrderByLookup(lookup: OrderId): Promise<OrderData | null>;
    loadOrdersByServer(): Promise<OrderData[]>;
    /**
     * 静默全量刷新：后台重新拉取全量 SSE 订单数据并更新本地
     * 拿到完整数据后一次性替换 store，触发订单变更与同步完成事件
     * @returns 刷新后的订单列表
     */
    silentRefresh(): Promise<OrderData[]>;
    getOrdersByResourceId(resourceId: string | number): OrderData[];
    private normalizeOrderForMemoryList;
    /**
     * 仅覆盖本地已存在的订单；不存在则直接跳过，不落库、不 emit。
     * 适用于"按 order_id 主动刷新本地订单详情"的代理场景。
     */
    overwriteExistingOrder(fresh: OrderData): Promise<{
        overwritten: boolean;
    }>;
    /**
     * 将远端拉取的订单合并进本地 store（已存在则更新，不存在则追加），落库并 emit onOrdersChanged。
     * 供 /update/localOrder 等在「本地尚无该单」时写入新建单。
     */
    upsertOrdersFromRemote(freshOrders: OrderData[]): Promise<void>;
    markOrderSyncedByExternalSaleNumber(params: {
        externalSaleNumber: OrderId;
        patch?: Partial<OrderData>;
    }): Promise<{
        updated: boolean;
        order?: OrderData;
    }>;
    /**
     * 将本地待同步订单按 SQLite storage key 合并进 store 并落库。
     * checkout 离线兜底可能没有 order_id，但通常会有 external_sale_number。
     */
    upsertPendingSyncOrders(pendingOrders: OrderData[]): Promise<void>;
    /**
     * 通过 SSE 按自定义 query 拉取订单（支持 select/with 精简字段）
     */
    fetchOrdersBySSE(query?: Record<string, any>): Promise<OrderData[]>;
    getRoutes(): RouteDefinition[];
    destroy(): void;
    private syncOrdersMap;
    private getOrderIdentityKeys;
    private extractResourceIds;
    private getOrderDateKey;
    /**
     * 初始化 OrderDataSource 实例
     */
    private initOrderDataSource;
    /**
     * 初始化 pubsub 订阅，监听订单变更（纯订阅，不拉数据；全量 SSE 由 loadOrdersByServer 负责）
     */
    private setupOrderSync;
    /**
     * 调度订单同步节流窗口（leading-edge throttle）：
     * - 空闲状态下收到的第一条消息立即触发批处理，无需等待；
     * - 首条处理后进入冷却窗口，窗口期间的后续消息聚合，窗口结束后批量处理；
     * - 若当前批处理执行中，则由批处理结束后决定是否开启下一轮窗口。
     */
    private scheduleOrderSyncThrottle;
    /**
     * 执行一次节流批处理并在需要时续约下一轮窗口。
     * 批处理完成且无后续消息时恢复空闲状态，下一条消息将立即触发。
     */
    private flushOrderSyncMessagesByThrottle;
    /**
     * 处理节流窗口内聚合后的同步消息批次
     *
     * 后端统一发送 change 消息，不再区分新增/编辑/删除。
     * - 单条（id/order_id）：若携带 body/data 则直接 upsert 到本地
     * - 批量（ids）：通过 HTTP 按 ids 增量拉取，再 merge 到本地
     *
     * @example
     * // pending 队列中存在 8 条消息时，仅处理一次批次并统一 merge
     * await this.processOrderSyncMessages()
     */
    private processOrderSyncMessages;
    /**
     * 通过 HTTP 按 ids 批量拉取订单详情（走 orderDataSource）。
     *
     * - 优先使用 `orderDataSource.fetchOrdersByIds`（如适配器实现了该方法）
     * - 否则回退到 `orderDataSource.run({ http: { query: { ids } } })`
     * - 失败统一返回空数组（由调用方按"返回缺失的 id" 判断单笔失败）
     *
     * @example
     * const fresh = await orderModule.fetchOrdersByHttp(['96971', '96972'])
     */
    fetchOrdersByHttp(ids: OrderId[]): Promise<OrderData[]>;
    /**
     * 将增量订单合并到 store
     */
    private mergeOrdersToStore;
    private normalizeOrderSyncMessage;
    private normalizeOrderSyncPayload;
    private uniqueOrderIds;
    private getIdKey;
    private isOrderLookupMatch;
    /**
     * 解析订单 SQLite 主键，规则与宿主 OrderDataSource.getOrderStorageKey 一致。
     *
     * @example
     * const key = this.getOrderStorageKey({ order_id: 1001, external_sale_number: 'S-1001' })
     * // => 'S-1001'
     */
    private getOrderStorageKey;
    /**
     * 当前订单拉取窗口：
     * - 优先使用 createdAtQuery.sales_time_between（已按营业日边界初始化）
     * - 无法解析时退化为自然日窗口
     */
    private getCurrentPullWindow;
    private hasPulledOrdersToday;
    private markOrderPulledAtNow;
    private getStorageItem;
    private setStorageItem;
    private loadOrdersFromSQLite;
    private isPendingSyncOrder;
    private normalizeRemoteSyncedOrder;
    private mergeRemoteSnapshotWithPendingOrders;
    /**
     * 串行执行订单 SQLite 写入任务，避免快照替换与增量 upsert 并发交错。
     *
     * @example
     * await this.runInOrderSQLiteSaveQueue(async () => {
     *   await this.dbManager.bulkUpdate(INDEXDB_STORE_NAME, orders)
     * })
     */
    private runInOrderSQLiteSaveQueue;
    /**
     * 批量增量 upsert 订单到 SQLite，不清空表；用于 pubsub / HTTP 增量合并。
     *
     * @example
     * await this.patchOrdersInSQLite(freshOrders)
     */
    private patchOrdersInSQLite;
    /**
     * 单条 upsert 订单到 SQLite；用于 overwriteExistingOrder 等单条覆盖场景。
     *
     * @example
     * await this.updateOrderInSQLite(freshOrder)
     */
    private updateOrderInSQLite;
    /**
     * 全量快照替换 orders 表（clear + bulkAdd），用于 SSE 全量拉取与营业日窗口裁剪。
     *
     * @example
     * await this.replaceOrdersSnapshotInSQLite(orderList)
     */
    private replaceOrdersSnapshotInSQLite;
    /**
     * 清空订单模块的内存数据和本地 SQLite 订单表。
     *
     * @example
     * await orderModule.clear()
     */
    clear(): Promise<void>;
}
