import { n as MixedCurrencyError, t as CartValidationError } from "./errors-DXMuB65Y.js";
//#region src/reduce.ts
function computeSubtotal(lines) {
	return lines.reduce((sum, line) => sum + line.price.amount * BigInt(line.qty), 0n);
}
function cloneCart(cart) {
	return {
		id: cart.id,
		currency: cart.currency,
		lines: cart.lines.map((line) => ({
			...line,
			price: { ...line.price }
		})),
		subtotal: cart.subtotal
	};
}
function assertPositiveIntegerQty(qty) {
	if (!Number.isInteger(qty) || qty <= 0) throw new CartValidationError("qty");
}
function assertCurrencyMatch(cartCurrency, lineCurrency) {
	if (cartCurrency !== "" && lineCurrency !== cartCurrency) throw new MixedCurrencyError(cartCurrency, lineCurrency);
}
function cartReduce(state, action) {
	switch (action.type) {
		case "addLine": {
			assertPositiveIntegerQty(action.qty);
			assertCurrencyMatch(state.currency, action.price.currency);
			const currency = state.lines.length === 0 ? action.price.currency : state.currency;
			const vendorId = action.vendorId ?? null;
			const existingIndex = state.lines.findIndex((line) => line.variantId === action.variantId);
			let lines;
			if (existingIndex >= 0) lines = state.lines.map((line, index) => index === existingIndex ? {
				...line,
				qty: line.qty + action.qty,
				price: { ...action.price },
				vendorId
			} : {
				...line,
				price: { ...line.price }
			});
			else lines = [...state.lines.map((line) => ({
				...line,
				price: { ...line.price }
			})), {
				lineId: crypto.randomUUID(),
				variantId: action.variantId,
				qty: action.qty,
				price: { ...action.price },
				vendorId
			}];
			return {
				id: state.id,
				currency,
				lines,
				subtotal: computeSubtotal(lines)
			};
		}
		case "setQty": {
			assertPositiveIntegerQty(action.qty);
			const lineIndex = state.lines.findIndex((line) => line.lineId === action.lineId);
			if (lineIndex < 0) throw new CartValidationError("lineId");
			const lines = state.lines.map((line, index) => index === lineIndex ? {
				...line,
				qty: action.qty,
				price: { ...line.price }
			} : {
				...line,
				price: { ...line.price }
			});
			return {
				id: state.id,
				currency: state.currency,
				lines,
				subtotal: computeSubtotal(lines)
			};
		}
		case "removeLine": {
			if (state.lines.findIndex((line) => line.lineId === action.lineId) < 0) return cloneCart(state);
			const lines = state.lines.filter((line) => line.lineId !== action.lineId).map((line) => ({
				...line,
				price: { ...line.price }
			}));
			return {
				id: state.id,
				currency: state.lines.length === 1 ? "" : state.currency,
				lines,
				subtotal: computeSubtotal(lines)
			};
		}
		case "clear": return {
			id: state.id,
			currency: "",
			lines: [],
			subtotal: 0n
		};
	}
}
function groupByVendor(cart) {
	const groups = [];
	const indexByVendor = /* @__PURE__ */ new Map();
	for (const line of cart.lines) {
		const vendorId = line.vendorId;
		const existingIndex = indexByVendor.get(vendorId);
		if (existingIndex === void 0) {
			indexByVendor.set(vendorId, groups.length);
			groups.push({
				vendorId,
				lines: [{
					...line,
					price: { ...line.price }
				}],
				subtotal: line.price.amount * BigInt(line.qty)
			});
		} else {
			const group = groups[existingIndex];
			group.lines.push({
				...line,
				price: { ...line.price }
			});
			group.subtotal += line.price.amount * BigInt(line.qty);
		}
	}
	return groups;
}
//#endregion
export { groupByVendor as n, cartReduce as t };
