import { Module, PisellCore } from '../../../types';
import { BaseModule } from '../../../modules/BaseModule';
import { ProductData } from '../../../modules/Product/types';
import type { RouteDefinition } from '../../types';
import { ProductIdScope, ProductFormatter, ProductFormatterContext } from './types';
/**
 * Products 模块 - 用于获取和管理完整的商品详细数据
 * 相比 ProductList 模块，Products 会获取所有详细信息并缓存
 */
export declare class ProductsModule extends BaseModule implements Module {
    protected defaultName: string;
    protected defaultVersion: string;
    private store;
    private request;
    private dbManager;
    private logger;
    private otherParams;
    private productsPriceCache;
    private readonly CACHE_MAX_DAYS;
    private formatters;
    private isPriceFormatterRegistered;
    private quotationPriceBridge?;
    private quotationBridgeChannel?;
    private quotationBridgeCustomerId?;
    private quotationBridgeRefreshPromise?;
    private quotationBridgeRefreshKey?;
    private productDataSource;
    private pendingSyncMessages;
    private syncTimer?;
    constructor(name?: string, version?: string);
    initialize(core: PisellCore, options: any): Promise<void>;
    /**
     * 记录信息日志
     * @param title 日志标题
     * @param metadata 日志元数据
     */
    private logInfo;
    /**
     * 记录警告日志
     * @param title 日志标题
     * @param metadata 日志元数据
     */
    private logWarning;
    /**
     * 记录错误日志
     * @param title 日志标题
     * @param metadata 日志元数据
     */
    private logError;
    /**
     * 加载商品价格（原始方法，不带缓存）
     * @private
     */
    private loadProductsPrice;
    /**
     * 设置报价单价格桥接器。
     * Server 层负责传入完整 schedule 模块，Products 只负责把报价单计算结果转成价格响应形状。
     */
    setupQuotationPriceBridge(params: {
        scheduleModule?: any;
        channel?: string;
        customer_id?: number | string;
    }): Promise<void>;
    /**
     * 刷新桥接器内的报价单列表。
     */
    refreshQuotationPriceBridge(params?: {
        customer_id?: number | string;
    }): Promise<void>;
    private ensureQuotationBridgeReady;
    private getQuotationBridgeScopeKey;
    private buildPriceDataFromQuotation;
    private buildVariantPriceData;
    private buildBundleGroupPriceData;
    /**
     * 获取应用了价格的商品列表（带缓存）
     * 使用日期作为缓存 key，同一天的商品价格会被缓存
     * 缓存的是已经应用了价格的完整商品列表，避免重复转换
     * @param schedule_date 日期
     * @param extraContext 额外的上下文数据（可选，由 Server 层传入）
     * @param options 可选参数
     * @param options.changedIds 变更的商品 IDs，非空时仅对这些商品增量执行 prepare 并更新缓存
     * @param options.productIds 指定商品 IDs，仅对这些商品执行价格计算；不传则处理全量
     * @returns 应用了价格的商品列表
     */
    getProductsWithPrice(schedule_date: string, extraContext?: Partial<ProductFormatterContext>, options?: {
        changedIds?: number[];
        productIds?: number[];
    }): Promise<ProductData[]>;
    /**
     * 准备带价格的商品数据（通过格式化器流程处理）
     * @param schedule_date 日期
     * @param extraContext 额外的上下文数据（可选）
     * @param options 可选参数
     * @param options.productIds 指定商品 IDs，仅处理这些商品；不传则处理全量
     * @returns 处理后的商品列表
     * @private
     */
    private prepareProductsWithPrice;
    private getProductsPriceCacheKey;
    private normalizeProductIds;
    /**
     * 按轻量范围返回商品 ID，不做 structuredClone。
     */
    getProductIdsByScope(scope: ProductIdScope): number[];
    /**
     * 应用所有已注册的格式化器
     * @param products 商品列表
     * @param context 上下文信息
     * @returns 格式化后的商品列表
     * @private
     */
    private applyFormatters;
    /**
     * 注册内置的价格格式化器
     * 这个格式化器负责将价格数据应用到商品上
     * @private
     */
    private registerBuiltinPriceFormatter;
    /**
     * 注册商品格式化器
     * 格式化器会按注册顺序依次执行（内置价格格式化器始终是第一个）
     * @param formatter 格式化函数
     * @param prepend 是否插入到队列开头（默认 false，追加到末尾）
     * @example
     * ```ts
     * productsModule.registerFormatter((products, context) => {
     *   return products.map(p => ({
     *     ...p,
     *     custom_field: 'custom_value'
     *   }));
     * });
     * ```
     */
    registerFormatter(formatter: ProductFormatter, prepend?: boolean): void;
    /**
     * 清空所有格式化器（包括内置价格格式化器）
     * @param keepBuiltin 是否保留内置价格格式化器（默认 true）
     */
    clearFormatters(keepBuiltin?: boolean): void;
    /**
     * 清理过期的价格缓存
     * 当缓存数量超过限制时，删除最老的缓存
     * @private
     */
    private cleanExpiredPriceCache;
    /**
     * 清空商品价格缓存
     * 可用于手动刷新价格数据
     */
    clearPriceCache(): void;
    /**
     * 通过 ProductDataSource SSE 加载完整商品列表
     */
    loadProductsByServer(): Promise<any>;
    /**
     * 纯请求方法：通过 HTTP 接口获取商品列表（无副作用，不触发事件、不写 IndexDB）
     * @param params 查询参数
     * @returns 商品列表
     */
    private fetchProductsByHttp;
    /**
     * 加载完整商品列表通过接口（包含所有详细数据）
     * 包含副作用：保存到 IndexDB + 触发 onProductsLoaded 事件
     * @param params 查询参数
     */
    loadProductsByServerHttp(params?: {
        category_ids?: number[];
        product_ids?: number[];
        collection?: number | string[];
        customer_id?: number;
        cacheId?: string;
    }): Promise<ProductData[]>;
    /**
     * 获取商品列表（深拷贝，供外部安全使用）
     */
    getProducts(): Promise<ProductData[]>;
    /**
     * 内部获取商品列表的直接引用（无拷贝）
     * 仅供内部 formatter 流程使用，因为 formatter 会创建新对象
     */
    private getProductsRef;
    /**
     * 按 ID 从 Map 取商品引用，供内部 formatter 流程使用。
     */
    private getProductsRefByIds;
    /**
     * 根据ID获取单个商品（从内存缓存）
     * 使用 Map 快速查询，时间复杂度 O(1)
     */
    getProductById(id: number): Promise<ProductData | undefined>;
    /**
     * 根据 ID 列表删除商品（用于 pubsub 同步删除场景）
     * 同时更新 store.list、store.map、IndexDB 和价格缓存
     */
    removeProductsByIds(ids: number[]): Promise<void>;
    /**
     * 重新从服务器加载全量商品列表并更新本地 store
     * 用于 pubsub 同步 create / update / batch_update 场景
     */
    refreshProducts(): Promise<ProductData[]>;
    /**
     * 清空缓存
     */
    clear(): Promise<void>;
    /**
     * 从 IndexDB 加载商品数据
     * @private
     */
    private loadProductsFromIndexDB;
    /**
     * 保存商品数据到 IndexDB（平铺存储）
     * @private
     */
    private saveProductsToIndexDB;
    /**
     * 同步更新商品 Map 缓存
     * 将 list 中的商品同步到 map，以 id 为 key
     * @private
     */
    private syncProductsMap;
    /**
     * 预加载模块数据（统一接口）
     * 在模块注册后自动调用
     */
    preload(): Promise<void>;
    /**
     * 初始化 ProductDataSource 实例
     * 与 pubsub 订阅和数据获取分开，仅负责创建实例
     */
    private initProductDataSource;
    /**
     * 初始化 pubsub 订阅，监听管理后台商品变更
     * 仅负责订阅 product / product_quotation 频道，消息通过防抖合并后批量处理
     * 数据获取由 loadProductsByServer 单独负责
     */
    private setupProductSync;
    /**
     * 处理防抖后的同步消息批次
     *
     * product 模块：
     *   - operation === 'delete' → 本地删除
     *   - change_types 包含 price → 仅收集变更 IDs（不拉商品数据）
     *   - 有 body → body 完整数据直接覆盖本地
     *   - 其他 → SSE 增量拉取
     *
     * product_collection / product_category：
     *   - 按 relation_product_ids SSE 拉取受影响商品
     *
     * product_quotation：
     *   - 报价单变更影响范围大，直接清除价格缓存走全量重建
     *
     * 处理完成后 emit onProductsSyncCompleted（携带 changedIds），
     * Server 层监听该事件后对变更商品增量执行 prepareProductsWithPrice 并更新缓存
     */
    private processProductSyncMessages;
    /**
     * 通过 SSE 按 ids 增量拉取商品数据
     * 请求 GET /shop/core/stream?type=product&ids={ids}
     */
    private fetchProductsBySSE;
    /**
     * 将 body 完整数据直接覆盖到本地 store（不调用报价单接口）
     * 已存在的 → 直接替换；不存在的 → 追加
     * 同时更新 Map 缓存、IndexDB，触发 onProductsChanged
     * 价格缓存由 processProductSyncMessages 末尾统一清除
     */
    private applyBodyUpdatesToStore;
    /**
     * 将增量拉取的商品合并到 store
     * 已存在的 → 替换；新的 → 追加
     * 同时更新 store.map、IndexDB，触发 onProductsChanged
     */
    private mergeProductsToStore;
    /**
     * 静默全量刷新：后台重新拉取全量 SSE 数据并更新本地
     * 拿到完整数据后一次性替换 store，清除价格缓存，触发 onProductsSyncCompleted
     * @returns 刷新后的商品列表
     */
    silentRefresh(): Promise<ProductData[]>;
    /**
     * 销毁同步资源（取消 pubsub 订阅、清除定时器）
     */
    destroyProductSync(): void;
    /**
     * 获取模块的路由定义
     * Products 模块暂不提供路由，由 Server 层统一处理
     */
    getRoutes(): RouteDefinition[];
}
