'use client'
import { __awaiter } from '../../../../../_virtual/_tslib.js';
import { useCallback } from 'react';
import { NextViewEnum } from '@dynamic-labs/sdk-api-core';
import { isPasskeyWalletConnector } from '@dynamic-labs/wallet-connector-core';
import '../../../context/DynamicContext/DynamicContext.js';
import '../../../store/state/loadingAndLifecycle/loadingAndLifecycle.js';
import '@dynamic-labs/iconic';
import 'react/jsx-runtime';
import { useViewContext } from '../../../context/ViewContext/ViewContext.js';
import { logger } from '../../../shared/logger.js';
import '@dynamic-labs/wallet-book';
import '@dynamic-labs/utils';
import '../../constants/colors.js';
import '../../constants/values.js';
import '../../../shared/consts/index.js';
import { dynamicEvents } from '../../../events/dynamicEvents.js';
import '../../../context/CaptchaContext/CaptchaContext.js';
import '../../../context/ErrorContext/ErrorContext.js';
import { USER_NOT_LOGGED_IN } from '../../constants/errors.js';
import '@dynamic-labs/multi-wallet';
import 'react-international-phone';
import '../../../store/state/nonce/nonce.js';
import { isTurnkeyEnabled } from '../../functions/isTurnkeyEnabled/isTurnkeyEnabled.js';
import { getEnabledEmbeddedWalletsAuthenticators } from '../../functions/getEnabledEmbeddedWalletsAuthenticators/getEnabledEmbeddedWalletsAuthenticators.js';
import { hasEmbeddedWallet } from '../../functions/hasEmbeddedWallet/hasEmbeddedWallet.js';
import { getEmbeddedWalletSessionExpiration } from '../../functions/getEmbeddedWalletSessionExpiration/getEmbeddedWalletSessionExpiration.js';
import '@dynamic-labs-sdk/client/core';
import '../../../client/client.js';
import '@dynamic-labs-sdk/client';
import '../../../config/ApiEndpoint.js';
import '@dynamic-labs/locale';
import { updateUserProfileFields } from '../../../data/api/user/user.js';
import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
import '../../../store/state/primaryWalletId/primaryWalletId.js';
import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
import '../../../context/AccessDeniedContext/AccessDeniedContext.js';
import '../../../context/AccountExistsContext/AccountExistsContext.js';
import '../../../context/UserWalletsContext/UserWalletsContext.js';
import '../../../store/state/authMode/authMode.js';
import { useVerification } from '../../../context/VerificationContext/VerificationContext.js';
import 'react-dom';
import { useElementById } from '../useElementById/useElementById.js';
import '../../functions/compareChains/compareChains.js';
import '../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js';
import '../../../context/ThemeContext/ThemeContext.js';
import { useSmartWallets } from '../useSmartWallets/useSmartWallets.js';
import '../useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
import { iframeContainerId, iframeElementId } from '../../../views/Passkey/PasskeyRecovery/constants.js';
import { canRestoreEmbeddedWalletSession, restoreEmbeddedWalletSession, addNewPasskeyAuthenticator, addEmailRecovery } from '../../../views/Passkey/utils/passkeyRecovery/passkeyRecovery.js';
import { useInitEmbeddedWalletAuthMethod } from '../useInitEmbeddedWalletAuthMethod/useInitEmbeddedWalletAuthMethod.js';
import { useIsTurnkeyWallet } from '../useIsTurnkeyWallet/useIsTurnkeyWallet.js';
import 'bs58';
import '@dynamic-labs/types';
import '../../../context/SocialRedirectContext/SocialRedirectContext.js';
import '../../../context/LoadingContext/LoadingContext.js';
import '../../../context/WalletContext/WalletContext.js';
import '../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js';
import 'yup';
import '../../../context/MockContext/MockContext.js';
import '../../../views/CollectUserDataView/useFields.js';
import '../../../context/FieldsStateContext/FieldsStateContext.js';
import '../../../context/UserFieldEditorContext/UserFieldEditorContext.js';
import '@dynamic-labs/rpc-providers';
import '../../../store/state/walletOptions/walletOptions.js';
import 'react-i18next';
import '../../../components/Accordion/components/AccordionItem/AccordionItem.js';
import '../../../components/Alert/Alert.js';
import '../../../components/ShadowDOM/ShadowDOM.js';
import '../../../components/IconButton/IconButton.js';
import '../../../components/InlineWidget/InlineWidget.js';
import '../../../components/Input/Input.js';
import '../../../components/IsBrowser/IsBrowser.js';
import '../../../components/MenuList/Dropdown/Dropdown.js';
import '../../../components/OverlayCard/OverlayCard.js';
import '../../../components/Transition/ZoomTransition/ZoomTransition.js';
import '../../../components/Transition/SlideInUpTransition/SlideInUpTransition.js';
import '../../../components/Transition/OpacityTransition/OpacityTransition.js';
import '../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.js';
import '../../../components/Popper/Popper/Popper.js';
import '../../../components/Popper/PopperContext/PopperContext.js';
import 'react-focus-lock';
import 'qrcode';
import 'formik';
import '../useSubdomainCheck/useSubdomainCheck.js';
import '../../../context/WalletGroupContext/WalletGroupContext.js';
import '../../../context/IpConfigurationContext/IpConfigurationContext.js';
import '../../../context/ConnectWithOtpContext/ConnectWithOtpContext.js';
import '../../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.js';
import '@hcaptcha/react-hcaptcha';
import '../../../widgets/DynamicWidget/context/DynamicWidgetContext.js';
import '../../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js';
import '../../../views/ExchangeWhitelistWarning/ExchangeWhitelistWarning.js';
import '../../../context/ErrorContext/hooks/useErrorText/useErrorText.js';
import '../../../context/FooterAnimationContext/index.js';
import '../../../views/MfaChooseDeviceView/useGetMfaOptions/useGetMfaOptions.js';
import '../../../context/PasskeyContext/PasskeyContext.js';
import '../../../context/OnrampContext/OnrampContext.js';
import '../../../store/state/sendBalances.js';
import '../../../store/state/connectorsInitializing/connectorsInitializing.js';
import '../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.js';
import '../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.js';
import '../../../views/TransactionConfirmationView/TransactionConfirmationView.js';
import '../../../widgets/DynamicWidget/components/PasskeyCard/PasskeyCard.js';
import '../../../widgets/DynamicWidget/views/CryptoComOnramp/CryptoComOnramp.js';
import '../../../../index.js';
import '../../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js';
import '../../../store/state/tokenBalances.js';
import '../../../store/state/multichainBalances.js';
import '../../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';

