import { useRouter } from "../../router/RouteContext.js";
import { useEnvironment } from "../../contexts/EnvironmentContext.js";
import { useLoadingStatus } from "../../hooks/useLoadingStatus.js";
import { localizationKeys } from "../../localization/localizationKeys.js";
import { createPasswordError } from "../../utils/passwordUtils.js";
import { SignInContext } from "../../contexts/components/SignIn.js";
import { useSignUpContext } from "../../contexts/components/SignUp.js";
import { useCoreSignUp } from "../../contexts/CoreClientContext.js";
import { useLocalizations } from "../../localization/makeLocalizable.js";
import { buildRequest, useFormControl } from "../../utils/useFormControl.js";
import { descriptors } from "../../customizables/elementDescriptors.js";
import { useAppearance } from "../../customizables/AppearanceContext.js";
import { useCardState, withCardStateProvider } from "../../elements/contexts/index.js";
import { Flow } from "../../customizables/Flow.js";
import { Flex } from "../../customizables/index.js";
import { Card } from "../../elements/Card/index.js";
import { Header } from "../../elements/Header.js";
import { handleError } from "../../utils/errorHandler.js";
import { CaptchaElement } from "../../elements/CaptchaElement.js";
import { LoadingCard } from "../../elements/LoadingCard.js";
import { withRedirectToAfterSignUp, withRedirectToSignUpTask } from "../../common/withRedirect.js";
import { getPreferredAlternativePhoneChannel } from "../SignIn/utils.js";
import { SocialButtonsReversibleContainerWithDivider } from "../../elements/ReversibleContainer.js";
import { createUsernameError } from "../../utils/usernameUtils.js";
import { SignUpForm } from "./SignUpForm.js";
import { determineActiveFields, emailOrPhone, getInitialActiveIdentifier, showFormFields } from "./signUpFormHelpers.js";
import { SignUpSocialButtons } from "./SignUpSocialButtons.js";
import { completeSignUpFlow } from "./util.js";
import { SignUpRestrictedAccess } from "./SignUpRestrictedAccess.js";
import { SignUpStartAlternativePhoneCodePhoneNumberCard } from "./SignUpStartAlternativePhoneCodePhoneNumberCard.js";
import React from "react";
import { ERROR_CODES, SIGN_UP_MODES } from "@clerk/shared/internal/clerk-js/constants";
import { getClerkQueryParam, removeClerkQueryParam } from "@clerk/shared/internal/clerk-js/queryParams";
import { useClerk } from "@clerk/shared/react";
import { jsx, jsxs } from "@emotion/react/jsx-runtime";
import { isClerkAPIResponseError } from "@clerk/shared/error";
import { getAlternativePhoneCodeProviderData } from "@clerk/shared/alternativePhoneCode";

