import { useClerkModalStateParams } from "./hooks/useClerkModalStateParams.js";
import { BlankCaptchaModal, CreateOrganizationModal, EnableOrganizationsPrompt, ImpersonationFab, KeylessPrompt, OrganizationProfileModal, SignInModal, SignUpModal, UserProfileModal, UserVerificationModal, WaitlistModal, preloadComponent } from "./lazyModules/components.js";
import { MountedCheckoutDrawer, MountedPlanDetailDrawer, MountedSubscriptionDetailDrawer } from "./lazyModules/drawers.js";
import { LazyComponentRenderer, LazyEnableOrganizationsPromptProvider, LazyImpersonationFabProvider, LazyModalRenderer, LazyOneTapRenderer, LazyProviders, OrganizationSwitcherPrefetch } from "./lazyModules/providers.js";
import { buildVirtualRouterUrl } from "./utils/buildVirtualRouterUrl.js";
import { disambiguateRedirectOptions } from "./utils/disambiguateRedirectOptions.js";
import { extractCssLayerNameFromAppearance } from "./utils/extractCssLayerNameFromAppearance.js";
import { warnAboutCustomizationWithoutPinning } from "./utils/warnAboutCustomizationWithoutPinning.js";
import { clerkUIErrorDOMElementNotFound } from "@clerk/shared/internal/clerk-js/errors";
import { createDeferredPromise } from "@clerk/shared/utils";
import React, { Suspense, useCallback, useRef, useSyncExternalStore } from "react";
import { jsx, jsxs } from "@emotion/react/jsx-runtime";

