import "../translation-adapter-B-Vhfzbz.mjs";
import { t as FluidProvider } from "../FluidProvider-w-PbxHiZ.mjs";
import "../FluidThemeProvider-D_O4NV2b.mjs";
import "../ScreenRenderer-CBL1EEk8.mjs";
import "../use-account-CVCEuI6e.mjs";
import "../use-optional-store-DzThbXJh.mjs";
import "../mysite-api-context-BbxSfNft.mjs";
import "../ContactsTranslationBridge-Chex2IH_.mjs";
import "../hook-types-JekiyYyT.mjs";
import "../registry-context-Rn7c5X_k.mjs";
import "../WidgetInteractionContext-I716c8kj.mjs";
import "../RepUserContext-BTjMBEMg.mjs";
import "../QuickLinksWidget-BwSS-lXm.mjs";
import "../WidgetRenderStateContext-BpOkrVq-.mjs";
import "../static-dict-adapter-CMDcV28R.mjs";
import "../SearchSort-D_Niw4PM.mjs";
import "../use-share-link-CHk1_iNy.mjs";
import "../translation-api-context-factory-dNziJNS1.mjs";
import "../shell-translation-api-context-CwhOPjtM.mjs";
import "../error-state-CmesiiXJ.mjs";
import "../PointsWidget-Bvnj_7Ck.mjs";
import "../task-composer-form-DOoKMb9i.mjs";
import "../LayoutWidget-B6mLhd_v.mjs";
import "../registries-BZVov8GL.mjs";
import "../fields-Cq0nAluM.mjs";
import "../TextWidget-DROB24UD.mjs";
import "../AlertWidget-B7u_5CY8.mjs";
import "../BulletListWidget-D-Mt-4Kd.mjs";
import "../preview-context-BeRbfntP.mjs";
import "../CalendarWidget-_BiC1qFm.mjs";
import "../CardWidget-BBBAgnsg.mjs";
import "../purify.es-DI2Tffdk.mjs";
import "../MediaRenderer-BydUiy9x.mjs";
import "../CarouselWidget-BUQ1Ri8G.mjs";
import "../CatchUpWidget-SznFLD53.mjs";
import "../src-CAi8-qUm.mjs";
import "../ChartWidget-Cm-KPwRD.mjs";
import "../ContainerWidget-CC1zIMoX.mjs";
import "../EmbedWidget-BHidJxpW.mjs";
import "../ImageWidget-BwddirgT.mjs";
import "../LinkWidget-H88QpMf2.mjs";
import "../ListWidget-QgFIR9fE.mjs";
import "../MySiteWidget-6pZKJoDm.mjs";
import "../NestedWidget-csYmc52Y.mjs";
import "../QuickShareWidget-D2GA8R0C.mjs";
import "../RecentActivityWidget-W5VOvYig.mjs";
import "../SeparatorWidget-hqgYg78v.mjs";
import "../SpacerWidget-CXiamp_6.mjs";
import "../TableWidget-CPLF9ZNp.mjs";
import "../ToDoWidget-uRlqcJXM.mjs";
import "../VideoWidget-Dubqz6B9.mjs";
import "../ShopWidget-4V7UZLjB.mjs";
import "../translation-adapter-CxA_PHry.mjs";
import "../translation-adapter-AUVlDFgQ.mjs";
import { a as loadWidgetPackages, f as buildWidgetRegistry, i as installAndReadFluidWidgetsRegistry, m as createDefaultFluidConfig, p as mergeRegisteredWidgetsIntoRegistry, t as dedupeWidgetPackagesByPackageIdAndVersion } from "../widget-package-utils-3cs8viyn.mjs";
import { n as isPreviewCommand, t as isAllowedOrigin } from "../protocol-g9Z0NTk-.mjs";
import { Component, StrictMode, useCallback, useEffect, useRef, useState } from "react";
import { jsx } from "react/jsx-runtime";
import { createRoot } from "react-dom/client";
//#region src/preview/PreviewRenderer.tsx
/**
* Renders a single widget inside the preview iframe, driven by
* postMessage commands from the builder.
*
* Lifecycle:
*   1. Sends `ready` event on mount
*   2. Waits for `auth` command → calls onAuth()
*   3. Waits for `render-widget` command → renders the widget
*   4. Reports dimensions via ResizeObserver
*/
function PreviewRenderer({ widgetRegistry, onAuth, builderOrigin, skipReady = false }) {
	const [widget, setWidget] = useState(null);
	const [error, setError] = useState(null);
	const containerRef = useRef(null);
	const sentReady = useRef(false);
	const sendToBuilder = useCallback((event) => {
		if (!builderOrigin) return;
		window.parent.postMessage(event, builderOrigin);
	}, [builderOrigin]);
	useEffect(() => {
		if (skipReady) return;
		if (sentReady.current) return;
		sentReady.current = true;
		sendToBuilder({ type: "ready" });
	}, [sendToBuilder, skipReady]);
	const sentAuthReady = useRef(false);
	useEffect(() => {
		if (!skipReady) return;
		if (sentAuthReady.current) return;
		sentAuthReady.current = true;
		sendToBuilder({ type: "auth-ready" });
	}, [sendToBuilder, skipReady]);
	useEffect(() => {
		if (!builderOrigin) return;
		function handleMessage(event) {
			if (event.origin !== builderOrigin) return;
			if (!isPreviewCommand(event.data)) return;
			const command = event.data;
			switch (command.type) {
				case "auth":
					onAuth(command.token);
					if (!sentAuthReady.current) {
						sentAuthReady.current = true;
						sendToBuilder({ type: "auth-ready" });
					}
					break;
				case "render-widget":
					setError(null);
					setWidget({
						widgetType: command.widgetType,
						props: command.props
					});
					break;
				case "select-widget": break;
				case "unmount-widget":
					setWidget(null);
					setError(null);
					break;
				default:
			}
		}
		window.addEventListener("message", handleMessage);
		return () => window.removeEventListener("message", handleMessage);
	}, [
		builderOrigin,
		onAuth,
		sendToBuilder
	]);
	useEffect(() => {
		const container = containerRef.current;
		if (!container || !widget) return;
		const observer = new ResizeObserver((entries) => {
			const entry = entries[0];
			if (!entry) return;
			const { width, height } = entry.contentRect;
			sendToBuilder({
				type: "widget-rendered",
				widgetType: widget.widgetType,
				dimensions: {
					width: Math.ceil(width),
					height: Math.ceil(height)
				}
			});
		});
		observer.observe(container);
		return () => observer.disconnect();
	}, [widget, sendToBuilder]);
	useEffect(() => {
		const hot = import.meta.hot;
		if (hot) {
			const handler = () => sendToBuilder({ type: "widget-hmr" });
			hot.on("vite:afterUpdate", handler);
			return () => hot.off("vite:afterUpdate", handler);
		}
	}, [sendToBuilder]);
	const WidgetComponent = widget ? widgetRegistry[widget.widgetType] : void 0;
	useEffect(() => {
		if (!widget) return;
		if (!widgetRegistry[widget.widgetType]) sendToBuilder({
			type: "widget-error",
			widgetType: widget.widgetType,
			error: `Unknown widget type: ${widget.widgetType}`
		});
	}, [
		widget,
		widgetRegistry,
		sendToBuilder
	]);
	if (!widget) return null;
	if (!WidgetComponent) return null;
	if (error) return null;
	return /* @__PURE__ */ jsx("div", {
		ref: containerRef,
		onClick: () => sendToBuilder({
			type: "widget-clicked",
			widgetType: widget.widgetType
		}),
		children: /* @__PURE__ */ jsx(ErrorBoundary, {
			widgetType: widget.widgetType,
			onError: (err) => {
				setError(err);
				sendToBuilder({
					type: "widget-error",
					widgetType: widget.widgetType,
					error: err
				});
			},
			children: /* @__PURE__ */ jsx(WidgetComponent, { ...widget.props })
		}, widget.widgetType)
	});
}
var ErrorBoundary = class extends Component {
	constructor(props) {
		super(props);
		this.state = { hasError: false };
	}
	static getDerivedStateFromError() {
		return { hasError: true };
	}
	componentDidCatch(error) {
		this.props.onError(error.message);
	}
	render() {
		if (this.state.hasError) return null;
		return this.props.children;
	}
};
//#endregion
//#region src/preview/preview-entry.tsx
/**
* Preview iframe bootstrap function.
*
* Called from the portal project's src/preview-entry.tsx with the
* customWidgets array from portal.config.ts. Mirrors the createPortal()
* pattern — SDK handles the wiring, user project provides the widgets.
*
* Two-phase auth handshake:
*   Phase 1: Send `ready`, wait for `auth` command, store token
*   Phase 2: Mount provider stack + PreviewRenderer, send `auth-ready`
*/
function createPreview(options = {}) {
	const { customWidgets = [], widgetPackages = [], rootId = "preview-root" } = options;
	const dedupedWidgetPackages = dedupeWidgetPackagesByPackageIdAndVersion(widgetPackages);
	const initialWidgetRegistry = mergeRegisteredWidgetsIntoRegistry(buildWidgetRegistry(customWidgets), installAndReadFluidWidgetsRegistry());
	const rawBuilderOrigin = new URLSearchParams(window.location.search).get("builderOrigin");
	const builderOrigin = rawBuilderOrigin && isAllowedOrigin(rawBuilderOrigin) ? rawBuilderOrigin : null;
	if (builderOrigin) window.parent.postMessage({ type: "ready" }, builderOrigin);
	function handleAuthMessage(event) {
		if (event.origin !== builderOrigin) return;
		if (typeof event.data !== "object" || event.data === null || event.data.type !== "auth") return;
		window.removeEventListener("message", handleAuthMessage);
		const command = event.data;
		mountApp({
			initialWidgetRegistry,
			widgetPackages: dedupedWidgetPackages,
			builderOrigin,
			rootId,
			authToken: command.token
		});
	}
	if (builderOrigin) window.addEventListener("message", handleAuthMessage);
	else {
		const rootElement = document.getElementById(rootId);
		if (rootElement) {
			rootElement.style.cssText = "display:flex;align-items:center;justify-content:center;height:100vh;font-family:system-ui;color:#888;font-size:14px";
			rootElement.textContent = rawBuilderOrigin ? `Preview unavailable — origin "${rawBuilderOrigin}" is not allowed` : "Preview unavailable — missing builderOrigin parameter";
		}
	}
}
function mountApp({ initialWidgetRegistry, widgetPackages, builderOrigin, rootId, authToken }) {
	const rootElement = document.getElementById(rootId);
	if (!rootElement) return;
	const iframeOrigin = window.location.origin;
	const tree = /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(PreviewRuntimeWidgetBootstrap, {
		fluidConfig: createDefaultFluidConfig({
			baseUrl: iframeOrigin,
			getAuthToken: () => authToken
		}),
		initialWidgetRegistry,
		widgetPackageLoadPromise: builderOrigin && widgetPackages.length ? loadWidgetPackages(widgetPackages) : void 0,
		builderOrigin
	}) });
	createRoot(rootElement).render(tree);
}
function PreviewRuntimeWidgetBootstrap({ fluidConfig, initialWidgetRegistry, widgetPackageLoadPromise, builderOrigin }) {
	const [runtimeWidgetState, setRuntimeWidgetState] = useState(() => ({
		widgetRegistry: initialWidgetRegistry,
		packageLoadSettled: !widgetPackageLoadPromise
	}));
	useEffect(() => {
		if (!widgetPackageLoadPromise) {
			setRuntimeWidgetState({
				widgetRegistry: initialWidgetRegistry,
				packageLoadSettled: true
			});
			return;
		}
		let cancelled = false;
		setRuntimeWidgetState({
			widgetRegistry: initialWidgetRegistry,
			packageLoadSettled: false
		});
		widgetPackageLoadPromise.then((summary) => {
			if (cancelled) return;
			setRuntimeWidgetState({
				widgetRegistry: mergeRegisteredWidgetsIntoRegistry(initialWidgetRegistry, summary.registeredWidgets),
				packageLoadSettled: true
			});
		}).catch((error) => {
			if (cancelled) return;
			console.error("[portal] Failed to load preview widget packages:", error);
			setRuntimeWidgetState({
				widgetRegistry: initialWidgetRegistry,
				packageLoadSettled: true
			});
		});
		return () => {
			cancelled = true;
		};
	}, [initialWidgetRegistry, widgetPackageLoadPromise]);
	return /* @__PURE__ */ jsx(FluidProvider, {
		config: fluidConfig,
		widgetRegistry: runtimeWidgetState.widgetRegistry,
		children: runtimeWidgetState.packageLoadSettled ? /* @__PURE__ */ jsx(PreviewRenderer, {
			widgetRegistry: runtimeWidgetState.widgetRegistry,
			onAuth: () => {},
			builderOrigin,
			skipReady: true
		}) : null
	});
}
//#endregion
export { createPreview };

//# sourceMappingURL=preview-entry.mjs.map