const require_chunk = require("./chunk-9hOWP6kD.cjs");
const require_FluidProvider = require("./FluidProvider-IQDml4f2.cjs");
const require_static_dict_adapter = require("./static-dict-adapter-D1ErNskC.cjs");
const require_src = require("./src-B0ut9PTw.cjs");
const require_ScreenHeaderContext = require("./ScreenHeaderContext-CsfhnuJk.cjs");
const require_use_store = require("./use-store-DvtLtZ3f.cjs");
const require_AppNavigationContext = require("./AppNavigationContext-C1-hd9Rw.cjs");
const require_PortalProductsApiProvider = require("./PortalProductsApiProvider-BNsaexxl.cjs");
let react = require("react");
react = require_chunk.__toESM(react);
let _tanstack_react_query = require("@tanstack/react-query");
let react_jsx_runtime = require("react/jsx-runtime");
let lucide_react = require("lucide-react");
let react_dom = require("react-dom");
//#region ../../shop/core/src/translation-api-context.ts
const { Provider, useTranslation } = require_static_dict_adapter.createTranslationContext("Shop");
const ShopTranslationProvider = Provider;
const useShopTranslation = useTranslation;
//#endregion
//#region ../../shop/ui/src/utils/media-helpers.ts
const VIDEO_EXTENSIONS = [
	".mp4",
	".webm",
	".mov",
	".avi",
	".m4v",
	".mkv",
	".ogv",
	".ogg",
	".wmv",
	".flv",
	".3gp"
];
function isVideoUrl(url) {
	if (!url) return false;
	const lowerUrl = url.toLowerCase();
	return VIDEO_EXTENSIONS.some((ext) => lowerUrl.includes(ext));
}
function getVideoThumbnailUrl(videoUrl) {
	if (videoUrl.includes("ik.imagekit.io")) return `${videoUrl}/ik-thumbnail.jpg`;
	return videoUrl;
}
//#endregion
//#region ../../shop/ui/src/components/product-card.tsx
function tagPortalProduct(product) {
	return {
		...product,
		__portalProduct: true
	};
}
function isPortalProduct(product) {
	return "__portalProduct" in product && product.__portalProduct === true;
}
function getPortalProductCoverImage(product) {
	if (product.images && product.images.length > 0) return product.images[0]?.url ?? null;
	return null;
}
function defaultRenderImage$1({ src, alt, fill, className, onError }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
		src,
		alt,
		className: `${fill ? "absolute inset-0 h-full w-full" : ""} ${className ?? ""}`,
		onError
	});
}
function formatPortalPrice(price, currency) {
	if (!price) return null;
	const numericPrice = Number(price);
	if (Number.isNaN(numericPrice)) return `${currency ?? ""}${price}`;
	try {
		return new Intl.NumberFormat(void 0, {
			style: "currency",
			currency: currency || "USD"
		}).format(numericPrice);
	} catch {
		return `$${price}`;
	}
}
function ProductCardContent({ product, countryIso, companyLogoUrl, renderImage = defaultRenderImage$1 }) {
	const [isHovered, setIsHovered] = (0, react.useState)(false);
	const { t } = useShopTranslation();
	const isPortal = isPortalProduct(product);
	const coverImage = isPortal ? getPortalProductCoverImage(product) : require_PortalProductsApiProvider.getProductImageUrl(product);
	const isVideo = isVideoUrl(coverImage);
	const productName = isPortal ? product.name || t("no_title") : product.title || t("no_title");
	let repPrice = null;
	let price = null;
	if (isPortal) if (product.wholesale_price) {
		repPrice = formatPortalPrice(product.wholesale_price, product.currency);
		const retailFormatted = formatPortalPrice(product.price, product.currency);
		if (retailFormatted !== repPrice) price = retailFormatted;
	} else repPrice = formatPortalPrice(product.price, product.currency);
	else if (countryIso) {
		const prices = require_PortalProductsApiProvider.determineProductPrice(product, countryIso);
		repPrice = prices.repPrice;
		price = prices.price;
	}
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		className: "bg-muted relative aspect-square overflow-hidden",
		onMouseEnter: () => isVideo && setIsHovered(true),
		onMouseLeave: () => isVideo && setIsHovered(false),
		children: [isVideo && isHovered ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
			src: coverImage || "",
			className: "absolute inset-0 h-full w-full object-cover",
			autoPlay: true,
			muted: true,
			loop: true,
			playsInline: true
		}) : renderImage({
			src: isVideo && coverImage ? getVideoThumbnailUrl(coverImage) : coverImage || "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png",
			alt: productName,
			fill: true,
			className: "object-cover transition-transform group-hover:scale-105",
			onError: (e) => {
				e.currentTarget.src = companyLogoUrl || "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
			},
			unoptimized: true
		}), isVideo && !isHovered && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "absolute inset-0 flex items-center justify-center",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				className: "flex h-16 w-16 items-center justify-center rounded-full bg-black/50 backdrop-blur-sm",
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CirclePlay, { className: "h-12 w-12 text-white" })
			})
		})]
	}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		className: "px-3 pt-2 pb-4",
		children: [
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
				className: "text-foreground line-clamp-1 text-sm font-bold",
				children: productName
			}),
			/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "flex items-center gap-2",
				children: [repPrice && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
					className: "text-foreground text-sm font-bold",
					children: repPrice
				}), price && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
					className: "text-muted-foreground text-sm line-through",
					children: price
				})]
			}),
			!isPortal && countryIso && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "text-muted-foreground text-sm",
				children: [
					"CV",
					" ",
					getVariantCountryValue(getSelectedVariant(product), countryIso, "cv") || "-",
					" ",
					"| QV",
					" ",
					getVariantCountryValue(getSelectedVariant(product), countryIso, "qv") || "-"
				]
			}),
			isPortal && product.wholesale_price != null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "text-muted-foreground text-sm",
				children: [
					"CV ",
					product.cv ?? "-",
					" | QV ",
					product.qv ?? "-"
				]
			})
		]
	})] });
}
function getSelectedVariant(product) {
	if (!product.variants || product.variants.length === 0) return null;
	const masterVariant = product.variants.find((v) => {
		return "is_master" in v && v.is_master;
	});
	if (masterVariant) return masterVariant;
	return product.variants[0] || null;
}
function getVariantCountryValue(variant, countryIso, field) {
	if (!variant || !variant.variant_countries) return null;
	if (typeof variant.variant_countries === "object" && !Array.isArray(variant.variant_countries)) return variant.variant_countries[countryIso]?.[field] ?? null;
	if (Array.isArray(variant.variant_countries)) return variant.variant_countries.find((vc) => vc.country_iso === countryIso)?.[field] ?? null;
	return null;
}
function ProductCard({ product, countryIso, companyLogoUrl, showShareModal = false, setShareModalOpen, setSelectedProduct, renderLink, renderImage, onClick }) {
	const cardContent = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductCardContent, {
		product,
		countryIso,
		companyLogoUrl,
		renderImage
	});
	const cardClassName = "overflow-hidden border-0 shadow-none pt-0 gap-0";
	if (showShareModal && !isPortalProduct(product)) {
		const handleShareClick = () => {
			if (setSelectedProduct && setShareModalOpen) {
				setSelectedProduct(product);
				setShareModalOpen(true);
			}
		};
		return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Card, {
			className: cardClassName,
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
				onClick: handleShareClick,
				className: "group block w-full cursor-pointer text-left",
				children: cardContent
			})
		});
	}
	if (onClick) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Card, {
		className: cardClassName,
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
			onClick,
			className: "group block w-full cursor-pointer text-left",
			children: cardContent
		})
	});
	const href = `/portal/shop/${product.id}`;
	if (renderLink) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Card, {
		className: cardClassName,
		children: renderLink({
			href,
			children: cardContent
		})
	});
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Card, {
		className: cardClassName,
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
			href,
			className: "group block cursor-pointer",
			children: cardContent
		})
	});
}
//#endregion
//#region ../../shop/ui/src/components/image-gallery.tsx
function defaultRenderImage({ src, alt, fill, className, onError }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
		src,
		alt,
		className: `${fill ? "absolute inset-0 h-full w-full" : ""} ${className ?? ""}`,
		onError
	});
}
function ImageGallery({ images, fallbackImageUrl, productTitle, renderImage = defaultRenderImage }) {
	const [currentImageIndex, setCurrentImageIndex] = (0, react.useState)(0);
	const hasMultipleImages = images && images.length > 0;
	const displayImages = (0, react.useMemo)(() => hasMultipleImages ? [...images].sort((a, b) => a.position - b.position) : [{
		id: 0,
		image_url: fallbackImageUrl,
		position: 0
	}], [
		images,
		hasMultipleImages,
		fallbackImageUrl
	]);
	(0, react.useEffect)(() => {
		setCurrentImageIndex(0);
	}, [displayImages]);
	const nextImage = () => {
		if (displayImages.length > 1) setCurrentImageIndex((prev) => (prev + 1) % displayImages.length);
	};
	const prevImage = () => {
		if (displayImages.length > 1) setCurrentImageIndex((prev) => (prev - 1 + displayImages.length) % displayImages.length);
	};
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "space-y-4",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "group relative aspect-square overflow-hidden rounded-sm bg-gray-100",
			children: [
				isVideoUrl(displayImages[currentImageIndex]?.image_url) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("video", {
					src: displayImages[currentImageIndex]?.image_url,
					className: "absolute inset-0 h-full w-full object-cover",
					controls: true,
					loop: true,
					playsInline: true
				}, displayImages[currentImageIndex]?.id) : renderImage({
					src: displayImages[currentImageIndex]?.image_url || fallbackImageUrl,
					alt: productTitle,
					fill: true,
					className: "object-cover",
					onError: (e) => {
						e.currentTarget.src = "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png";
					},
					unoptimized: true
				}),
				displayImages.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
					type: "button",
					"aria-label": "Previous image",
					className: "absolute top-1/2 left-3 z-10 flex h-8 w-8 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/40 shadow-sm transition-colors group-hover:bg-white/80 hover:bg-white",
					onClick: prevImage,
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronLeft, { className: "h-5 w-5 text-black/40 transition-colors group-hover:text-black" })
				}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
					type: "button",
					"aria-label": "Next image",
					className: "absolute top-1/2 right-3 z-10 flex h-8 w-8 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/40 shadow-sm transition-colors group-hover:bg-white/80 hover:bg-white",
					onClick: nextImage,
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, { className: "h-5 w-5 text-black/40 transition-colors group-hover:text-black" })
				})] }),
				displayImages.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					className: "absolute bottom-3 left-1/2 flex -translate-x-1/2 gap-3",
					children: displayImages.map((_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
						type: "button",
						className: `h-1.5 w-6 cursor-pointer rounded-lg transition-colors ${index === currentImageIndex ? "bg-gray-800" : "bg-gray-400 hover:bg-gray-600"}`,
						"aria-label": `Go to image ${index + 1}`,
						onClick: () => setCurrentImageIndex(index)
					}, index))
				})
			]
		})
	});
}
//#endregion
//#region ../../shop/ui/src/components/quantity-selector.tsx
function QuantitySelector({ quantity, setQuantity }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "flex items-center gap-3",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "flex items-center rounded-lg",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
					variant: "default",
					onClick: () => setQuantity(Math.max(1, quantity - 1)),
					className: "border-0 px-3 py-2 shadow-none",
					children: "−"
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
					className: "text-foreground min-w-8 px-4 py-2 text-center text-sm font-medium",
					children: quantity
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
					variant: "default",
					onClick: () => setQuantity(quantity + 1),
					className: "border-0 px-3 py-2 shadow-none",
					children: "+"
				})
			]
		})
	});
}
//#endregion
//#region ../../shop/ui/src/components/purchase-options.tsx
function PurchaseOptions({ showBuyOnce, showSubscribe, isSubscribe, onSubscribeChange, product_subscription_plans, selectedSubscriptionPlan, onSubscriptionPlanChange, userSelectedSubscribe, wholesalePrice, wholesaleSubscriptionPrice }) {
	const { t } = useShopTranslation();
	const defaultSubscriptionPlan = (0, react.useMemo)(() => {
		if (!product_subscription_plans?.length) return null;
		return product_subscription_plans.find((plan) => plan.default) || product_subscription_plans[0];
	}, [product_subscription_plans]);
	const currentSubscriptionPlan = selectedSubscriptionPlan || defaultSubscriptionPlan;
	const savingsPercentage = (0, react.useMemo)(() => {
		if (wholesalePrice === void 0 || wholesaleSubscriptionPrice === void 0 || wholesalePrice <= 0) return null;
		const savings = wholesalePrice - wholesaleSubscriptionPrice;
		if (savings <= 0) return null;
		const pct = Math.round(savings / wholesalePrice * 100);
		return pct > 0 ? pct : null;
	}, [wholesalePrice, wholesaleSubscriptionPrice]);
	const formatSubscriptionPlan = (plan) => {
		return `${plan.subscription_plan.billing_interval} ${plan.subscription_plan.billing_interval_unit} (${plan.subscription_plan.name})`;
	};
	const subscriptionPlanOptions = (0, react.useMemo)(() => {
		if (!product_subscription_plans?.length) return [];
		return product_subscription_plans.map((plan) => ({
			value: plan.subscription_plan.id.toString(),
			label: formatSubscriptionPlan(plan)
		}));
	}, [product_subscription_plans]);
	if (showBuyOnce && !showSubscribe) return null;
	const handleSubscriptionPlanChange = (planId) => {
		const selectedPlan = product_subscription_plans?.find((plan) => plan.subscription_plan.id.toString() === planId);
		if (selectedPlan && onSubscriptionPlanChange) onSubscriptionPlanChange(selectedPlan);
	};
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "mb-3 flex flex-col",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.RadioGroup, {
			value: isSubscribe ? "subscribe" : "once",
			onValueChange: (value) => onSubscribeChange(value === "subscribe"),
			className: "gap-0 space-y-0",
			children: [showSubscribe && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				onClick: () => onSubscribeChange(true),
				className: `cursor-pointer rounded-t-lg p-4 text-left transition-all duration-200 ${showBuyOnce ? "border border-b-0" : "rounded-b-lg"} ${userSelectedSubscribe ? "bg-muted" : "bg-background"}`,
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "flex items-start space-x-3",
					children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.RadioGroupItem, {
						value: "subscribe",
						onClick: (e) => e.stopPropagation(),
						className: `flex items-center justify-center [&_svg]:h-1.5 [&_svg]:w-1.5 [&_svg]:fill-white ${isSubscribe ? "border-contrast bg-contrast text-foreground" : "border-border bg-background text-muted-foreground"}`
					}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
						className: "flex-1",
						children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
							className: "text-foreground mb-1 text-sm leading-tight font-medium",
							children: savingsPercentage ? t("subscribe_and_save", { percentage: savingsPercentage }) : t("subscribe")
						}), product_subscription_plans?.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "bg-muted mt-3 rounded-lg p-2",
							onClick: (e) => e.stopPropagation(),
							children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
								className: "text-foreground mb-1 text-xs font-medium",
								children: t("delivery_frequency")
							}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Select, {
								value: currentSubscriptionPlan?.subscription_plan.id.toString() || "",
								onValueChange: handleSubscriptionPlanChange,
								disabled: product_subscription_plans?.length === 1,
								children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectTrigger, {
									className: "bg-background text-foreground! w-full text-xs",
									children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectValue, { placeholder: t("select_delivery_schedule") })
								}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectContent, { children: subscriptionPlanOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectItem, {
									value: option.value,
									children: option.label
								}, option.value)) })]
							})]
						})]
					})]
				})
			}), showBuyOnce && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				onClick: () => onSubscribeChange(false),
				className: `cursor-pointer rounded-b-lg border p-4 text-left transition-all duration-200 ${showSubscribe ? "border-t-0" : "rounded-t-lg"} ${!userSelectedSubscribe ? "bg-muted" : "bg-background"}`,
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "flex items-center space-x-3",
					children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.RadioGroupItem, {
						value: "once",
						onClick: (e) => e.stopPropagation(),
						className: `flex items-center justify-center [&_svg]:h-1.5 [&_svg]:w-1.5 [&_svg]:fill-white ${!isSubscribe ? "border-contrast bg-contrast text-foreground" : "border-border bg-background text-muted-foreground"}`
					}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
						className: "text-foreground mb-1 text-sm leading-tight font-medium",
						children: t("one_time_purchase")
					})]
				})
			})]
		})
	});
}
//#endregion
//#region ../../shop/ui/src/components/shop-app.tsx
const PAGE_SIZE = 25;
function sanitizeHtml(html) {
	const doc = new DOMParser().parseFromString(html, "text/html");
	for (const el of doc.querySelectorAll("script, iframe, object, embed, form, base, meta, link, style")) el.remove();
	for (const el of doc.querySelectorAll("*")) for (const attr of [...el.attributes]) if (attr.name.toLowerCase().startsWith("on") || attr.value.toLowerCase().trim().startsWith("javascript:")) el.removeAttribute(attr.name);
	return doc.body.innerHTML;
}
const GRID_CLASS = "grid grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4";
function SkeletonGrid({ count = 8 }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: GRID_CLASS,
		children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "space-y-2",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "aspect-square w-full rounded-lg" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-4 w-3/4" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-4 w-1/2" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-3 w-1/3" })
			]
		}, i))
	});
}
function ProductListing({ companyLogoUrl, renderImage, onSelectProduct, cartButton }) {
	const observerTarget = (0, react.useRef)(null);
	const { t } = useShopTranslation();
	const catalog = require_PortalProductsApiProvider.usePortalProductCatalog({ perPage: PAGE_SIZE });
	const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage, error, isFetched } = (0, _tanstack_react_query.useInfiniteQuery)({
		queryKey: catalog.queryKey,
		queryFn: ({ pageParam }) => catalog.fetchProducts(pageParam),
		getNextPageParam: catalog.getNextPageParam,
		initialPageParam: void 0
	});
	const handleIntersect = (0, react.useCallback)((entries) => {
		if (entries[0]?.isIntersecting && hasNextPage && !isFetchingNextPage) fetchNextPage();
	}, [
		hasNextPage,
		isFetchingNextPage,
		fetchNextPage
	]);
	(0, react.useEffect)(() => {
		const target = observerTarget.current;
		if (!target) return;
		const observer = new IntersectionObserver(handleIntersect, {
			threshold: .1,
			rootMargin: "200px"
		});
		observer.observe(target);
		return () => observer.disconnect();
	}, [handleIntersect]);
	const allProducts = data?.pages.flatMap((page) => page.products) ?? [];
	const sortOptions = (0, react.useMemo)(() => [
		{
			id: "title_asc",
			label: t("sort_title_asc")
		},
		{
			id: "title_desc",
			label: t("sort_title_desc")
		},
		{
			id: "price_asc",
			label: t("sort_price_asc")
		},
		{
			id: "price_desc",
			label: t("sort_price_desc")
		},
		{
			id: "created_at_desc",
			label: t("sort_recent")
		},
		{
			id: "created_at_asc",
			label: t("sort_oldest")
		}
	], [t]);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "mx-auto px-2 md:px-10",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "flex items-center justify-end gap-2 py-4",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					className: "w-full max-w-sm",
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_PortalProductsApiProvider.SearchSort, {
						searchValue: catalog.searchTerm,
						onSearchChange: catalog.setSearchTerm,
						placeholder: t("search_placeholder")
					})
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuTrigger, {
					asChild: true,
					children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
						variant: "outline",
						size: "icon",
						className: "border-foreground/10 shadow-input h-9 w-9 shrink-0",
						children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUpDown, { className: "h-3 w-3" })
					})
				}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.DropdownMenuContent, {
					align: "end",
					className: "w-60",
					children: [
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuLabel, { children: t("sort_by") }),
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuSeparator, {}),
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuRadioGroup, {
							value: catalog.currentSort,
							onValueChange: catalog.setCurrentSort,
							children: sortOptions.map((opt) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.DropdownMenuRadioItem, {
								value: opt.id,
								children: opt.label
							}, opt.id))
						})
					]
				})] }),
				cartButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					className: "flex shrink-0 items-center gap-3",
					children: cartButton
				})
			]
		})
	}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "mx-auto space-y-8 px-2 md:px-10 md:py-8",
		children: isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonGrid, {}) : error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
			className: "mx-auto my-6 rounded-lg bg-red-100 px-3 py-2 text-red-500",
			children: t("error_generic")
		}) : isFetched && allProducts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "flex flex-col items-center justify-center py-8 text-center",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
				className: "text-muted-foreground text-sm",
				children: catalog.searchTerm ? t("no_search_results", { term: catalog.searchTerm }) : t("no_products")
			})
		}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
				className: GRID_CLASS,
				children: allProducts.map((product) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductCard, {
					product: tagPortalProduct(product),
					companyLogoUrl,
					renderImage,
					onClick: () => onSelectProduct(String(product.id))
				}, product.id))
			}),
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: observerTarget }),
			isFetchingNextPage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonGrid, { count: 4 })
		] })
	})] });
}
/**
* Build the variant options map by grouping option_values across non-master variants.
* Groups by option_id, collecting unique value entries.
*/
function buildOptionGroups(variants) {
	const groupMap = /* @__PURE__ */ new Map();
	for (const variant of variants) {
		if (variant.is_master) continue;
		for (const ov of variant.option_values ?? []) {
			if (ov.option_id == null || ov.id == null) continue;
			if (!groupMap.has(ov.option_id)) groupMap.set(ov.option_id, {
				name: ov.option_name ?? `Option ${ov.option_id}`,
				values: /* @__PURE__ */ new Map()
			});
			groupMap.get(ov.option_id).values.set(ov.id, ov.name ?? String(ov.id));
		}
	}
	return [...groupMap.entries()].map(([optionId, group]) => ({
		optionId,
		name: group.name,
		values: [...group.values.entries()].map(([id, name]) => ({
			id,
			name
		}))
	}));
}
/**
* Find the variant matching a set of selected option value IDs.
* selections is a map of optionId → selected value id.
*/
function findVariantBySelections(variants, selections) {
	const entries = Object.entries(selections).map(([k, v]) => [Number(k), v]);
	if (entries.length === 0) return void 0;
	return variants.find((v) => !v.is_master && entries.every(([optionId, valueId]) => v.option_values?.some((ov) => ov.option_id === optionId && ov.id === valueId)));
}
/**
* Map BFF flat subscription plans to the legacy ProductSubscriptionPlan shape
* expected by the PurchaseOptions component.
*/
function mapToLegacySubscriptionPlans(plans) {
	return plans.map((plan, idx) => ({
		id: plan.id,
		default: idx === 0,
		products_count: null,
		subscribers_count: null,
		active: true,
		subscription_plan: {
			id: plan.id ?? 0,
			name: plan.name ?? "",
			billing_interval: plan.billing_interval ?? 1,
			billing_interval_unit: plan.billing_interval_unit ?? "month",
			billing_frequency_in_words: plan.billing_frequency ?? `${plan.billing_interval} ${plan.billing_interval_unit}`,
			active: true,
			price_adjustment_amount: null,
			price_adjustment_type: null
		}
	}));
}
function formatPrice(price, currency) {
	if (!price) return null;
	const numericPrice = Number(price);
	if (Number.isNaN(numericPrice)) return `${currency ?? ""}${price}`;
	try {
		return new Intl.NumberFormat(void 0, {
			style: "currency",
			currency: currency || "USD"
		}).format(numericPrice);
	} catch {
		return `$${price}`;
	}
}
function ProductDetail({ productId, renderImage }) {
	const [quantity, setQuantity] = (0, react.useState)(1);
	const [selections, setSelections] = (0, react.useState)({});
	const [userSelectedSubscribe, setUserSelectedSubscribe] = (0, react.useState)(false);
	const [selectedSubscriptionPlan, setSelectedSubscriptionPlan] = (0, react.useState)(void 0);
	const { t } = useShopTranslation();
	const { product, isLoading, error, images } = require_PortalProductsApiProvider.usePortalProductDetail({ productId });
	const variants = (0, react.useMemo)(() => product?.variants ?? [], [product?.variants]);
	const subscriptionPlans = (0, react.useMemo)(() => product?.subscription_plans ?? [], [product?.subscription_plans]);
	const masterVariant = (0, react.useMemo)(() => variants.find((v) => v.is_master) ?? variants[0], [variants]);
	const optionGroups = (0, react.useMemo)(() => buildOptionGroups(variants), [variants]);
	const showVariantChoices = optionGroups.length === 0 && variants.length > 1;
	const [selectedVariantId, setSelectedVariantId] = (0, react.useState)(null);
	(0, react.useEffect)(() => {
		if (optionGroups.length === 0) return;
		const source = variants.find((v) => !v.is_master) ?? masterVariant;
		if (!source?.option_values?.length) return;
		const defaults = {};
		for (const ov of source.option_values) if (ov.option_id != null && ov.id != null) defaults[ov.option_id] = ov.id;
		setSelections(defaults);
	}, [
		optionGroups,
		variants,
		masterVariant
	]);
	(0, react.useEffect)(() => {
		if (!showVariantChoices) return;
		if (selectedVariantId != null) return;
		if (masterVariant?.id == null) return;
		setSelectedVariantId(masterVariant.id);
	}, [
		showVariantChoices,
		selectedVariantId,
		masterVariant?.id
	]);
	const selectedVariant = (0, react.useMemo)(() => {
		if (showVariantChoices) return variants.find((v) => v.id === selectedVariantId) ?? masterVariant;
		if (optionGroups.length === 0) return masterVariant;
		return findVariantBySelections(variants, selections) ?? masterVariant;
	}, [
		variants,
		optionGroups,
		selections,
		masterVariant,
		showVariantChoices,
		selectedVariantId
	]);
	const legacySubscriptionPlans = (0, react.useMemo)(() => mapToLegacySubscriptionPlans(subscriptionPlans), [subscriptionPlans]);
	const isSubscribe = selectedVariant?.subscription_only === true || userSelectedSubscribe;
	const showSubscribe = legacySubscriptionPlans.length > 0;
	const showBuyOnce = selectedVariant?.subscription_only !== true;
	(0, react.useEffect)(() => {
		if (selectedVariant?.subscription_only && legacySubscriptionPlans.length > 0) setUserSelectedSubscribe(true);
	}, [selectedVariant, legacySubscriptionPlans]);
	const galleryImages = (0, react.useMemo)(() => {
		const variantImages = selectedVariant?.images;
		if (variantImages && variantImages.length > 0) return variantImages.map((img, idx) => ({
			id: idx,
			image_url: img.url ?? "",
			image_path: null,
			position: idx
		}));
		return images.map((img, idx) => ({
			id: img.id ?? idx,
			image_url: img.url,
			image_path: null,
			position: idx
		}));
	}, [selectedVariant?.images, images]);
	const coverImage = galleryImages[0]?.image_url ?? null;
	const selectedPricing = selectedVariant?.subscription_pricing?.find((sp) => sp.plan_id === (selectedSubscriptionPlan?.subscription_plan.id ?? legacySubscriptionPlans[0]?.subscription_plan.id));
	const wholesalePrice = selectedVariant?.wholesale_price ? Number(selectedVariant.wholesale_price) : void 0;
	const wholesaleSubscriptionPrice = selectedPricing?.wholesale_price ? Number(selectedPricing.wholesale_price) : void 0;
	const currency = selectedVariant?.currency ?? product?.currency;
	const displayPrice = formatPrice(selectedVariant?.price ?? product?.price, currency);
	const displayWholesalePrice = formatPrice(selectedVariant?.wholesale_price ?? selectedVariant?.price ?? product?.price, currency);
	const displayWholesaleSubscriptionPrice = formatPrice(selectedPricing?.wholesale_price ?? selectedPricing?.price ?? selectedVariant?.wholesale_price ?? void 0, currency);
	const resolvedPlanId = selectedSubscriptionPlan?.subscription_plan.id ?? legacySubscriptionPlans.find((p) => p.default)?.subscription_plan.id ?? legacySubscriptionPlans[0]?.subscription_plan.id;
	const cartVariantId = String(selectedVariant?.id ?? product?.id ?? "");
	if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "mx-auto max-w-7xl py-8 pr-4 pl-0 md:pr-6 lg:pr-8 lg:pl-0",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "grid grid-cols-1 gap-5 lg:grid-cols-2",
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "aspect-square w-full rounded-lg" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "space-y-4 pl-2 lg:pl-20",
				children: [
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-8 w-3/4" }),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-5 w-1/4" }),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-20 w-full" }),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-10 w-1/2" }),
					/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Skeleton, { className: "h-10 w-full" })
				]
			})]
		})
	});
	if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "flex min-h-[400px] items-center justify-center",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "text-center",
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
				className: "text-foreground mb-2 text-lg font-medium",
				children: t("error_loading")
			}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
				className: "text-muted-foreground",
				children: t("error_generic")
			})]
		})
	});
	if (!product) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "flex min-h-[400px] items-center justify-center",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "text-center",
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
				className: "text-foreground mb-2 text-lg font-medium",
				children: t("product_not_found")
			}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
				className: "text-muted-foreground",
				children: t("product_not_found_description")
			})]
		})
	});
	const title = product.name || t("product_fallback_name");
	const isBundle = product.bundle === true;
	const bundleUrl = isBundle && product.canonical_url ? product.canonical_url : null;
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: "pb-5 md:pl-8",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "mx-auto max-w-7xl px-4 py-8 md:pr-6 md:pl-0 lg:pr-8 lg:pl-0",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "grid grid-cols-1 gap-5 lg:grid-cols-2",
				children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageGallery, {
					images: galleryImages,
					fallbackImageUrl: coverImage ?? "https://assets.fluid.app/fluid-admin/images/we-commerce/we-commerce.png",
					productTitle: title,
					renderImage
				}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "max-w-lg pl-2 lg:pl-20",
					children: [
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
							className: "text-foreground text-3xl font-bold",
							children: title
						}),
						!isBundle && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "mb-2 flex items-center gap-2",
							children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
								className: "text-foreground text-sm",
								children: isSubscribe ? displayWholesaleSubscriptionPrice : displayWholesalePrice
							}), (isSubscribe && displayWholesaleSubscriptionPrice !== displayWholesalePrice || !isSubscribe && displayWholesalePrice !== displayPrice) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
								className: "text-muted-foreground text-sm line-through",
								children: isSubscribe ? displayWholesalePrice : displayPrice
							})]
						}),
						/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "pt-2",
							children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
								className: "text-foreground mb-1 text-sm font-medium",
								children: t("product_description")
							}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
								className: "text-foreground mb-3 text-[12px]",
								dangerouslySetInnerHTML: { __html: sanitizeHtml(product.description ?? "") }
							})]
						}),
						product.wholesale_price != null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "text-muted-foreground mb-3 text-sm",
							children: [
								"CV ",
								selectedVariant?.cv ?? "-",
								" | QV",
								" ",
								selectedVariant?.qv ?? "-"
							]
						}),
						isBundle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "pt-4",
							children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Button, {
								variant: "default",
								className: "w-full gap-2 py-2 text-base font-medium",
								disabled: !bundleUrl,
								onClick: () => {
									if (bundleUrl) window.open(bundleUrl, "_blank", "noopener,noreferrer");
								},
								children: t("purchase_bundle")
							}), !bundleUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
								className: "text-muted-foreground mt-2 text-center text-xs",
								children: t("bundle_unavailable")
							})]
						}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
							/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PurchaseOptions, {
								showBuyOnce,
								showSubscribe,
								isSubscribe,
								userSelectedSubscribe,
								onSubscribeChange: setUserSelectedSubscribe,
								wholesalePrice,
								wholesaleSubscriptionPrice,
								product_subscription_plans: legacySubscriptionPlans,
								selectedSubscriptionPlan,
								onSubscriptionPlanChange: setSelectedSubscriptionPlan
							}),
							optionGroups.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
								className: "mb-4 pt-4",
								children: optionGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
									className: "mb-3 flex items-center",
									children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
										className: "text-md text-foreground w-24 font-bold",
										children: group.name.charAt(0).toUpperCase() + group.name.slice(1)
									}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Select, {
										value: String(selections[group.optionId] ?? ""),
										onValueChange: (value) => setSelections((prev) => ({
											...prev,
											[group.optionId]: Number(value)
										})),
										children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectTrigger, {
											className: "w-48 max-w-full",
											children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectValue, { placeholder: t("select_option", { name: group.name }) })
										}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectContent, {
											position: "popper",
											className: "max-h-60",
											children: group.values.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectItem, {
												value: String(v.id),
												children: v.name
											}, v.id))
										})]
									})]
								}, group.optionId))
							}),
							showVariantChoices && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
								className: "mb-4 pt-4",
								children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
									className: "mb-3 flex items-center",
									children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
										className: "text-md text-foreground w-24 font-bold",
										children: "Variant"
									}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Select, {
										value: selectedVariantId != null ? String(selectedVariantId) : "",
										onValueChange: (value) => setSelectedVariantId(Number(value)),
										children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectTrigger, {
											className: "w-48 max-w-full",
											children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectValue, { placeholder: "Select variant" })
										}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectContent, {
											position: "popper",
											className: "max-h-60",
											children: variants.map((v, idx) => v.id == null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.SelectItem, {
												value: String(v.id),
												children: v.title || `Variant ${idx + 1}`
											}, v.id))
										})]
									})]
								})
							}),
							selectedVariant?.subscription_only && !selectedVariant?.allow_subscription && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
								className: "text-muted-foreground text-sm",
								children: t("product_unavailable")
							}),
							/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "mt-4 mb-3" }),
							/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
								className: "flex items-center gap-3 pb-3",
								children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuantitySelector, {
									quantity,
									setQuantity
								}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
									variant: "default",
									className: "flex-1 gap-2 py-2 text-base font-medium",
									disabled: selectedVariant?.subscription_only === true && !selectedVariant?.allow_subscription,
									"data-fluid-add-to-cart": cartVariantId,
									"data-fluid-quantity": quantity,
									"data-fluid-subscribe": isSubscribe,
									"data-fluid-subscription-plan-id": isSubscribe ? String(resolvedPlanId ?? "") : "",
									"data-fluid-open-cart-after-add": "false",
									children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "h-4 w-4" }), isSubscribe ? t("subscribe") : t("add_to_cart")]
								})]
							})
						] })
					]
				})]
			})
		})
	});
}
function ShopApp({ companyLogoUrl, renderImage, productId: controlledProductId, onSelectProduct: onSelectProductProp, onBack: _onBack, cartButton }) {
	const [internalProductId, setInternalProductId] = (0, react.useState)(null);
	const activeProductId = controlledProductId !== void 0 ? controlledProductId : internalProductId;
	const handleSelectProduct = onSelectProductProp ?? setInternalProductId;
	if (activeProductId) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductDetail, {
		productId: activeProductId,
		renderImage
	});
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductListing, {
		companyLogoUrl,
		renderImage,
		onSelectProduct: handleSelectProduct,
		cartButton
	});
}
//#endregion
//#region ../../cart/ui/src/components/cart-script.tsx
const SCRIPT_ID = "fluid-cdn-script";
const LEAD_CAPTURE_ID = "fluid-lead-capture-suppress";
const DEFAULT_SCRIPT_SRC = "https://assets.fluid.app/scripts/fluid-sdk/latest/web-widgets/index.js";
function CartScript({ subdomain, authJwt, bffMode, scriptSrc, apiBaseUrl, debug }) {
	const authJwtRef = (0, react.useRef)(authJwt);
	authJwtRef.current = authJwt;
	(0, react.useEffect)(() => {
		if (!subdomain) return;
		if (document.getElementById(SCRIPT_ID)) return;
		const script = document.createElement("script");
		script.id = SCRIPT_ID;
		script.src = scriptSrc ?? DEFAULT_SCRIPT_SRC;
		script.type = "module";
		script.crossOrigin = "anonymous";
		script.dataset.fluidShop = subdomain;
		if (bffMode) script.dataset.bffMode = "true";
		else if (authJwtRef.current) script.dataset.authJwt = authJwtRef.current;
		if (apiBaseUrl) script.dataset.fluidApiBaseUrl = apiBaseUrl;
		if (debug) script.dataset.debug = "true";
		document.head.appendChild(script);
		const leadCapture = document.createElement("fluid-lead-capture-widget");
		leadCapture.id = LEAD_CAPTURE_ID;
		leadCapture.setAttribute("hide-widget", "true");
		document.body.appendChild(leadCapture);
		return () => {
			const existing = document.getElementById(SCRIPT_ID);
			if (existing) existing.remove();
			const existingLeadCapture = document.getElementById(LEAD_CAPTURE_ID);
			if (existingLeadCapture) existingLeadCapture.remove();
		};
	}, [
		subdomain,
		bffMode,
		scriptSrc,
		apiBaseUrl,
		debug
	]);
	return null;
}
//#endregion
//#region ../../cart/ui/src/components/cart-widget.tsx
function CartWidget({ theme }) {
	const [mounted, setMounted] = (0, react.useState)(false);
	const widgetRef = (0, react.useRef)(null);
	(0, react.useEffect)(() => {
		setMounted(true);
	}, []);
	(0, react.useEffect)(() => {
		if (!mounted) return;
		const el = widgetRef.current;
		if (!el) return;
		if (theme) el.setAttribute("theme", JSON.stringify(theme));
		else el.removeAttribute("theme");
	}, [theme, mounted]);
	const widget = react.default.createElement("fluid-cart-widget", {
		ref: (el) => {
			widgetRef.current = el;
		},
		"data-fluid-widget": "true",
		"hide-widget": "true",
		"is-primary": "true"
	});
	if (mounted) return (0, react_dom.createPortal)(widget, document.body);
	return null;
}
//#endregion
//#region ../../cart/ui/src/components/cart-button.tsx
const MAX_SDK_POLL_ATTEMPTS = 50;
function CartButton({ onCheckout }) {
	const [initialCount, setInitialCount] = (0, react.useState)(0);
	const navigateToCheckout = (0, react.useCallback)(() => {
		if (!window.FluidCommerceSDK) {
			console.error("FluidCommerceSDK not available");
			return;
		}
		try {
			const checkoutUrl = window.FluidCommerceSDK.getCheckoutUrl();
			if (!checkoutUrl) {
				console.error("No checkout URL available");
				return;
			}
			onCheckout?.(checkoutUrl);
		} catch (error) {
			console.error("Error getting checkout URL:", error);
		}
	}, [onCheckout]);
	(0, react.useEffect)(() => {
		let timeoutId = null;
		let attempts = 0;
		let cancelled = false;
		const setupSDK = () => {
			if (cancelled) return;
			if (window.FluidCommerceSDK) {
				if (onCheckout) window.FluidCommerceSDK.setOnCheckout(navigateToCheckout);
				const count = window.FairShareSDK?.getCartItemCount?.();
				if (count != null) setInitialCount(count);
			} else if (attempts < MAX_SDK_POLL_ATTEMPTS) {
				attempts++;
				timeoutId = setTimeout(setupSDK, 100);
			}
		};
		setupSDK();
		return () => {
			cancelled = true;
			if (timeoutId) clearTimeout(timeoutId);
		};
	}, [navigateToCheckout, onCheckout]);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.Button, {
		className: "bg-primary text-primary-foreground hover:bg-primary/70 relative flex h-8 items-center gap-2 rounded-sm px-3 py-1 text-xs",
		onClick: () => {
			window.fluidCart?.open();
		},
		children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "relative",
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ShoppingCart, { className: "size-4" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
				id: "fluid-cart-count",
				className: "bg-primary-foreground text-primary absolute -top-1 -right-2 flex h-3.5 w-3.5 items-center justify-center rounded-full text-[8px] font-bold",
				children: initialCount
			})]
		}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Cart" })]
	});
}
//#endregion
//#region ../../cart/ui/src/components/shop-container.tsx
function ShopContainer({ children, className = "", cartScript, cartWidget }) {
	const containerRef = (0, react.useRef)(null);
	const [portalContainer, setPortalContainer] = (0, react.useState)(null);
	(0, react.useEffect)(() => {
		const currentContainer = containerRef.current;
		if (!currentContainer) return;
		const reactContentWrapper = document.createElement("div");
		reactContentWrapper.id = "react-content-wrapper";
		reactContentWrapper.style.cssText = `
      position: relative;
    `;
		reactContentWrapper.className = "min-h-full";
		currentContainer.appendChild(reactContentWrapper);
		setPortalContainer(reactContentWrapper);
		return () => {
			if (currentContainer && reactContentWrapper) try {
				currentContainer.removeChild(reactContentWrapper);
			} catch (e) {
				console.warn("Failed to cleanup isolated container:", e);
			}
			setPortalContainer(null);
		};
	}, []);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		ref: containerRef,
		className: `isolated-shop-wrapper ${className} h-full`,
		children: portalContainer && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
			cartScript,
			cartWidget,
			children
		] }), portalContainer)
	}) });
}
//#endregion
//#region ../../shop/core/src/translation-adapter.ts
const shopDomain = require_static_dict_adapter.createDomainTranslations({
	fallback: {
		breadcrumb: "Shop",
		product_fallback_name: "Product",
		search_placeholder: "Search products...",
		sort_by: "Sort By",
		sort_title_asc: "Title (A-Z)",
		sort_title_desc: "Title (Z-A)",
		sort_price_asc: "Price (Low to High)",
		sort_price_desc: "Price (High to Low)",
		sort_recent: "Recently Updated",
		sort_oldest: "Oldest Updated",
		no_products: "There are no products available at the moment.",
		no_search_results: "No products match \"{{term}}\". Try a different search term.",
		error_loading: "Unable to load product",
		error_generic: "Something went wrong. Please try again later.",
		product_not_found: "Product not found",
		product_not_found_description: "The product you're looking for doesn't exist.",
		product_description: "Product Description",
		no_title: "No title available",
		add_to_cart: "Add to Cart",
		subscribe: "Subscribe",
		subscribe_and_save: "Subscribe & Save {{percentage}}%",
		one_time_purchase: "One-Time Purchase",
		delivery_frequency: "Delivery Frequency:",
		select_delivery_schedule: "Select delivery schedule",
		purchase_bundle: "Purchase Bundle",
		bundle_unavailable: "Bundle configuration is unavailable. Please contact support.",
		product_unavailable: "This product is unavailable for purchase.",
		ratings_and_reviews: "Ratings and reviews",
		ratings_count: "{{count}} ratings",
		select_option: "Select {{name}}"
	},
	loaders: {
		de: () => Promise.resolve().then(() => require("./de-CA1BpazO.cjs")).then((m) => m.default),
		el: () => Promise.resolve().then(() => require("./el-BVROkdqG.cjs")).then((m) => m.default),
		es: () => Promise.resolve().then(() => require("./es-C2uchKja.cjs")).then((m) => m.default),
		fr: () => Promise.resolve().then(() => require("./fr-C-2Pj7D2.cjs")).then((m) => m.default),
		he: () => Promise.resolve().then(() => require("./he-BNgtWUzu.cjs")).then((m) => m.default),
		hu: () => Promise.resolve().then(() => require("./hu-BR0rOtJC.cjs")).then((m) => m.default),
		id: () => Promise.resolve().then(() => require("./id-52itow18.cjs")).then((m) => m.default),
		it: () => Promise.resolve().then(() => require("./it-CbZjaErj.cjs")).then((m) => m.default),
		ja: () => Promise.resolve().then(() => require("./ja-BaU2QXo2.cjs")).then((m) => m.default),
		ko: () => Promise.resolve().then(() => require("./ko-vQjiRfrX.cjs")).then((m) => m.default),
		nl: () => Promise.resolve().then(() => require("./nl-DRxCBp_v.cjs")).then((m) => m.default),
		pl: () => Promise.resolve().then(() => require("./pl-AsC20yM9.cjs")).then((m) => m.default),
		pt: () => Promise.resolve().then(() => require("./pt-BBFH5zDu.cjs")).then((m) => m.default),
		ro: () => Promise.resolve().then(() => require("./ro-DS3mARiW.cjs")).then((m) => m.default),
		ru: () => Promise.resolve().then(() => require("./ru-CKfstS2M.cjs")).then((m) => m.default),
		th: () => Promise.resolve().then(() => require("./th-BYXBW0X2.cjs")).then((m) => m.default),
		tl: () => Promise.resolve().then(() => require("./tl-lZlSu-sM.cjs")).then((m) => m.default),
		tr: () => Promise.resolve().then(() => require("./tr-CifdAA_w.cjs")).then((m) => m.default),
		zh_CN: () => Promise.resolve().then(() => require("./zh_CN-BWIy2qoV.cjs")).then((m) => m.default),
		zh_TW: () => Promise.resolve().then(() => require("./zh_TW-D86GUR9C.cjs")).then((m) => m.default)
	}
});
function createShopTranslationAdapter(locale, dict) {
	return require_static_dict_adapter.createStaticDictAdapter(locale, dict);
}
//#endregion
//#region src/providers/ShopTranslationBridge.tsx
function ShopTranslationBridge({ children }) {
	const { locale } = require_static_dict_adapter.useActiveLocale();
	const dict = require_static_dict_adapter.useDomainDict(shopDomain, locale);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopTranslationProvider, {
		value: (0, react.useMemo)(() => createShopTranslationAdapter(locale, dict), [locale, dict]),
		children
	});
}
//#endregion
//#region src/screens/ShopScreen.tsx
function ShopScreen(props) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopTranslationBridge, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopScreenContent, { ...props }) });
}
function ShopScreenContent({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
	const { config } = require_FluidProvider.useFluidContext();
	const { t } = useShopTranslation();
	const { data: store } = require_use_store.useStore();
	const { currentSlug, navigate } = require_AppNavigationContext.useAppNavigation();
	const countryCode = config.countryIso ?? "US";
	const subdomain = store?.subdomain;
	const productId = currentSlug.split("/")[1] ?? null;
	(0, react.useEffect)(() => {
		if (!countryCode) return;
		const sdk = () => window.FairShareSDK;
		let done = false;
		let inFlight = false;
		const tryUpdate = async () => {
			const fairShareSdk = sdk();
			if (done || inFlight || !fairShareSdk) return;
			inFlight = true;
			try {
				await fairShareSdk.updateLocaleSettings({ country: countryCode });
				done = true;
				clearInterval(id);
			} catch {} finally {
				inFlight = false;
			}
		};
		let attempts = 0;
		const id = setInterval(() => {
			if (attempts >= 50) {
				console.warn("[FairShare] updateLocaleSettings: gave up after 50 attempts — session never became ready", { country: countryCode });
				clearInterval(id);
				return;
			}
			attempts++;
			tryUpdate();
		}, 100);
		return () => {
			done = true;
			clearInterval(id);
		};
	}, [countryCode]);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
		!productId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbList, {
			className: "text-lg",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
				className: "font-semibold",
				children: t("breadcrumb")
			}) })
		}) }) }),
		/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderActions, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			className: "flex items-center gap-4",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CartButton, {})
		}) }),
		/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
			...divProps,
			className: divProps.className ?? "",
			children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopContainer, {
				cartScript: subdomain ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CartScript, {
					subdomain,
					bffMode: true,
					scriptSrc: {}.env.DEV ? String({}.env.VITE_FAIRSHARE_SDK_URL || "http://localhost:4444/index.js") : void 0,
					apiBaseUrl: {}.env.DEV ? String({}.env.VITE_FAIRSHARE_API_BASE_URL || "http://api.fluid.localhost:3000") : void 0,
					debug: {}.env.DEV
				}) : null,
				cartWidget: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CartWidget, {}),
				children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_PortalProductsApiProvider.PortalProductsApiProvider, { children: [productId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProductBreadcrumb, { productId }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShopApp, {
					companyLogoUrl: store?.logo_url ?? void 0,
					productId,
					onSelectProduct: (id) => navigate(`shop/${id}`),
					onBack: () => navigate("shop")
				})] })
			})
		})
	] });
}
const shopScreenPropertySchema = {
	widgetType: "ShopScreen",
	displayName: "Shop Screen",
	tabsConfig: [{
		id: "styling",
		label: "Styling"
	}],
	fields: []
};
/**
* Renders inside PortalProductsCoreProvider to set breadcrumbs with the
* product name: "Shop > {product name}". Overrides the parent's "Shop"
* breadcrumb once product data loads.
*/
function ProductBreadcrumb({ productId }) {
	const { navigate } = require_AppNavigationContext.useAppNavigation();
	const { t } = useShopTranslation();
	const { product } = require_PortalProductsApiProvider.usePortalProductDetail({ productId });
	const productName = product?.name ?? t("product_fallback_name");
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ScreenHeaderContext.ScreenHeaderBreadcrumbs, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Breadcrumb, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_src.BreadcrumbList, {
		className: "text-lg",
		children: [
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbLink, {
				onClick: () => navigate("shop"),
				className: "cursor-pointer font-semibold",
				children: t("breadcrumb")
			}) }),
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbSeparator, {}),
			/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbItem, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.BreadcrumbPage, {
				className: "font-semibold",
				children: productName
			}) })
		]
	}) }) });
}
//#endregion
Object.defineProperty(exports, "ShopScreen", {
	enumerable: true,
	get: function() {
		return ShopScreen;
	}
});
Object.defineProperty(exports, "shopScreenPropertySchema", {
	enumerable: true,
	get: function() {
		return shopScreenPropertySchema;
	}
});

//# sourceMappingURL=ShopScreen-BgiNBkIk.cjs.map