//#region src/Components.tsx
/**
* Avoid importing from `@clerk/shared/react` to prevent extra dependencies being added to the bundle.
*/
const useSafeLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
const ROOT_ELEMENT_ID = "clerk-components";
let portalCt = 0;
function assertDOMElement(element) {
	if (!element) clerkUIErrorDOMElementNotFound();
}
const mountComponentRenderer = (getClerk, getEnvironment, _options, moduleManager) => {
	const options = { ..._options };
	if (options.appearance) options.appearance = extractCssLayerNameFromAppearance(options.appearance);
	let clerkRoot = document.getElementById(ROOT_ELEMENT_ID);
	if (!clerkRoot) {
		clerkRoot = document.createElement("div");
		clerkRoot.setAttribute("id", "clerk-components");
		document.body.appendChild(clerkRoot);
	}
	let componentsControlsResolver;
	return { ensureMounted: (opts) => {
		const { preloadHint } = opts || {};
		if (preloadHint) preloadComponent(preloadHint).catch(() => {});
		if (!componentsControlsResolver) {
			const deferredPromise = createDeferredPromise();
			const mountTimeout = setTimeout(() => {
				console.error("[Clerk UI] Component renderer did not mount within 10s. Common causes: a failed chunk load, a dev-server misconfiguration (e.g. unresolved lazy-compilation proxy), or a ClerkProvider/mountX call before the page is hydrated. Check the Network tab for stalled or empty requests.");
			}, 1e4);
			componentsControlsResolver = import("./lazyModules/common.js").then(({ createRoot }) => {
				createRoot(clerkRoot).render(/* @__PURE__ */ jsx(Components, {
					getClerk,
					getEnvironment,
					options,
					onComponentsMounted: () => {
						clearTimeout(mountTimeout);
						if (getClerk().instanceType === "development") (typeof requestIdleCallback === "function" ? requestIdleCallback : (cb) => setTimeout(cb, 0))(() => warnAboutCustomizationWithoutPinning(options));
						deferredPromise.resolve();
					},
					moduleManager
				}));
				return deferredPromise.promise.then(() => componentsControls);
			}).catch((err) => {
				clearTimeout(mountTimeout);
				console.error("[Clerk UI] Failed to initialize component renderer:", err);
				throw err;
			});
		}
		return componentsControlsResolver.then((controls) => controls);
	} };
};
const componentsControls = {};
const componentNodes = Object.freeze({
	SignUp: "signUpModal",
	SignIn: "signInModal",
	UserProfile: "userProfileModal",
	OrganizationProfile: "organizationProfileModal",
	CreateOrganization: "createOrganizationModal",
	Waitlist: "waitlistModal"
});
const Components = (props) => {
	const [state, setState] = React.useState({
		appearance: props.options.appearance,
		options: props.options,
		googleOneTapModal: null,
		signInModal: null,
		signUpModal: null,
		userProfileModal: null,
		userVerificationModal: null,
		organizationProfileModal: null,
		createOrganizationModal: null,
		enableOrganizationsPromptModal: null,
		organizationSwitcherPrefetch: false,
		waitlistModal: null,
		blankCaptchaModal: null,
		checkoutDrawer: {
			open: false,
			props: null
		},
		planDetailsDrawer: {
			open: false,
			props: null
		},
		subscriptionDetailsDrawer: {
			open: false,
			props: null
		},
		impersonationFab: false
	});
	const { googleOneTapModal, signInModal, signUpModal, userProfileModal, userVerificationModal, organizationProfileModal, createOrganizationModal, waitlistModal, blankCaptchaModal, checkoutDrawer, planDetailsDrawer, subscriptionDetailsDrawer } = state;
	const clerk = props.getClerk();
	useSyncExternalStore(useCallback((callback) => clerk.addListener(callback, { skipInitialEmit: true }), [clerk]), useCallback(() => {
		return clerk.__internal_lastEmittedResources;
	}, [clerk]), useCallback(() => {
		return clerk.__internal_lastEmittedResources;
	}, [clerk]));
	const nodesRef = useRef(/* @__PURE__ */ new Map());
	const { urlStateParam, clearUrlStateParam, decodedRedirectParams } = useClerkModalStateParams();
	useSafeLayoutEffect(() => {
		if (decodedRedirectParams) setState((s) => ({
			...s,
			[componentNodes[decodedRedirectParams.componentName]]: true
		}));
		const triggerRender = () => {
			setState((s) => ({ ...s }));
		};
		componentsControls.mountComponent = (params) => {
			const { node, name, props: props$1, appearanceKey } = params;
			assertDOMElement(node);
			nodesRef.current.set(node, {
				key: `p${++portalCt}`,
				name,
				props: props$1,
				appearanceKey
			});
			triggerRender();
		};
		componentsControls.unmountComponent = (params) => {
			const { node } = params;
			nodesRef.current.delete(node);
			triggerRender();
		};
		componentsControls.updateProps = ({ node, props: props$1,...restProps }) => {
			if (node && props$1 && typeof props$1 === "object") {
				const nodeOptions = nodesRef.current.get(node);
				if (nodeOptions) {
					nodeOptions.props = { ...props$1 };
					triggerRender();
					return;
				}
			}
			setState((s) => ({
				...s,
				...restProps,
				options: {
					...s.options,
					...restProps.options
				}
			}));
		};
		componentsControls.closeModal = (name, options = {}) => {
			const { notify = true } = options;
			clearUrlStateParam();
			setState((s) => {
				function handleCloseModalForExperimentalUserVerification() {
					const modal = s[`${name}Modal`];
					if (modal && typeof modal === "object" && "afterVerificationCancelled" in modal && notify) modal.afterVerificationCancelled?.();
				}
				/**
				* We need this in order for `Clerk.__experimental_closeUserVerification()`
				* to properly trigger the previously defined `afterVerificationCancelled` callback
				*/
				handleCloseModalForExperimentalUserVerification();
				return {
					...s,
					[`${name}Modal`]: null
				};
			});
		};
		componentsControls.openModal = (name, props$1) => {
			if (name === "enableOrganizationsPrompt") {
				setState((prev) => {
					if (prev.enableOrganizationsPromptModal) return prev;
					return {
						...prev,
						[`${name}Modal`]: props$1
					};
				});
				return;
			}
			function handleCloseModalForExperimentalUserVerification() {
				if (!("afterVerificationCancelled" in props$1)) return;
				setState((s) => ({
					...s,
					[`${name}Modal`]: {
						...props$1,
						afterVerification() {
							props$1.afterVerification?.();
							componentsControls.closeModal(name, { notify: false });
						}
					}
				}));
			}
			if ("afterVerificationCancelled" in props$1) handleCloseModalForExperimentalUserVerification();
			else setState((s) => ({
				...s,
				[`${name}Modal`]: props$1
			}));
		};
		componentsControls.mountImpersonationFab = () => {
			setState((s) => ({
				...s,
				impersonationFab: true
			}));
		};
		componentsControls.openDrawer = (name, props$1) => {
			setState((s) => ({
				...s,
				[`${name}Drawer`]: {
					open: true,
					props: props$1
				}
			}));
		};
		componentsControls.closeDrawer = (name) => {
			setState((s) => {
				s[`${name}Drawer`]?.props?.onClose?.();
				return {
					...s,
					[`${name}Drawer`]: {
						...s[`${name}Drawer`],
						open: false
					}
				};
			});
		};
		componentsControls.prefetch = (component) => {
			setState((s) => ({
				...s,
				[`${component}Prefetch`]: true
			}));
		};
		props.onComponentsMounted();
	}, []);
	const mountedOneTapModal = /* @__PURE__ */ jsx(LazyOneTapRenderer, {
		componentProps: googleOneTapModal,
		globalAppearance: state.appearance,
		componentAppearance: googleOneTapModal?.appearance,
		startPath: buildVirtualRouterUrl({
			base: "/one-tap",
			path: ""
		})
	});
	const mountedSignInModal = /* @__PURE__ */ jsxs(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "signIn",
		componentAppearance: signInModal?.appearance,
		flowName: "signIn",
		onClose: () => componentsControls.closeModal("signIn"),
		onExternalNavigate: () => componentsControls.closeModal("signIn"),
		startPath: buildVirtualRouterUrl({
			base: "/sign-in",
			path: urlStateParam?.path
		}),
		getContainer: signInModal?.getContainer ?? (() => null),
		componentName: "SignInModal",
		children: [
			/* @__PURE__ */ jsx(SignInModal, { ...signInModal }),
			/* @__PURE__ */ jsx(SignUpModal, { ...disambiguateRedirectOptions(signInModal, "signin") }),
			/* @__PURE__ */ jsx(WaitlistModal, { ...waitlistModal })
		]
	});
	const mountedSignUpModal = /* @__PURE__ */ jsxs(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "signUp",
		componentAppearance: signUpModal?.appearance,
		flowName: "signUp",
		onClose: () => componentsControls.closeModal("signUp"),
		onExternalNavigate: () => componentsControls.closeModal("signUp"),
		startPath: buildVirtualRouterUrl({
			base: "/sign-up",
			path: urlStateParam?.path
		}),
		getContainer: signUpModal?.getContainer ?? (() => null),
		componentName: "SignUpModal",
		children: [
			/* @__PURE__ */ jsx(SignInModal, { ...disambiguateRedirectOptions(signUpModal, "signup") }),
			/* @__PURE__ */ jsx(SignUpModal, { ...signUpModal }),
			/* @__PURE__ */ jsx(WaitlistModal, { ...waitlistModal })
		]
	});
	const mountedUserProfileModal = /* @__PURE__ */ jsx(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "userProfile",
		componentAppearance: userProfileModal?.appearance,
		flowName: "userProfile",
		onClose: () => componentsControls.closeModal("userProfile"),
		onExternalNavigate: () => componentsControls.closeModal("userProfile"),
		startPath: buildVirtualRouterUrl({
			base: "/user",
			path: userProfileModal?.__experimental_startPath || urlStateParam?.path
		}),
		getContainer: userProfileModal?.getContainer ?? (() => null),
		componentName: "UserProfileModal",
		modalContainerSx: { alignItems: "center" },
		modalContentSx: (t) => ({
			height: `min(${t.sizes.$176}, calc(100% - ${t.sizes.$12}))`,
			margin: 0
		}),
		children: /* @__PURE__ */ jsx(UserProfileModal, { ...userProfileModal })
	});
	const mountedUserVerificationModal = /* @__PURE__ */ jsx(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "userVerification",
		componentAppearance: userVerificationModal?.appearance,
		flowName: "userVerification",
		onClose: () => componentsControls.closeModal("userVerification"),
		onExternalNavigate: () => componentsControls.closeModal("userVerification"),
		startPath: buildVirtualRouterUrl({
			base: "/user-verification",
			path: urlStateParam?.path
		}),
		getContainer: userVerificationModal?.getContainer ?? (() => null),
		componentName: "UserVerificationModal",
		modalContainerSx: { alignItems: "center" },
		children: /* @__PURE__ */ jsx(UserVerificationModal, { ...userVerificationModal })
	});
	const mountedOrganizationProfileModal = /* @__PURE__ */ jsx(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "organizationProfile",
		componentAppearance: organizationProfileModal?.appearance,
		flowName: "organizationProfile",
		onClose: () => componentsControls.closeModal("organizationProfile"),
		onExternalNavigate: () => componentsControls.closeModal("organizationProfile"),
		startPath: buildVirtualRouterUrl({
			base: "/organizationProfile",
			path: organizationProfileModal?.__experimental_startPath || urlStateParam?.path
		}),
		getContainer: organizationProfileModal?.getContainer ?? (() => null),
		componentName: "OrganizationProfileModal",
		modalContainerSx: { alignItems: "center" },
		modalContentSx: (t) => ({
			height: `min(${t.sizes.$176}, calc(100% - ${t.sizes.$12}))`,
			margin: 0
		}),
		children: /* @__PURE__ */ jsx(OrganizationProfileModal, { ...organizationProfileModal })
	});
	const mountedCreateOrganizationModal = /* @__PURE__ */ jsx(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "createOrganization",
		componentAppearance: createOrganizationModal?.appearance,
		flowName: "createOrganization",
		onClose: () => componentsControls.closeModal("createOrganization"),
		onExternalNavigate: () => componentsControls.closeModal("createOrganization"),
		startPath: buildVirtualRouterUrl({
			base: "/createOrganization",
			path: urlStateParam?.path
		}),
		getContainer: createOrganizationModal?.getContainer ?? (() => null),
		componentName: "CreateOrganizationModal",
		modalContainerSx: { alignItems: "center" },
		modalContentSx: (t) => ({
			height: `min(${t.sizes.$120}, calc(100% - ${t.sizes.$12}))`,
			margin: 0
		}),
		children: /* @__PURE__ */ jsx(CreateOrganizationModal, { ...createOrganizationModal })
	});
	const mountedWaitlistModal = /* @__PURE__ */ jsxs(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "waitlist",
		componentAppearance: waitlistModal?.appearance,
		flowName: "waitlist",
		onClose: () => componentsControls.closeModal("waitlist"),
		onExternalNavigate: () => componentsControls.closeModal("waitlist"),
		startPath: buildVirtualRouterUrl({
			base: "/waitlist",
			path: urlStateParam?.path
		}),
		getContainer: waitlistModal?.getContainer ?? (() => null),
		componentName: "WaitlistModal",
		children: [/* @__PURE__ */ jsx(WaitlistModal, { ...waitlistModal }), /* @__PURE__ */ jsx(SignInModal, { ...waitlistModal })]
	});
	const mountedBlankCaptchaModal = /* @__PURE__ */ jsx(LazyModalRenderer, {
		globalAppearance: state.appearance,
		appearanceKey: "blankCaptcha",
		componentAppearance: {},
		flowName: "blankCaptcha",
		onClose: () => componentsControls.closeModal("blankCaptcha"),
		startPath: buildVirtualRouterUrl({
			base: "/blank-captcha",
			path: urlStateParam?.path
		}),
		componentName: "BlankCaptchaModal",
		canCloseModal: false,
		modalId: "cl-modal-captcha-wrapper",
		modalStyle: {
			visibility: "hidden",
			pointerEvents: "none"
		},
		getContainer: () => null,
		children: /* @__PURE__ */ jsx(BlankCaptchaModal, {})
	});
	return /* @__PURE__ */ jsx(Suspense, {
		fallback: "",
		children: /* @__PURE__ */ jsxs(LazyProviders, {
			clerk: props.getClerk(),
			environment: props.getEnvironment(),
			options: state.options,
			moduleManager: props.moduleManager,
			children: [
				[...nodesRef.current].map(([node, component]) => {
					return /* @__PURE__ */ jsx(LazyComponentRenderer, {
						node,
						globalAppearance: state.appearance,
						appearanceKey: component.appearanceKey,
						componentAppearance: component.props?.appearance,
						componentName: component.name,
						componentProps: component.props
					}, component.key);
				}),
				googleOneTapModal && mountedOneTapModal,
				signInModal && mountedSignInModal,
				signUpModal && mountedSignUpModal,
				userProfileModal && mountedUserProfileModal,
				userVerificationModal && mountedUserVerificationModal,
				organizationProfileModal && mountedOrganizationProfileModal,
				createOrganizationModal && mountedCreateOrganizationModal,
				waitlistModal && mountedWaitlistModal,
				blankCaptchaModal && mountedBlankCaptchaModal,
				/* @__PURE__ */ jsx(MountedCheckoutDrawer, {
					appearance: state.appearance,
					checkoutDrawer,
					onOpenChange: () => componentsControls.closeDrawer("checkout")
				}),
				/* @__PURE__ */ jsx(MountedPlanDetailDrawer, {
					appearance: state.appearance,
					planDetailsDrawer,
					onOpenChange: () => componentsControls.closeDrawer("planDetails")
				}),
				/* @__PURE__ */ jsx(MountedSubscriptionDetailDrawer, {
					appearance: state.appearance,
					subscriptionDetailsDrawer,
					onOpenChange: () => componentsControls.closeDrawer("subscriptionDetails")
				}),
				state.impersonationFab && /* @__PURE__ */ jsx(LazyImpersonationFabProvider, {
					globalAppearance: state.appearance,
					children: /* @__PURE__ */ jsx(ImpersonationFab, {})
				}),
				state.enableOrganizationsPromptModal && /* @__PURE__ */ jsx(LazyEnableOrganizationsPromptProvider, {
					globalAppearance: state.appearance,
					children: /* @__PURE__ */ jsx(EnableOrganizationsPrompt, { ...state.enableOrganizationsPromptModal })
				}),
				state.options?.__internal_keyless_claimKeylessApplicationUrl && state.options?.__internal_keyless_copyInstanceKeysUrl && /* @__PURE__ */ jsx(LazyImpersonationFabProvider, {
					globalAppearance: state.appearance,
					children: /* @__PURE__ */ jsx(KeylessPrompt, {
						claimUrl: state.options.__internal_keyless_claimKeylessApplicationUrl,
						copyKeysUrl: state.options.__internal_keyless_copyInstanceKeysUrl,
						onDismiss: state.options.__internal_keyless_dismissPrompt
					})
				}),
				/* @__PURE__ */ jsx(Suspense, { children: state.organizationSwitcherPrefetch && /* @__PURE__ */ jsx(OrganizationSwitcherPrefetch, {}) })
			]
		})
	});
};

//#endregion
export { mountComponentRenderer };
//# sourceMappingURL=Components.js.map