const require_chunk = require("./chunk-9hOWP6kD.cjs");
const require_registries = require("./registries-CpUM406S.cjs");
let react = require("react");
react = require_chunk.__toESM(react);
let react_jsx_runtime = require("react/jsx-runtime");
let lucide_react = require("lucide-react");
let react_dom = require("react-dom");
//#region ../widgets/src/contexts/RepUserContext.tsx
const RepUserContext = (0, react.createContext)(null);
function RepUserProvider({ user, children }) {
	const value = (0, react.useMemo)(() => user, [user]);
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RepUserContext.Provider, {
		value,
		children
	});
}
function useRepUser() {
	return (0, react.useContext)(RepUserContext);
}
//#endregion
//#region ../widgets/src/widgets/EmbedWidget.tsx
var EmbedWidget_exports = /* @__PURE__ */ require_chunk.__exportAll({
	EmbedWidget: () => EmbedWidget,
	embedWidgetPropertySchema: () => embedWidgetPropertySchema
});
function isValidHttpUrl(urlString) {
	try {
		const parsed = new URL(urlString);
		return parsed.protocol === "https:" || parsed.protocol === "http:";
	} catch {
		return false;
	}
}
function useEmbedUrl(url, publicId) {
	return (0, react.useMemo)(() => {
		const normalizedUrl = url && (url.startsWith("http://") || url.startsWith("https://")) ? url : url ? `https://${url}` : "";
		let isValidUrl = false;
		if (normalizedUrl) try {
			const parsed = new URL(normalizedUrl);
			isValidUrl = (parsed.protocol === "http:" || parsed.protocol === "https:") && (parsed.hostname.includes(".") || parsed.hostname === "localhost");
		} catch {}
		if (!isValidUrl || !publicId) return {
			normalizedUrl,
			isValidUrl,
			iframeSrc: normalizedUrl
		};
		const urlObj = new URL(normalizedUrl);
		urlObj.searchParams.set("public_id", publicId);
		return {
			normalizedUrl,
			isValidUrl,
			iframeSrc: urlObj.toString()
		};
	}, [url, publicId]);
}
function useEmbedPostMessageBridge({ iframeRef, normalizedUrl, isValidUrl, editMode }) {
	(0, react.useEffect)(() => {
		if (!isValidUrl || editMode) return;
		const expectedOrigin = new URL(normalizedUrl).origin;
		function handleMessage(event) {
			if (event.origin !== expectedOrigin) return;
			if (event.source !== iframeRef.current?.contentWindow) return;
			let data;
			if (typeof event.data === "string") try {
				data = JSON.parse(event.data);
			} catch {
				return;
			}
			else data = event.data;
			if (typeof data === "object" && data !== null && "type" in data && data.type === "OPEN_FULL_SCREEN_WEBVIEW") {
				const messageUrl = data.url;
				if (messageUrl && isValidHttpUrl(messageUrl)) window.open(messageUrl, "_blank", "noopener,noreferrer");
			}
		}
		window.addEventListener("message", handleMessage);
		return () => window.removeEventListener("message", handleMessage);
	}, [
		iframeRef,
		normalizedUrl,
		isValidUrl,
		editMode
	]);
}
function useModalBodyScrollLock(isOpen) {
	(0, react.useEffect)(() => {
		if (!isOpen) return;
		const previousOverflow = document.body.style.overflow;
		document.body.style.overflow = "hidden";
		return () => {
			document.body.style.overflow = previousOverflow;
		};
	}, [isOpen]);
}
function useModalEscapeClose(isOpen, onClose) {
	(0, react.useEffect)(() => {
		if (!isOpen) return;
		const handleKeyDown = (event) => {
			if (event.key === "Escape") onClose();
		};
		window.addEventListener("keydown", handleKeyDown);
		return () => window.removeEventListener("keydown", handleKeyDown);
	}, [isOpen, onClose]);
}
function useDialogFocusRestore(dialogRef) {
	(0, react.useEffect)(() => {
		const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
		dialogRef.current?.focus();
		return () => {
			previouslyFocused?.focus();
		};
	}, [dialogRef]);
}
const HEADER_ICON_MAP = {
	GraduationCap: lucide_react.GraduationCap,
	Video: lucide_react.Video,
	BookOpen: lucide_react.BookOpen,
	Globe: lucide_react.Globe,
	User: lucide_react.User,
	Star: lucide_react.Star,
	Heart: lucide_react.Heart,
	Trophy: lucide_react.Trophy,
	Sparkles: lucide_react.Sparkles,
	Zap: lucide_react.Zap,
	Gift: lucide_react.Gift,
	ShoppingBag: lucide_react.ShoppingBag,
	Bell: lucide_react.Bell,
	Calendar: lucide_react.Calendar,
	Bookmark: lucide_react.BookmarkIcon
};
const HEADER_ICON_OPTIONS = [
	{
		label: "Graduation Cap",
		value: "GraduationCap"
	},
	{
		label: "Video",
		value: "Video"
	},
	{
		label: "Book",
		value: "BookOpen"
	},
	{
		label: "Globe",
		value: "Globe"
	},
	{
		label: "User",
		value: "User"
	},
	{
		label: "Star",
		value: "Star"
	},
	{
		label: "Heart",
		value: "Heart"
	},
	{
		label: "Trophy",
		value: "Trophy"
	},
	{
		label: "Sparkles",
		value: "Sparkles"
	},
	{
		label: "Zap / Lightning",
		value: "Zap"
	},
	{
		label: "Gift",
		value: "Gift"
	},
	{
		label: "Shopping Bag",
		value: "ShoppingBag"
	},
	{
		label: "Bell",
		value: "Bell"
	},
	{
		label: "Calendar",
		value: "Calendar"
	},
	{
		label: "Bookmark",
		value: "Bookmark"
	}
];
const getHeaderIcon = (name) => {
	if (!name) return lucide_react.GraduationCap;
	return HEADER_ICON_MAP[name] ?? lucide_react.GraduationCap;
};
function EmbedWidget({ url = "", title = "Embedded Content", height = "400px", fullScreen = false, allowFullscreen = true, loading = "lazy", borderRadius = "md", borderWidth = "none", borderColor = "muted", editMode = false, isSelected = false, displayMode = "inline", coverResource, coverUseCustomUrl = false, coverImageUrl = "", coverTitle = "", coverMeta = "", coverShowHeader = true, coverHeaderIcon = "GraduationCap", coverHeaderIconColor = "primary", coverHeight = "320px", className, ...props }) {
	const isFullScreen = fullScreen;
	const iframeRef = (0, react.useRef)(null);
	const publicId = useRepUser()?.publicId;
	const [modalOpen, setModalOpen] = (0, react.useState)(false);
	const [coverReloadKey, setCoverReloadKey] = (0, react.useState)(0);
	const [iframeReloadKey, setIframeReloadKey] = (0, react.useState)(0);
	const closeModal = (0, react.useCallback)(() => setModalOpen(false), []);
	const { normalizedUrl, isValidUrl, iframeSrc } = useEmbedUrl(url, publicId);
	useEmbedPostMessageBridge({
		iframeRef,
		normalizedUrl,
		isValidUrl,
		editMode
	});
	useModalBodyScrollLock(modalOpen);
	useModalEscapeClose(modalOpen, closeModal);
	if (!url || !isValidUrl) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		className: `flex items-center justify-center rounded-${borderRadius} border-border bg-muted text-muted-foreground border-2 border-dashed ${className ?? ""}`,
		...props,
		style: isFullScreen ? { height: "var(--portal-fullscreen-embed-height, calc(100dvh - 4rem))" } : { height: displayMode === "cover" ? coverHeight : height },
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "flex flex-col items-center gap-2 p-6 text-center",
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "size-12 opacity-50" }),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
					className: "text-sm font-medium",
					children: "Enter a URL to embed external content"
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
					className: "text-xs opacity-75",
					children: "Configure the URL in the properties panel"
				})
			]
		})
	});
	if (displayMode === "cover") {
		const resolvedCoverImage = coverUseCustomUrl ? coverImageUrl : coverResource?.imageUrl || coverResource?.image_url || coverImageUrl;
		const effectiveTitle = coverTitle || title;
		const HeaderIcon = getHeaderIcon(coverHeaderIcon);
		const handleOpenModal = () => {
			if (editMode) return;
			setModalOpen(true);
		};
		const handleReload = () => {
			if (editMode) return;
			setCoverReloadKey((key) => key + 1);
		};
		const handleOpenNewTab = (e) => {
			e.stopPropagation();
			if (editMode) return;
			window.open(iframeSrc, "_blank", "noopener,noreferrer");
		};
		return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: `relative w-full overflow-hidden rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""} bg-background ${className ?? ""}`,
			style: { boxShadow: "0 1px 2px color-mix(in oklch, var(--color-foreground) 5%, transparent), 0 12px 32px -16px color-mix(in oklch, var(--color-foreground) 10%, transparent)" },
			...props,
			children: [
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
					"aria-hidden": "true",
					className: `pointer-events-none absolute inset-0 z-[1] rounded-${borderRadius}`,
					style: { boxShadow: "inset 0 0 0 1px color-mix(in oklch, var(--color-foreground) 8%, transparent)" }
				}),
				coverShowHeader && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "relative z-[2] flex items-center gap-3 px-5 py-3",
					children: [
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
							"aria-hidden": "true",
							className: `text-${coverHeaderIconColor}-foreground flex size-7 shrink-0 items-center justify-center rounded-${borderRadius}`,
							style: {
								background: `linear-gradient(135deg, color-mix(in oklch, var(--color-${coverHeaderIconColor}) 75%, white 25%) 0%, var(--color-${coverHeaderIconColor}) 100%)`,
								boxShadow: `
                    inset 0 1px 0 rgba(255,255,255,0.25),
                    inset 0 -1px 0 rgba(0,0,0,0.08),
                    0 1px 2px color-mix(in oklch, var(--color-${coverHeaderIconColor}) 25%, transparent)
                  `
							},
							children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIcon, {
								className: "size-3.5",
								strokeWidth: 2.25
							})
						}),
						/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "min-w-0 flex-1",
							children: [effectiveTitle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
								className: "text-foreground truncate text-[15px] leading-tight font-semibold tracking-tight",
								children: effectiveTitle
							}), coverMeta && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
								className: "text-foreground/40 mt-0.5 truncate text-[11px] font-medium tracking-[0.08em] uppercase",
								children: coverMeta
							})]
						}),
						/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
							className: "bg-foreground/5 flex shrink-0 items-center rounded-lg p-0.5",
							children: [
								/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
									Icon: lucide_react.RotateCw,
									label: "Reload",
									onClick: (e) => {
										e.stopPropagation();
										handleReload();
									}
								}),
								/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
									Icon: lucide_react.Maximize2,
									label: "Open",
									onClick: (e) => {
										e.stopPropagation();
										handleOpenModal();
									}
								}),
								/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
									Icon: lucide_react.ExternalLink,
									label: "Open in new tab",
									onClick: handleOpenNewTab
								})
							]
						})
					]
				}),
				/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
					type: "button",
					onClick: handleOpenModal,
					disabled: editMode,
					className: `relative block w-full overflow-hidden ${editMode ? "cursor-default" : "cursor-pointer"}`,
					style: { height: coverHeight },
					"aria-label": `Open ${effectiveTitle || title}`,
					children: resolvedCoverImage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
						src: resolvedCoverImage,
						alt: effectiveTitle || title,
						className: "h-full w-full object-cover"
					}, `cover-${coverReloadKey}`) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
						className: "bg-muted flex h-full w-full items-center justify-center",
						children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "text-muted-foreground/40 size-16" })
					})
				}),
				editMode && !isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "absolute inset-0 z-10" })
			]
		}), modalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EmbedModal, {
			src: iframeSrc,
			title: effectiveTitle || title,
			allowFullscreen,
			iframeRef,
			onClose: closeModal,
			onReload: () => setIframeReloadKey((key) => key + 1)
		}, `modal-${iframeReloadKey}`)] });
	}
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		className: `relative w-full rounded-${borderRadius} ${require_registries.borderWidthClasses[borderWidth]} ${borderWidth !== "none" ? require_registries.borderColorClasses[borderColor] : ""} ${className ?? ""}`,
		...props,
		style: isFullScreen ? { height: "var(--portal-fullscreen-embed-height, calc(100dvh - 4rem))" } : void 0,
		children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
			ref: iframeRef,
			src: iframeSrc,
			title,
			width: "100%",
			style: isFullScreen ? { height: "100%" } : { height },
			loading,
			allowFullScreen: allowFullscreen,
			className: `rounded-${borderRadius} border-border border`,
			sandbox: "allow-scripts allow-popups"
		}), editMode && !isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "absolute inset-0 z-10" })]
	});
}
function HeaderIconButton({ Icon, label, onClick }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
		type: "button",
		onClick,
		"aria-label": label,
		className: "text-foreground/45 hover:text-foreground hover:bg-background flex size-7 items-center justify-center rounded-md transition-colors",
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
			className: "size-3.5",
			strokeWidth: 2.25
		})
	});
}
function EmbedModal({ src, title, allowFullscreen, iframeRef, onClose, onReload }) {
	const dialogRef = (0, react.useRef)(null);
	useDialogFocusRestore(dialogRef);
	return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
		ref: dialogRef,
		tabIndex: -1,
		className: "fixed inset-0 z-[100] flex items-center justify-center p-4 focus:outline-none sm:p-8",
		style: { background: "color-mix(in oklch, var(--color-foreground) 80%, black)" },
		onClick: onClose,
		role: "dialog",
		"aria-modal": "true",
		"aria-label": title,
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
			className: "bg-background relative flex h-full max-h-[95vh] w-full max-w-[1400px] flex-col overflow-hidden rounded-2xl shadow-2xl",
			onClick: (e) => e.stopPropagation(),
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
				className: "flex items-center justify-between gap-4 px-5 py-3",
				style: { borderBottom: "1px solid color-mix(in oklch, var(--color-foreground) 8%, transparent)" },
				children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
					className: "text-foreground truncate text-sm font-semibold tracking-tight",
					children: title
				}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
					className: "flex shrink-0 items-center gap-1",
					children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderIconButton, {
						Icon: lucide_react.RotateCw,
						label: "Reload",
						onClick: (e) => {
							e.stopPropagation();
							onReload();
						}
					}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
						type: "button",
						onClick: onClose,
						"aria-label": "Close",
						className: "text-foreground/60 hover:text-foreground hover:bg-foreground/5 flex size-9 shrink-0 items-center justify-center rounded-full transition-colors",
						children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "size-5" })
					})]
				})]
			}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
				ref: iframeRef,
				src,
				title,
				className: "flex-1 border-0",
				allowFullScreen: allowFullscreen,
				sandbox: "allow-scripts allow-popups"
			})]
		})
	}), document.body);
}
const embedWidgetPropertySchema = {
	widgetType: "EmbedWidget",
	displayName: "Embed",
	fields: [
		{
			key: "url",
			label: "URL",
			type: "text",
			description: "The URL of the external site to embed",
			placeholder: "https://example.com",
			defaultValue: "",
			group: "Content"
		},
		{
			key: "title",
			label: "Title",
			type: "text",
			description: "Accessibility title for the embedded content",
			defaultValue: "Embedded Content",
			group: "Content"
		},
		{
			key: "displayMode",
			label: "Display Mode",
			type: "buttonGroup",
			description: "Inline: iframe renders directly. Cover: shows a card that opens the embed in a full-screen modal.",
			defaultValue: "inline",
			options: [{
				label: "Inline",
				value: "inline"
			}, {
				label: "Cover + Modal",
				value: "cover"
			}],
			group: "Display Mode"
		},
		{
			key: "coverResource",
			label: "Cover Image",
			type: "resource",
			description: "Select the image shown before the embed opens",
			allowedTypes: ["Medium"],
			group: "Cover",
			requiresKeyValue: {
				key: "displayMode",
				value: "cover"
			}
		},
		{
			key: "coverUseCustomUrl",
			label: "Use Custom URL",
			type: "boolean",
			description: "Enter a custom image URL instead of selecting media",
			defaultValue: false,
			group: "Cover",
			requiresKeyValue: {
				key: "displayMode",
				value: "cover"
			}
		},
		{
			key: "coverImageUrl",
			label: "Cover Image URL",
			type: "text",
			description: "Direct URL to the cover image",
			placeholder: "https://example.com/cover.jpg",
			defaultValue: "",
			group: "Cover",
			requiresKeyValue: [{
				key: "displayMode",
				value: "cover"
			}, {
				key: "coverUseCustomUrl",
				value: true
			}]
		},
		require_registries.getHeightField({
			key: "coverHeight",
			label: "Cover Height",
			description: "Height of the cover image area",
			defaultValue: "320px",
			group: "Cover",
			requiresKeyValue: {
				key: "displayMode",
				value: "cover"
			}
		}),
		{
			key: "coverShowHeader",
			label: "Show Card Header",
			type: "boolean",
			description: "Show the header with icon, title, and action buttons",
			defaultValue: true,
			group: "Cover Header",
			requiresKeyValue: {
				key: "displayMode",
				value: "cover"
			}
		},
		{
			key: "coverHeaderIcon",
			label: "Header Icon",
			type: "select",
			description: "Icon displayed in the colored badge on the left",
			options: HEADER_ICON_OPTIONS,
			defaultValue: "GraduationCap",
			group: "Cover Header",
			requiresKeyValue: [{
				key: "displayMode",
				value: "cover"
			}, {
				key: "coverShowHeader",
				value: true
			}]
		},
		require_registries.getColorField({
			key: "coverHeaderIconColor",
			label: "Icon Badge Color",
			description: "Background color of the icon badge",
			defaultValue: "primary",
			group: "Cover Header",
			requiresKeyValue: [{
				key: "displayMode",
				value: "cover"
			}, {
				key: "coverShowHeader",
				value: true
			}]
		}),
		{
			key: "coverTitle",
			label: "Header Title",
			type: "text",
			description: "Title shown in the card header and modal (falls back to the widget Title if empty). Available even when the card header is hidden so the modal still has a meaningful title.",
			defaultValue: "",
			group: "Cover Header",
			requiresKeyValue: {
				key: "displayMode",
				value: "cover"
			}
		},
		{
			key: "coverMeta",
			label: "Meta Text",
			type: "text",
			description: "Small uppercase meta line below the title (e.g. 'APR 16 · COACHING THE HOSTESS')",
			defaultValue: "",
			group: "Cover Header",
			requiresKeyValue: [{
				key: "displayMode",
				value: "cover"
			}, {
				key: "coverShowHeader",
				value: true
			}]
		},
		require_registries.getBorderRadiusField({
			key: "borderRadius",
			label: "Border Radius",
			description: "Border radius for the embed container",
			defaultValue: "md",
			group: "Design"
		}),
		require_registries.getBorderWidthField({
			key: "borderWidth",
			label: "Border Width",
			description: "Border width for the widget",
			defaultValue: "none",
			group: "Design"
		}),
		require_registries.getBorderColorField({
			key: "borderColor",
			label: "Border Color",
			description: "Border color for the widget",
			defaultValue: "muted",
			group: "Design"
		}),
		{
			key: "fullScreen",
			label: "Full Screen",
			type: "boolean",
			description: "Inline mode: fill the available space instead of a fixed height",
			defaultValue: false,
			group: "Design",
			requiresKeyValue: {
				key: "displayMode",
				value: "inline"
			}
		},
		require_registries.getHeightField({
			key: "height",
			label: "Height",
			description: "Height of the inline embed iframe",
			defaultValue: "400px",
			group: "Design",
			requiresKeyValue: [{
				key: "displayMode",
				value: "inline"
			}, {
				key: "fullScreen",
				value: false
			}]
		}),
		{
			key: "allowFullscreen",
			label: "Allow Fullscreen",
			type: "boolean",
			description: "Allow the embedded content to use fullscreen mode",
			defaultValue: true,
			group: "Settings"
		},
		{
			key: "loading",
			label: "Loading",
			type: "select",
			description: "When to load the embedded content (inline mode only)",
			options: [{
				label: "Lazy (on scroll)",
				value: "lazy"
			}, {
				label: "Eager (immediately)",
				value: "eager"
			}],
			defaultValue: "lazy",
			group: "Settings",
			requiresKeyValue: {
				key: "displayMode",
				value: "inline"
			}
		}
	]
};
//#endregion
Object.defineProperty(exports, "EmbedWidget", {
	enumerable: true,
	get: function() {
		return EmbedWidget;
	}
});
Object.defineProperty(exports, "EmbedWidget_exports", {
	enumerable: true,
	get: function() {
		return EmbedWidget_exports;
	}
});
Object.defineProperty(exports, "RepUserProvider", {
	enumerable: true,
	get: function() {
		return RepUserProvider;
	}
});
Object.defineProperty(exports, "embedWidgetPropertySchema", {
	enumerable: true,
	get: function() {
		return embedWidgetPropertySchema;
	}
});
Object.defineProperty(exports, "useRepUser", {
	enumerable: true,
	get: function() {
		return useRepUser;
	}
});

//# sourceMappingURL=EmbedWidget-B1gWxgsn.cjs.map