import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
import { _asyncToGenerator } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
import { showAddToCartToast } from "../components/showAddToCartToast.js";
import { resolveAddProductDebounceKey } from "./resolveAddProductDebounceKey.js";
import { resolveInCartQuantityForAddToast } from "./resolveInCartQuantityForAddToast.js";
function toFlowResult(result) {
	if (result.status === "added") return {
		status: "added",
		products: result.products
	};
	if (result.status === "requiresDetail") return {
		status: "requiresDetail",
		payload: result.payload
	};
	return {
		status: "requiresBookingEdit",
		payload: result.payload
	};
}
function resolveProductTitle(product, cacheItem) {
	var _ref, _ref2, _ref3, _product$title, _product$id;
	return (_ref = (_ref2 = (_ref3 = (_product$title = product === null || product === void 0 ? void 0 : product.title) !== null && _product$title !== void 0 ? _product$title : product === null || product === void 0 ? void 0 : product.name) !== null && _ref3 !== void 0 ? _ref3 : cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.title) !== null && _ref2 !== void 0 ? _ref2 : cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.name) !== null && _ref !== void 0 ? _ref : String((_product$id = product === null || product === void 0 ? void 0 : product.id) !== null && _product$id !== void 0 ? _product$id : "");
}
/**
* 创建带防抖的 `addProductWithFlow`：
* - OS `decideAddProduct` 为 `requiresDetail` / `requiresBookingEdit` 时立即走完整弹窗链；
* - 仅 `action === 'add'` 时合并数量、防抖后一次 `addProduct`；
* - Toast 仅在加车成功（`status === 'added'`）后展示，避免 Holder / 跨日弹窗尚未完成时误提示。
*/
function createAddProductWithFlowDebounced(deps) {
	var _deps$defaultDebounce;
	const pendingMap = /* @__PURE__ */ new Map();
	const timerMap = /* @__PURE__ */ new Map();
	const defaultDebounceMs = (_deps$defaultDebounce = deps.defaultDebounceMs) !== null && _deps$defaultDebounce !== void 0 ? _deps$defaultDebounce : 100;
	const flushKey = function() {
		var _ref4 = _asyncToGenerator(function* (key) {
			const entry = pendingMap.get(key);
			if (!entry) return;
			pendingMap.delete(key);
			timerMap.delete(key);
			const { product, options, quantity, waiters } = entry;
			try {
				const flowResult = toFlowResult(yield deps.addProductDirect(product, _objectSpread2(_objectSpread2({}, options), {}, { quantity })));
				if (!options.notShowToast && flowResult.status === "added") {
					const inCart = resolveInCartQuantityForAddToast(deps.getCartItems(), product.id);
					showAddToCartToast(deps.Toast, resolveProductTitle(product, entry.cacheItem), inCart + quantity);
				}
				waiters.forEach((w) => w.resolve(flowResult));
			} catch (error) {
				waiters.forEach((w) => w.reject(error));
			}
		});
		return function flushKey(_x) {
			return _ref4.apply(this, arguments);
		};
	}();
	const scheduleFlush = (key, debounceMs) => {
		const existing = timerMap.get(key);
		if (existing) clearTimeout(existing);
		timerMap.set(key, setTimeout(() => {
			flushKey(key).catch(() => {});
		}, debounceMs));
	};
	function addProductWithFlow(_x2, _x3) {
		return _addProductWithFlow.apply(this, arguments);
	}
	function _addProductWithFlow() {
		_addProductWithFlow = _asyncToGenerator(function* (product, options) {
			var _callOptions$quantity;
			const callOptions = options !== null && options !== void 0 ? options : {};
			const decision = deps.decideAddProduct(product, {
				type: callOptions.type,
				quantity: callOptions.quantity
			});
			if (decision.action !== "add") return deps.runAddProductFlow(product, callOptions);
			const debounceMs = callOptions.debounceMs !== void 0 ? callOptions.debounceMs : defaultDebounceMs;
			const addQty = (_callOptions$quantity = callOptions.quantity) !== null && _callOptions$quantity !== void 0 ? _callOptions$quantity : 1;
			const key = resolveAddProductDebounceKey(product, decision.cacheItem);
			if (debounceMs <= 0) {
				const result = yield deps.addProductDirect(product, _objectSpread2(_objectSpread2({}, callOptions), {}, { quantity: addQty }));
				if (!callOptions.notShowToast && result.status === "added") {
					const inCart = resolveInCartQuantityForAddToast(deps.getCartItems(), product.id);
					showAddToCartToast(deps.Toast, resolveProductTitle(product, decision.cacheItem), inCart + addQty);
				}
				return toFlowResult(result);
			}
			let entry = pendingMap.get(key);
			if (entry) entry.quantity += addQty;
			else {
				entry = {
					product,
					options: callOptions,
					quantity: addQty,
					cacheItem: decision.cacheItem,
					waiters: []
				};
				pendingMap.set(key, entry);
			}
			return new Promise((resolve, reject) => {
				entry.waiters.push({
					resolve,
					reject
				});
				scheduleFlush(key, debounceMs);
			});
		});
		return _addProductWithFlow.apply(this, arguments);
	}
	return { addProductWithFlow };
}
//#endregion
export { createAddProductWithFlowDebounced };