//#region src/components/SignUp/SignUpStart.tsx
function SignUpStartInternal() {
	const card = useCardState();
	const clerk = useClerk();
	const status = useLoadingStatus();
	const signUp = useCoreSignUp();
	const { showOptionalFields } = useAppearance().parsedOptions;
	const { userSettings, authConfig } = useEnvironment();
	const { navigate } = useRouter();
	const { attributes } = userSettings;
	const { setActive } = useClerk();
	const ctx = useSignUpContext();
	const isWithinSignInContext = !!React.useContext(SignInContext);
	const { afterSignUpUrl, signInUrl, unsafeMetadata, navigateOnSetActive } = ctx;
	const isCombinedFlow = !!(ctx.isCombinedFlow && !!isWithinSignInContext);
	const [activeCommIdentifierType, setActiveCommIdentifierType] = React.useState(() => getInitialActiveIdentifier(attributes, userSettings.signUp.progressive, {
		phoneNumber: ctx.initialValues?.phoneNumber === null ? void 0 : ctx.initialValues?.phoneNumber,
		emailAddress: ctx.initialValues?.emailAddress === null ? void 0 : ctx.initialValues?.emailAddress,
		...isCombinedFlow ? {
			emailAddress: signUp.emailAddress,
			phoneNumber: signUp.phoneNumber
		} : {}
	}));
	const { t, locale } = useLocalizations();
	const initialValues = ctx.initialValues || {};
	const [alternativePhoneCodeProvider, setAlternativePhoneCodeProvider] = React.useState(null);
	const [missingRequirementsWithTicket, setMissingRequirementsWithTicket] = React.useState(false);
	const { userSettings: { passwordSettings, usernameSettings } } = useEnvironment();
	const { mode } = userSettings.signUp;
	const formState = {
		firstName: useFormControl("firstName", signUp.firstName || initialValues.firstName || "", {
			type: "text",
			label: localizationKeys("formFieldLabel__firstName"),
			placeholder: localizationKeys("formFieldInputPlaceholder__firstName")
		}),
		lastName: useFormControl("lastName", signUp.lastName || initialValues.lastName || "", {
			type: "text",
			label: localizationKeys("formFieldLabel__lastName"),
			placeholder: localizationKeys("formFieldInputPlaceholder__lastName")
		}),
		emailAddress: useFormControl("emailAddress", signUp.emailAddress || initialValues.emailAddress || "", {
			type: "email",
			label: localizationKeys("formFieldLabel__emailAddress"),
			placeholder: localizationKeys("formFieldInputPlaceholder__emailAddress")
		}),
		username: useFormControl("username", signUp.username || initialValues.username || "", {
			type: "text",
			label: localizationKeys("formFieldLabel__username"),
			placeholder: localizationKeys("formFieldInputPlaceholder__username"),
			transformer: (value) => value.trim(),
			buildErrorMessage: (errors) => createUsernameError(errors, {
				t,
				locale,
				usernameSettings
			})
		}),
		phoneNumber: useFormControl("phoneNumber", signUp.phoneNumber || initialValues.phoneNumber || "", {
			type: "tel",
			label: localizationKeys("formFieldLabel__phoneNumber"),
			placeholder: localizationKeys("formFieldInputPlaceholder__phoneNumber")
		}),
		legalAccepted: useFormControl("legalAccepted", "", {
			type: "checkbox",
			label: "",
			defaultChecked: false,
			isRequired: userSettings.signUp.legal_consent_enabled || false
		}),
		password: useFormControl("password", "", {
			type: "password",
			label: localizationKeys("formFieldLabel__password"),
			placeholder: localizationKeys("formFieldInputPlaceholder__password"),
			validatePassword: true,
			buildErrorMessage: (errors) => createPasswordError(errors, {
				t,
				locale,
				passwordSettings
			})
		}),
		ticket: useFormControl("ticket", getClerkQueryParam("__clerk_ticket") || getClerkQueryParam("__clerk_invitation_token") || "")
	};
	const hasTicket = !!formState.ticket.value;
	const hasExistingSignUpWithTicket = !!(signUp.id && signUp.status !== null && (getClerkQueryParam("__clerk_ticket") || getClerkQueryParam("__clerk_invitation_token")));
	const hasEmail = !!formState.emailAddress.value;
	const isProgressiveSignUp = userSettings.signUp.progressive;
	const isLegalConsentEnabled = userSettings.signUp.legal_consent_enabled;
	const oidcPrompt = ctx.oidcPrompt;
	const fields = determineActiveFields({
		attributes,
		hasTicket: hasTicket || hasExistingSignUpWithTicket,
		hasEmail,
		activeCommIdentifierType,
		isProgressiveSignUp,
		legalConsentRequired: isLegalConsentEnabled
	});
	const handleTokenFlow = () => {
		if (!formState.ticket.value) return;
		status.setLoading();
		card.setLoading();
		signUp.create({
			strategy: "ticket",
			ticket: formState.ticket.value,
			unsafeMetadata
		}).then((signUp$1) => {
			formState.emailAddress.setValue(signUp$1.emailAddress || "");
			if (signUp$1.status === "missing_requirements") setMissingRequirementsWithTicket(true);
			const redirectUrl = ctx.ssoCallbackUrl;
			return completeSignUpFlow({
				signUp: signUp$1,
				redirectUrl,
				redirectUrlComplete: ctx.afterSignUpUrl || "/",
				verifyEmailPath: "verify-email-address",
				verifyPhonePath: "verify-phone-number",
				continuePath: "continue",
				handleComplete: () => {
					removeClerkQueryParam("__clerk_ticket");
					removeClerkQueryParam("__clerk_invitation_token");
					return setActive({
						session: signUp$1.createdSessionId,
						navigate: async ({ session }) => {
							await navigateOnSetActive({
								session,
								redirectUrl: afterSignUpUrl
							});
						}
					});
				},
				navigate,
				oidcPrompt
			});
		}).catch((err) => {
			formState.ticket.setValue("");
			handleError(err, [], card.setError);
		}).finally(() => {
			if (signUp.missingFields.some((mf) => mf === "enterprise_sso")) return;
			status.setIdle();
			card.setIdle();
		});
	};
	React.useLayoutEffect(() => {
		handleTokenFlow();
	}, []);
	React.useEffect(() => {
		async function handleOauthError() {
			const error = signUp.verifications.externalAccount.error;
			if (error) {
				switch (error.code) {
					case ERROR_CODES.NOT_ALLOWED_TO_SIGN_UP:
					case ERROR_CODES.OAUTH_ACCESS_DENIED:
					case ERROR_CODES.NOT_ALLOWED_ACCESS:
					case ERROR_CODES.SAML_USER_ATTRIBUTE_MISSING:
					case ERROR_CODES.OAUTH_EMAIL_DOMAIN_RESERVED_BY_SAML:
					case ERROR_CODES.USER_LOCKED:
					case ERROR_CODES.ENTERPRISE_SSO_USER_ATTRIBUTE_MISSING:
					case ERROR_CODES.ENTERPRISE_SSO_EMAIL_ADDRESS_DOMAIN_MISMATCH:
					case ERROR_CODES.ENTERPRISE_SSO_HOSTED_DOMAIN_MISMATCH:
					case ERROR_CODES.SAML_EMAIL_ADDRESS_DOMAIN_MISMATCH:
					case ERROR_CODES.ORGANIZATION_MEMBERSHIP_QUOTA_EXCEEDED_FOR_SSO:
					case ERROR_CODES.CAPTCHA_INVALID:
					case ERROR_CODES.FRAUD_DEVICE_BLOCKED:
					case ERROR_CODES.FRAUD_ACTION_BLOCKED:
					case ERROR_CODES.SIGNUP_RATE_LIMIT_EXCEEDED:
					case ERROR_CODES.USER_BANNED:
						card.setError(error);
						break;
					default: card.setError("Unable to complete action at this time. If the problem persists please contact support.");
				}
				await signUp.create({});
			}
		}
		handleOauthError();
	}, []);
	const handleChangeActive = (type) => {
		if (!emailOrPhone(attributes, isProgressiveSignUp)) return;
		setActiveCommIdentifierType(type);
	};
	const handleSubmit = async (e) => {
		e.preventDefault();
		const fieldsToSubmit = Object.entries(fields).reduce((acc, [k, v]) => {
			acc.push(...v && formState[k] ? [formState[k]] : []);
			return acc;
		}, []);
		if (unsafeMetadata) fieldsToSubmit.push({
			id: "unsafeMetadata",
			value: unsafeMetadata
		});
		if (fields.ticket || hasExistingSignUpWithTicket) {
			const noop = () => {};
			fieldsToSubmit.push({
				id: "strategy",
				value: "ticket",
				clearFeedback: noop,
				setValue: noop,
				onChange: noop,
				setError: noop
			});
			if (!formState.ticket.value && hasExistingSignUpWithTicket) {
				const ticketValue = getClerkQueryParam("__clerk_ticket") || getClerkQueryParam("__clerk_invitation_token");
				if (ticketValue) fieldsToSubmit.push({
					id: "ticket",
					value: ticketValue,
					clearFeedback: noop,
					setValue: noop,
					onChange: noop,
					setError: noop
				});
			}
		}
		const preferredAlternativePhoneChannel = alternativePhoneCodeProvider?.channel || getPreferredAlternativePhoneChannel(fieldsToSubmit, authConfig.preferredChannels, "phoneNumber");
		if (preferredAlternativePhoneChannel) {
			const noop = () => {};
			fieldsToSubmit.push({
				id: "strategy",
				value: "phone_code",
				clearFeedback: noop,
				setValue: noop,
				onChange: noop,
				setError: noop
			});
			fieldsToSubmit.push({
				id: "channel",
				value: preferredAlternativePhoneChannel,
				clearFeedback: noop,
				setValue: noop,
				onChange: noop,
				setError: noop
			});
		}
		const emailAddressProvided = !!(fieldsToSubmit.find((f) => f.id === "emailAddress")?.value || "");
		const phoneNumberProvided = !!(fieldsToSubmit.find((f) => f.id === "phoneNumber")?.value || "");
		if (!emailAddressProvided && !phoneNumberProvided && emailOrPhone(attributes, isProgressiveSignUp)) {
			fieldsToSubmit.push(formState.emailAddress);
			fieldsToSubmit.push(formState.phoneNumber);
		}
		card.setLoading();
		card.setError(void 0);
		const redirectUrl = ctx.ssoCallbackUrl;
		const redirectUrlComplete = ctx.afterSignUpUrl || "/";
		let signUpAttempt;
		if (!fields.ticket && !hasExistingSignUpWithTicket) signUpAttempt = signUp.create(buildRequest(fieldsToSubmit));
		else signUpAttempt = signUp.upsert(buildRequest(fieldsToSubmit));
		return signUpAttempt.then((res) => completeSignUpFlow({
			signUp: res,
			verifyEmailPath: "verify-email-address",
			verifyPhonePath: "verify-phone-number",
			handleComplete: () => setActive({
				session: res.createdSessionId,
				navigate: async ({ session }) => {
					await navigateOnSetActive({
						session,
						redirectUrl: afterSignUpUrl
					});
				}
			}),
			navigate,
			redirectUrl,
			redirectUrlComplete,
			oidcPrompt
		})).catch((err) => {
			/**
			* @experimental
			*/
			if (isClerkAPIResponseError(err) && err.errors?.[0]?.code === "enterprise_connection_id_is_required_with_multiple_connections") return navigate("./enterprise-connections");
			return handleError(err, fieldsToSubmit, card.setError);
		}).finally(() => card.setIdle());
	};
	if (status.isLoading) return /* @__PURE__ */ jsx(LoadingCard, {});
	const canToggleEmailPhone = emailOrPhone(attributes, isProgressiveSignUp);
	const visibleFields = Object.entries(fields).filter(([key, opts]) => {
		if ((key === "emailAddress" || key === "phoneNumber") && canToggleEmailPhone) return !!opts;
		return showOptionalFields || opts?.required;
	});
	const shouldShowForm = showFormFields(userSettings) && visibleFields.length > 0;
	const showOauthProviders = (!(hasTicket || hasExistingSignUpWithTicket) || missingRequirementsWithTicket) && userSettings.authenticatableSocialStrategies.length > 0;
	const showWeb3Providers = !(hasTicket || hasExistingSignUpWithTicket) && userSettings.web3FirstFactors.length > 0;
	const showAlternativePhoneCodeProviders = !(hasTicket || hasExistingSignUpWithTicket) && userSettings.alternativePhoneCodeChannels.length > 0;
	const onAlternativePhoneCodeUseAnotherMethod = () => {
		setAlternativePhoneCodeProvider(null);
	};
	const onAlternativePhoneCodeProviderClick = (phoneCodeChannel) => {
		setAlternativePhoneCodeProvider(getAlternativePhoneCodeProviderData(phoneCodeChannel) || null);
	};
	if (mode !== SIGN_UP_MODES.PUBLIC && !(hasTicket || hasExistingSignUpWithTicket)) return /* @__PURE__ */ jsx(SignUpRestrictedAccess, {});
	return /* @__PURE__ */ jsx(Flow.Part, {
		part: "start",
		children: !alternativePhoneCodeProvider ? /* @__PURE__ */ jsxs(Card.Root, { children: [/* @__PURE__ */ jsxs(Card.Content, { children: [
			/* @__PURE__ */ jsxs(Header.Root, {
				showLogo: true,
				children: [/* @__PURE__ */ jsx(Header.Title, { localizationKey: isCombinedFlow ? localizationKeys("signUp.start.titleCombined") : localizationKeys("signUp.start.title") }), /* @__PURE__ */ jsx(Header.Subtitle, { localizationKey: isCombinedFlow ? localizationKeys("signUp.start.subtitleCombined") : localizationKeys("signUp.start.subtitle") })]
			}),
			/* @__PURE__ */ jsx(Card.Alert, { children: card.error }),
			/* @__PURE__ */ jsxs(Flex, {
				direction: "col",
				elementDescriptor: descriptors.main,
				gap: 6,
				children: [/* @__PURE__ */ jsxs(SocialButtonsReversibleContainerWithDivider, { children: [(showOauthProviders || showWeb3Providers || showAlternativePhoneCodeProviders) && /* @__PURE__ */ jsx(SignUpSocialButtons, {
					enableOAuthProviders: showOauthProviders,
					enableWeb3Providers: showWeb3Providers,
					enableAlternativePhoneCodeProviders: showAlternativePhoneCodeProviders,
					onAlternativePhoneCodeProviderClick,
					continueSignUp: missingRequirementsWithTicket,
					legalAccepted: Boolean(formState.legalAccepted.checked) || void 0
				}), shouldShowForm && /* @__PURE__ */ jsx(SignUpForm, {
					handleSubmit,
					fields,
					formState,
					canToggleEmailPhone,
					handleEmailPhoneToggle: handleChangeActive
				})] }), !shouldShowForm && /* @__PURE__ */ jsx(CaptchaElement, {})]
			})
		] }), /* @__PURE__ */ jsx(Card.Footer, { children: /* @__PURE__ */ jsxs(Card.Action, {
			elementId: "signUp",
			children: [/* @__PURE__ */ jsx(Card.ActionText, { localizationKey: localizationKeys("signUp.start.actionText") }), /* @__PURE__ */ jsx(Card.ActionLink, {
				localizationKey: localizationKeys("signUp.start.actionLink"),
				to: isCombinedFlow ? "../" : clerk.buildUrlWithAuth(signInUrl)
			})]
		}) })] }) : /* @__PURE__ */ jsx(SignUpStartAlternativePhoneCodePhoneNumberCard, {
			handleSubmit,
			fields,
			formState,
			onUseAnotherMethod: onAlternativePhoneCodeUseAnotherMethod,
			phoneCodeProvider: alternativePhoneCodeProvider
		})
	});
}
const SignUpStart = withRedirectToSignUpTask(withRedirectToAfterSignUp(withCardStateProvider(SignUpStartInternal)));

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