// Hook exposed to customers and used internally to trigger passkey recovery
const usePasskeyRecovery = () => {
    var _a, _b, _c;
    const { environmentId, primaryWallet, projectSettings, setShowAuthFlow, user, } = useInternalDynamicContext();
    const { createRootElement } = useElementById();
    const iframeContainerRef = createRootElement(iframeContainerId);
    const { isTurnkeyWalletWithoutAuthenticator, hasRecoveryEmail } = useIsTurnkeyWallet();
    const { initAuthMethod } = useInitEmbeddedWalletAuthMethod();
    const { setDisplayedDestination: setEmailForVerification, setVerificationUUID, } = useVerification();
    const { getEOAWallet } = useSmartWallets();
    const { pushView } = useViewContext();
    const wallet = (_a = (primaryWallet && getEOAWallet(primaryWallet))) !== null && _a !== void 0 ? _a : primaryWallet;
    const isSessionRestored = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        var _d, _e;
        if (!((_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _d === void 0 ? void 0 : _d.sessionKeyDuration) ||
            !canRestoreEmbeddedWalletSession((_e = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _e === void 0 ? void 0 : _e.sessionKeyDuration)) {
            return false;
        }
        const sessionExpiration = getEmbeddedWalletSessionExpiration(projectSettings.sdk.embeddedWallets.sessionKeyDuration);
        try {
            return yield restoreEmbeddedWalletSession({
                iframeContainer: iframeContainerRef.current,
                iframeElementId,
                sessionExpiration,
                user,
                wallet: primaryWallet,
            });
        }
        catch (err) {
            logger.error('Failed to restore embedded wallet', err);
        }
        return false;
    }), [
        user,
        iframeContainerRef,
        primaryWallet,
        (_c = (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _b === void 0 ? void 0 : _b.embeddedWallets) === null || _c === void 0 ? void 0 : _c.sessionKeyDuration,
    ]);
    const shouldInitRecovery = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        if (!wallet || !isPasskeyWalletConnector(wallet.connector)) {
            return false;
        }
        const turnkeyRecoveryHandler = wallet.connector.getAuthenticatorHandler();
        // user has passkey authenticator set up OR
        // email auth - session is still up, so no need to recover
        if (!isTurnkeyWalletWithoutAuthenticator ||
            turnkeyRecoveryHandler.isSessionActive() ||
            (yield isSessionRestored())) {
            return false;
        }
        return true;
    }), [wallet, isTurnkeyWalletWithoutAuthenticator, isSessionRestored]);
    const initPasskeyRecoveryProcess = useCallback((authenticatorType, currentAction) => __awaiter(void 0, void 0, void 0, function* () {
        var _f;
        const validateRecoveryRequest = () => {
            if (!user) {
                throw new Error(USER_NOT_LOGGED_IN);
            }
            if (!isTurnkeyEnabled(projectSettings)) {
                throw new Error('Dynamic embedded wallet is not enabled. Go to the dashboard and make sure to have both Dynamic embedded wallet and at least one EVM network enabled. Also, check if EthereumWalletConnectors is in the  DynamicContextProvider > settings > walletConnectors.');
            }
            if (!hasEmbeddedWallet(user)) {
                throw new Error('Dynamic embedded wallet not found');
            }
            if (wallet && !isPasskeyWalletConnector(wallet.connector)) {
                throw new Error('Dynamic embedded wallet not found.');
            }
        };
        validateRecoveryRequest();
        const turnkeyRecoveryHandler = (wallet === null || wallet === void 0 ? void 0 : wallet.connector).getAuthenticatorHandler();
        // email auth - session is still up, so create passkey authenticator usign the same session
        if (authenticatorType === 'passkey' &&
            turnkeyRecoveryHandler.isSessionActive()) {
            yield addNewPasskeyAuthenticator({
                environmentId,
                user,
                wallet: wallet,
            });
            setShowAuthFlow(false);
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            return wallet;
        }
        const supportedAuthenticators = getEnabledEmbeddedWalletsAuthenticators((_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _f === void 0 ? void 0 : _f.supportedSecurityMethods);
        const supportedAuthenticatorMethods = supportedAuthenticators
            ? Object.keys(supportedAuthenticators)
            : [];
        if (!hasRecoveryEmail) {
            pushView('passkey-recovery-add-email', { shouldInitRecovery: true });
            setShowAuthFlow(true, {
                ignoreIfIsEmbeddedWidget: false,
                performMultiWalletChecks: false,
            });
        }
        else if (!authenticatorType &&
            supportedAuthenticatorMethods.length > 1) {
            pushView('embedded-wallet-auth-choice', { currentAction });
            setShowAuthFlow(true, {
                ignoreIfIsEmbeddedWidget: false,
                performMultiWalletChecks: false,
            });
        }
        else {
            const [authType] = supportedAuthenticatorMethods;
            // since we're forcing the authenticator type = 'email' during transactions when no passkey is configured,
            // we need to make sure it's supported.
            // Otherwise, we'll use the first supported authenticator type from the list
            if (authenticatorType &&
                !supportedAuthenticatorMethods.includes(authenticatorType)) {
                authenticatorType = authType;
            }
            yield initAuthMethod({
                authenticatorType: authenticatorType || authType,
                currentAction,
                iframeContainer: iframeContainerRef.current,
            });
        }
        return new Promise((resolve, reject) => {
            dynamicEvents.once('passkeyRecoveryCompleted', (wallet) => resolve(wallet));
            dynamicEvents.once('passkeyRecoveryFailed', (error) => reject(error));
        });
    }), [
        wallet,
        projectSettings,
        hasRecoveryEmail,
        environmentId,
        user,
        setShowAuthFlow,
        pushView,
        initAuthMethod,
        iframeContainerRef,
    ]);
    const addRecoveryEmail = (emailInput) => __awaiter(void 0, void 0, void 0, function* () {
        try {
            let updatedUser = user;
            // TODO - This seems wrong what if the user has a different email.
            // As well it does not verify the the email is verified
            if (!(user === null || user === void 0 ? void 0 : user.email)) {
                updatedUser = yield updateUserProfile(emailInput);
            }
            yield addEmailRecovery({
                environmentId,
                user: updatedUser,
                wallet: primaryWallet,
            });
            dynamicEvents.emit('embeddedWalletRecoveryEmailCompleted', '');
        }
        catch (err) {
            logger.error('Failed to add recovery email', err);
            dynamicEvents.emit('embeddedWalletRecoveryEmailFailed', err);
        }
    });
    const updateUserProfile = (emailInput) => __awaiter(void 0, void 0, void 0, function* () {
        try {
            const { nextView, emailVerification, userProfile } = yield updateUserProfileFields(environmentId, {
                email: emailInput,
            });
            if (nextView === NextViewEnum.Done) {
                return userProfile;
            }
            pushView('verify-email', { isEmailRecoveryFlow: true });
            setEmailForVerification(emailInput);
            setVerificationUUID(emailVerification === null || emailVerification === void 0 ? void 0 : emailVerification.verificationUUID);
            return new Promise((resolve, reject) => {
                // TODO - This is not the latest user, it is the not verified user
                dynamicEvents.once('emailVerificationResult', (wasSuccessful) => {
                    if (wasSuccessful) {
                        resolve(userProfile);
                    }
                    reject('Failed to verify email');
                });
            });
        }
        catch (err) {
            logger.error('Failed to update user email', err);
            throw err;
        }
    });
    return {
        addRecoveryEmail,
        initPasskeyRecoveryProcess,
        shouldInitRecovery,
    };
};

export { usePasskeyRecovery };
