import { n as useTranslation, o as readStoredLanguage } from "../i18n-DoP1NB7u.js";
import { _ as y, c as z, l as A, o as P, p as d, v as u } from "../vendor-preact-DThS2ZQ_.js";
import { t as setUiConfig } from "../uiConfig-D2_wawvr.js";
import { c as useManager } from "../hooks-Da_yP_Dr.js";
import { t as IncodeComponent } from "../incodeComponent-CCP7GTMj.js";
import { t as TransitionSpinner } from "../transitionSpinner-dYLkc7PO.js";
import { t as registerIncodeModuleElement } from "../incodeModule-M8DszCee.js";
import { a as resolveApiKey, g as setupSDK, i as HEADLESS_WORKFLOW_MODULE_KEYS, l as LAZY_UI_MODULES, o as extractIncodeStatus, s as UnsupportedModule, t as useModuleLoader, v as fetchAndApplyTheme, y as TerminalErrorPage } from "../useModuleLoader-9R2L73bj.js";
import { resolveWasmConfig, upgradeToWasmHttpClient, warmupWasm } from "@incodetech/core/wasm";
import { getDeviceClass } from "@incodetech/core/device";
import { bootstrapSession, refreshQrUrlUuid } from "@incodetech/core/session";
import { createWorkflowManager } from "@incodetech/core/workflow";
//#region src/modules/workflow/workflowInit.ts
var LAZY_WORKFLOW_MODULES = {
	...LAZY_UI_MODULES,
	REDIRECT_TO_MOBILE: () => import("../redirect-to-mobile/redirect-to-mobile.es.js").then((m) => m.RedirectToMobile),
	ID: () => import("../id-verification/id-verification.es.js").then((m) => m.IdVerification),
	IDENTITY_REUSE: () => import("../identity-reuse/identity-reuse.es.js").then((m) => m.IdentityReuse)
};
async function fetchWorkflowTheme() {
	try {
		const theme = await fetchAndApplyTheme();
		return {
			theme,
			uiConfig: {
				logoSrc: theme.logo,
				hideFooterBranding: theme.hideFooterBranding
			}
		};
	} catch {
		return {};
	}
}
function createWorkflowUIManager(options = {}) {
	return createWorkflowManager({
		customModuleCallback: options.customModuleCallback,
		interviewId: options.interviewId,
		isDesktop: options.isDesktop ?? getDeviceClass() === "desktop"
	});
}
function warmupWorkflowWasm(wasmConfig) {
	if (wasmConfig === false) return;
	const resolved = resolveWasmConfig({
		...wasmConfig,
		pipelines: wasmConfig?.pipelines ?? ["selfie", "idCapture"]
	});
	const upgradeConfig = {
		...resolved,
		pipelines: resolved.pipelines ? [...resolved.pipelines] : void 0
	};
	warmupWasm(resolved).then(() => upgradeToWasmHttpClient(upgradeConfig)).catch((error) => {
		console.error("Workflow WASM warmup failed:", error);
	});
}
//#endregion
//#region src/modules/workflow/createWorkflowSession.ts
async function createWorkflowSession(config, signal) {
	return bootstrapSession(await resolveApiKey(config), {
		configurationId: config.configurationId,
		externalId: config.externalId,
		externalCustomerId: config.externalCustomerId,
		language: config.lang,
		customFields: config.customFields,
		uuid: config.uuid,
		urlUuid: config.urlUuid,
		loginHint: config.loginHint,
		onUrlUuidRefreshed: config.onUrlUuidRefreshed
	}, signal);
}
//#endregion
//#region src/modules/workflow/workflowConfig.ts
function hasWorkflowToken(config) {
	return typeof config.token === "string";
}
function isSelfLoadingWorkflowConfig(config) {
	const bootstrapConfig = config;
	return typeof bootstrapConfig.configurationId === "string" && (typeof bootstrapConfig.apiKey === "string" || typeof bootstrapConfig.clientId === "string");
}
//#endregion
//#region src/modules/workflow/useWorkflowInitialization.ts
function useWorkflowInitialization(options) {
	const { onError, onUrlUuidRefreshed } = options;
	const [state, setState] = d({ status: "initializing" });
	const managerRef = A(null);
	y(() => {
		if (state.status !== "initializing") return;
		const abortController = new AbortController();
		const { signal } = abortController;
		const initialize = async () => {
			try {
				let resolvedToken;
				let resolvedInterviewId;
				if (hasWorkflowToken(options)) {
					resolvedToken = options.token;
					resolvedInterviewId = options.interviewId;
					if (options.urlUuid) await refreshQrUrlUuid({
						urlUuid: options.urlUuid,
						onboardingId: null,
						onRefreshed: onUrlUuidRefreshed
					}, signal);
				} else if (isSelfLoadingWorkflowConfig(options)) {
					const session = await createWorkflowSession(options, signal);
					resolvedToken = session.token;
					resolvedInterviewId = session.interviewId;
				} else throw new Error("Workflow requires token, or configurationId with apiKey or clientId");
				if (signal.aborted) return;
				await setupSDK({
					token: resolvedToken,
					lang: options.lang
				});
				if (signal.aborted) return;
				const themePromise = options.disableDashboardTheme ? Promise.resolve() : fetchWorkflowTheme().then((result) => {
					if (result.uiConfig) setUiConfig(result.uiConfig);
				});
				warmupWorkflowWasm(options.wasmConfig);
				if (signal.aborted) return;
				managerRef.current = createWorkflowUIManager({
					customModuleCallback: options.customModuleCallback,
					interviewId: resolvedInterviewId,
					isDesktop: options.isDesktop
				});
				managerRef.current.load();
				await themePromise;
				if (signal.aborted) return;
				setState({
					status: "ready",
					workflowManager: managerRef.current
				});
			} catch (error) {
				if (signal.aborted) return;
				const errorMessage = error instanceof Error ? error.message : "Failed to initialize SDK";
				const errorCode = extractIncodeStatus(error);
				setState({
					status: "error",
					error: errorMessage,
					errorCode
				});
				onError?.(errorMessage, errorCode);
			}
		};
		initialize();
		return () => {
			abortController.abort();
			managerRef.current?.stop();
			managerRef.current = null;
		};
	}, []);
	return state;
}
//#endregion
//#region src/modules/workflow/workflow.tsx
var LazyHomeScreen = z(() => import("../homeScreen-W6-PF75j.js").then((module) => ({ default: module.HomeScreen })));
function mapModuleConfig(options) {
	const { moduleKey, config, workflowId, authHint, lang, mergeSessionRecordings, ageAssurance } = options;
	switch (moduleKey) {
		case "AUTHENTICATION": return {
			...config,
			authHint
		};
		case "REDIRECT_TO_MOBILE": return {
			...config,
			flowId: workflowId,
			authHint,
			lang
		};
		case "ID_CAPTURE":
		case "TUTORIAL_ID": return {
			...config,
			mergeSessionRecordings: config.mergeSessionRecordings ?? mergeSessionRecordings,
			ageAssurance: config.ageAssurance ?? ageAssurance,
			skipProcessId: true
		};
		case "ID": return config;
		case "SELFIE": return {
			...config,
			ageAssurance: config.ageAssurance ?? ageAssurance
		};
		case "ADDRESS": return {
			...config,
			processingType: "addressStatement"
		};
		case "SECOND_ID": return {
			...config,
			isSecondId: true
		};
		case "MANDATORY_CONSENT": return {
			...config,
			type: "MANDATORY"
		};
		default: return config;
	}
}
/**
* Inner component mounted only after `useWorkflowInitialization` has resolved
* the session and constructed the manager. Splitting this out keeps the
* `useManager` factory call out of the init path — token-mode and
* self-loading mode both arrive here with a fully-constructed manager.
*/
var IncodeWorkflowReady = ({ config, workflowManager: initialManager, onFinish, onError }) => {
	const [workflowState, workflowManager] = useManager(() => initialManager, {
		autoLoad: false,
		manageLifecycle: false
	});
	const moduleLoaderState = useModuleLoader({
		moduleKey: workflowState?.status === "ready" ? workflowState.currentNode.moduleKey : void 0,
		modules: LAZY_WORKFLOW_MODULES,
		headlessModuleKeys: HEADLESS_WORKFLOW_MODULE_KEYS,
		onModuleLoading: config.onModuleLoading,
		onModuleLoaded: config.onModuleLoaded,
		onError
	});
	const terminalFiredRef = A(false);
	y(() => {
		if (terminalFiredRef.current) return;
		if (workflowState?.status === "finished") {
			terminalFiredRef.current = true;
			const finishStatus = workflowState.finishStatus;
			queueMicrotask(() => onFinish?.(finishStatus));
			return;
		}
		if (workflowState?.status === "asyncResolution") {
			terminalFiredRef.current = true;
			queueMicrotask(() => onFinish?.());
			return;
		}
		if (workflowState?.status === "error" && onError) {
			terminalFiredRef.current = true;
			const { error, errorCode } = workflowState;
			queueMicrotask(() => onError(error, errorCode));
		}
	}, [
		workflowState?.status,
		onFinish,
		onError,
		workflowState
	]);
	const hideSpinnerText = !(config.spinnerConfig?.title || config.spinnerConfig?.subtitle);
	const renderSpinner = () => /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(TransitionSpinner, {
			spinnerConfig: config.spinnerConfig,
			hideText: hideSpinnerText
		})
	});
	const handleModuleError = (error, _errorCode, moduleErrorCode) => {
		workflowManager.errorModule(error ?? "Module error", moduleErrorCode);
	};
	if (workflowState && "homeScreen" in workflowState && workflowState.homeScreen.visible) return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(P, {
			fallback: null,
			children: /* @__PURE__ */ u(LazyHomeScreen, {
				isContinueLoading: workflowState.homeScreen.isContinueLoading,
				onContinue: () => workflowManager.continueFromHome()
			})
		})
	});
	if (!workflowState || workflowState.status === "idle" || workflowState.status === "loading") return renderSpinner();
	if (workflowState.status === "error") return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(TerminalErrorPage, { message: workflowState.error })
	});
	if (workflowState.status === "finished" || workflowState.status === "asyncResolution" || workflowState.status === "closed") return null;
	if (moduleLoaderState.status === "unsupported") return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(UnsupportedModule, {
			moduleKey: workflowState.currentNode.moduleKey,
			onNext: () => workflowManager.completeModule()
		})
	});
	if (moduleLoaderState.status === "idle" || moduleLoaderState.status === "loading" || moduleLoaderState.status === "error") return renderSpinner();
	const { Component } = moduleLoaderState;
	const moduleConfig = mapModuleConfig({
		moduleKey: workflowState.currentNode.moduleKey,
		config: workflowState.config,
		workflowId: workflowState.workflowConfig.id,
		authHint: config.authHint,
		lang: config.lang,
		mergeSessionRecordings: workflowState.workflowConfig.mergeSessionRecordings,
		ageAssurance: workflowState.workflowConfig.ageAssurance
	});
	let extraProps = {};
	if (workflowState.currentNode.moduleKey === "REDIRECT_TO_MOBILE") extraProps = {
		onFinish: () => workflowManager.finishWorkflow(),
		onContinue: () => workflowManager.completeModule()
	};
	return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(Component, {
			config: moduleConfig,
			onFinish: () => workflowManager.completeModule(),
			onError: handleModuleError,
			...extraProps
		}, workflowState.currentNode.id)
	});
};
var IncodeWorkflowContent = ({ config, onFinish, onError }) => {
	const { i18n } = useTranslation();
	const initState = useWorkflowInitialization({
		...config,
		onError
	});
	y(() => {
		if (readStoredLanguage()) return;
		if (config.lang && i18n.language !== config.lang) i18n.changeLanguage(config.lang);
	}, [config.lang, i18n]);
	const hideSpinnerText = !(config.spinnerConfig?.title || config.spinnerConfig?.subtitle);
	if (initState.status === "error") return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(TerminalErrorPage, { message: initState.error })
	});
	if (initState.status === "initializing") return /* @__PURE__ */ u("div", {
		class: "IncodeWorkflow",
		children: /* @__PURE__ */ u(TransitionSpinner, {
			spinnerConfig: config.spinnerConfig,
			hideText: hideSpinnerText
		})
	});
	return /* @__PURE__ */ u(IncodeWorkflowReady, {
		config,
		workflowManager: initState.workflowManager,
		onFinish,
		onError
	});
};
var IncodeWorkflow = ({ config, onFinish, onError }) => /* @__PURE__ */ u(IncodeComponent, { children: config ? /* @__PURE__ */ u(IncodeWorkflowContent, {
	config,
	onFinish,
	onError
}) : null });
registerIncodeModuleElement(IncodeWorkflow, "incode-workflow");
//#endregion
export { IncodeWorkflow, mapModuleConfig };
