'use client'
import { __awaiter } from '../../../../_virtual/_tslib.js';
import { useCallback } from 'react';
import { StorageService, PHANTOM_REDIRECT_CONNECTION_TYPE_KEY } from '@dynamic-labs/utils';
import { isPhantomRedirectConnector } from '@dynamic-labs/wallet-connector-core';
import { LAST_USED_WALLET, PHANTOM_SIGNATURE_STATE } from '../../utils/constants/localStorage.js';
import { getSiweStatement } from '../../utils/functions/getSiweStatement/getSiweStatement.js';
import { dynamicEvents } from '../../events/dynamicEvents.js';
import '../DynamicContext/useDynamicContext/useDynamicContext.js';
import { useInternalDynamicContext } from '../DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
import { useCaptchaContext } from '../CaptchaContext/CaptchaContext.js';
import '@dynamic-labs/sdk-api-core';
import { useErrorContext, getMappedErrorMessage, PHANTOM_SIGNING_FAILED_ERROR_CODE } from '../ErrorContext/ErrorContext.js';
import { useViewContext } from '../ViewContext/ViewContext.js';
import '@dynamic-labs/iconic';
import 'react/jsx-runtime';
import { logger } from '../../shared/logger.js';
import '@dynamic-labs/wallet-book';
import '../../utils/constants/colors.js';
import '../../utils/constants/values.js';
import { instrumentAuthLoginFailed } from '../../shared/utils/functions/instrumentAuthLoginFailed/instrumentAuthLoginFailed.js';
import '../../shared/consts/index.js';
import '@dynamic-labs/multi-wallet';
import 'react-international-phone';
import '../../store/state/nonce/nonce.js';
import '@dynamic-labs-wallet/browser-wallet-client';
import '@dynamic-labs-sdk/client/core';
import 'eventemitter3';
import '@dynamic-labs-sdk/client';
import '../../config/ApiEndpoint.js';
import '@dynamic-labs/locale';
import '../../store/state/dynamicContextProps/dynamicContextProps.js';
import '../../store/state/primaryWalletId/primaryWalletId.js';
import '../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
import '../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
import { useVerifyWallet } from '../../utils/hooks/useVerifyWallet/useVerifyWallet.js';
import { isConnectOnly } from '../../utils/hooks/authenticationHooks/helpers/isConnectOnly.js';
import '../../store/state/loadingAndLifecycle/loadingAndLifecycle.js';
import '../VerificationContext/VerificationContext.js';
import 'react-dom';
import '../../utils/functions/compareChains/compareChains.js';
import '../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js';
import '../ThemeContext/ThemeContext.js';
import '../../store/state/authMode/authMode.js';
import '../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
import 'bs58';
import '@dynamic-labs/types';
import '../SocialRedirectContext/SocialRedirectContext.js';
import '../AccessDeniedContext/AccessDeniedContext.js';
import '../AccountExistsContext/AccountExistsContext.js';
import '../LoadingContext/LoadingContext.js';
import '../WalletContext/WalletContext.js';
import '../UserWalletsContext/UserWalletsContext.js';
import '../../utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js';
import 'yup';
import '../MockContext/MockContext.js';
import '../../views/CollectUserDataView/useFields.js';
import '../FieldsStateContext/FieldsStateContext.js';
import '../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 '../../utils/hooks/useSubdomainCheck/useSubdomainCheck.js';
import '../WalletGroupContext/WalletGroupContext.js';
import '../../widgets/DynamicWidget/context/DynamicWidgetContext.js';
import '../../utils/hooks/useGetMfaToken/useGetMfaToken.js';
import '../../utils/hooks/useWalletBackup/useWalletBackup.js';
import '../../utils/hooks/useWalletBackup/BackupError.js';
import '../../utils/hooks/useWalletBackup/types.js';
import '../../utils/hooks/useWalletBackup/cloudProviders.js';
import '@hcaptcha/react-hcaptcha';
import '@marsidev/react-turnstile';
import '../IpConfigurationContext/IpConfigurationContext.js';
import '../ConnectWithOtpContext/ConnectWithOtpContext.js';
import '../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.js';
import '../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js';
import '../../views/ExchangeWhitelistWarning/ExchangeWhitelistWarning.js';
import '../ErrorContext/hooks/useErrorText/useErrorText.js';
import '../FooterAnimationContext/index.js';
import '../../views/MfaChooseDeviceView/useGetMfaOptions/useGetMfaOptions.js';
import '../PasskeyContext/PasskeyContext.js';
import '../OnrampContext/OnrampContext.js';
import '../../utils/hooks/useWalletDelegation/DelegationError.js';
import { useTransferWallet } from '../../utils/hooks/useTransferWallet/useTransferWallet.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 { useInternalFundWithWallet } from '../../utils/hooks/useFundWithWallet/useFundWithWallet.js';
import { getPromptAmountParams } from '../../widgets/DynamicWidget/views/ChooseWalletFundingMethod/useFundingMethods/getPromptAmountParams/getPromptAmountParams.js';
import '../../widgets/DynamicWidget/views/ManagePasskeysMfaWidgetView/ManagePasskeysMfaWidgetView.js';
import '../../widgets/DynamicWidget/views/ManageTotpMfaWidgetView/ManageTotpMfaWidgetView.js';
import '../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js';
import '../../../index.js';
import '../../store/state/tokenBalances.js';
import '../../store/state/multichainBalances.js';
import '@dynamic-labs/store';
import '../../shared/utils/functions/getInitialUrl/getInitialUrl.js';

const useResponseHandlers = () => {
    const { walletConnectorOptions, displaySiweStatement, environmentId, projectSettings, setIsSingleWalletAccount, connectWallet, setShowAuthFlow, setSelectedWalletConnectorKey, siweStatement, appName, user, } = useInternalDynamicContext();
    const { pushView } = useViewContext();
    const { setErrorMessage } = useErrorContext();
    const { getCaptchaToken } = useCaptchaContext();
    const { promptAmountAndFund } = useInternalFundWithWallet();
    const verifyWallet = useVerifyWallet({
        displaySiweStatement,
        environmentId,
        projectSettings,
        setIsSingleWalletAccount,
    });
    const phantomRedirectConnector = walletConnectorOptions
        .map(({ walletConnector }) => walletConnector)
        .find(isPhantomRedirectConnector);
    const handleConnectResponse = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] called');
        if (!phantomRedirectConnector) {
            logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] no phantomRedirectConnector');
            return;
        }
        // this completes the connection step
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] calling getSession');
        yield phantomRedirectConnector.getSession();
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] getSession complete, calling connectWallet');
        const connectResult = yield connectWallet(phantomRedirectConnector);
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] connectWallet result', {
            connectResult,
        });
        // Check if we have a connection type
        const connectionType = StorageService.getItem(PHANTOM_REDIRECT_CONNECTION_TYPE_KEY);
        // If this is an external wallet funding connection, then we need to
        // complete the wallet transfer.
        // If connectorConsumed is false that means that the connector has not yet
        // verified this connection type and we should ignore it.
        if ((connectionType === null || connectionType === void 0 ? void 0 : connectionType.connectorConsumed) &&
            connectionType.type === 'external-wallet-funding') {
            if (!connectResult)
                return;
            const wallet = phantomRedirectConnector.createWallet({
                address: connectResult.address,
                chain: phantomRedirectConnector.connectedChain,
                connector: phantomRedirectConnector,
                id: 'external-funding-wallet',
                isAuthenticated: false,
                key: phantomRedirectConnector.key,
            });
            // If the connection was initiated by the widget we can carry on with the funding flow
            // Otherwise we simply raise an event to let the customer's code handle the wallet
            dynamicEvents.emit('walletConnectedForFunding', {
                initiatedByWidget: connectionType.initiatedByWidget,
                isPhantomRedirect: true,
                wallet,
            });
            if (!connectionType.initiatedByWidget)
                return;
            const props = getPromptAmountParams({ wallet });
            promptAmountAndFund(props);
            return;
        }
        // Default behavior is to link a wallet
        // In connect-only mode, skip verification and just handle the wallet connection
        if (isConnectOnly()) {
            logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] Connect-only mode: skipping verification', {
                authMode: 'connect-only',
                connectResult,
            });
            if (connectResult === null || connectResult === void 0 ? void 0 : connectResult.address) {
                // connectWallet already added the wallet to the store in connect-only mode
                // Just set the last used wallet and close the auth flow
                StorageService.setItem(LAST_USED_WALLET, phantomRedirectConnector.key);
                setShowAuthFlow(false);
            }
            return;
        }
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleConnectResponse] Connect-and-sign mode: proceeding to verification', {
            authMode: 'connect-and-sign',
            connectResult,
        });
        setShowAuthFlow(true, { ignoreIfIsEmbeddedWidget: true });
        pushView('pending-signature');
        setSelectedWalletConnectorKey('phantom');
    }), [
        phantomRedirectConnector,
        connectWallet,
        setShowAuthFlow,
        pushView,
        setSelectedWalletConnectorKey,
        promptAmountAndFund,
    ]);
    const completeWalletTransfer = useTransferWallet();
    const handleUserResponse = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        var _a, _b, _c, _d;
        logger.debug('[PhantomRedirect handleUserResponse] called');
        if (!phantomRedirectConnector) {
            logger.debug('[PhantomRedirect handleUserResponse] no phantomRedirectConnector');
            return;
        }
        setSelectedWalletConnectorKey('phantom');
        const [address] = yield phantomRedirectConnector.getConnectedAccounts();
        logger.debug('[PhantomRedirect handleUserResponse] got address', {
            address,
        });
        const method = phantomRedirectConnector.consumeMethod();
        logger.debug('[PhantomRedirect handleUserResponse] consumed method', {
            method,
        });
        switch (method) {
            case 'signAndSendTransaction': {
                // Phantom redirect doesn't support signAndSendTransaction natively,
                // so we extract the signed transaction and send it ourselves
                const signAndSendRequestId = (_a = phantomRedirectConnector.consumeRequestId) === null || _a === void 0 ? void 0 : _a.call(phantomRedirectConnector);
                logger.debug('[PhantomRedirect handleUserResponse] handling signAndSendTransaction');
                try {
                    const signature = yield phantomRedirectConnector.extractAndSendTransaction();
                    phantomRedirectConnector.emit('signAndSendTransaction', {
                        requestId: signAndSendRequestId,
                        signature,
                    });
                }
                catch (error) {
                    logger.error('[PhantomRedirect handleUserResponse] Failed to send transaction', { error });
                    phantomRedirectConnector.emit('signAndSendTransaction', {
                        errorCode: 'SEND_FAILED',
                        errorMessage: error instanceof Error
                            ? error.message
                            : 'Failed to send transaction',
                        requestId: signAndSendRequestId,
                    });
                }
                break;
            }
            case 'signAllTransactions': {
                const signAllRequestId = (_b = phantomRedirectConnector.consumeRequestId) === null || _b === void 0 ? void 0 : _b.call(phantomRedirectConnector);
                logger.debug('[PhantomRedirect handleUserResponse] handling signAllTransactions');
                phantomRedirectConnector.emit('signAllTransactions', {
                    requestId: signAllRequestId,
                    transactions: phantomRedirectConnector.extractTransactions(),
                });
                break;
            }
            case 'signTransaction': {
                const requestId = (_c = phantomRedirectConnector.consumeRequestId) === null || _c === void 0 ? void 0 : _c.call(phantomRedirectConnector);
                logger.debug('[PhantomRedirect handleUserResponse] handling signTransaction');
                phantomRedirectConnector.emit('signTransaction', {
                    requestId,
                    transaction: phantomRedirectConnector.extractTransaction(),
                });
                break;
            }
            case 'signMessage': {
                logger.debug('[PhantomRedirect handleUserResponse] handling signMessage response');
                const { signature, message } = phantomRedirectConnector.extractSignature();
                logger.debug('[PhantomRedirect handleUserResponse] extracted signature and message', {
                    message,
                    messageLength: message === null || message === void 0 ? void 0 : message.length,
                    messagePreview: message === null || message === void 0 ? void 0 : message.substring(0, 200),
                    signature,
                    signatureLength: signature === null || signature === void 0 ? void 0 : signature.length,
                });
                const signatureState = StorageService.getItem(PHANTOM_SIGNATURE_STATE);
                StorageService.removeItem(PHANTOM_SIGNATURE_STATE);
                if ((signatureState === null || signatureState === void 0 ? void 0 : signatureState.verificationType) === 'awaiting_transfer') {
                    const siweStatementToUse = getSiweStatement({
                        appName,
                        siweStatement,
                    });
                    logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleUserResponse] completeWalletTransfer', {
                        messageToSignOverride: message,
                        overrideSiweStatement: siweStatementToUse,
                        publicWalletAddress: address,
                        signedMessageOverride: signature,
                    });
                    yield completeWalletTransfer({
                        messageToSignOverride: message,
                        overrideSiweStatement: siweStatementToUse,
                        publicWalletAddress: address,
                        signedMessageOverride: signature,
                        skipEmptyAccountCheck: signatureState.loseOriginalAccountOnTransfer,
                        walletConnector: phantomRedirectConnector,
                    });
                }
                else if ((signatureState === null || signatureState === void 0 ? void 0 : signatureState.verificationType) === 'awaiting_verification' ||
                    !user) {
                    logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleUserResponse] calling verifyWallet', {
                        address,
                        captchaTokenPresent: Boolean(getCaptchaToken()),
                        message,
                        messageLength: message === null || message === void 0 ? void 0 : message.length,
                        signature,
                        signatureLength: signature === null || signature === void 0 ? void 0 : signature.length,
                        user: Boolean(user),
                        verificationType: signatureState === null || signatureState === void 0 ? void 0 : signatureState.verificationType,
                    });
                    pushView('wallet-redirect-view');
                    try {
                        yield verifyWallet({
                            captchaToken: getCaptchaToken(),
                            messageToSignOverride: message,
                            publicWalletAddress: address,
                            signedMessageOverride: signature,
                            walletConnector: phantomRedirectConnector,
                        });
                        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleUserResponse] verifyWallet completed successfully');
                    }
                    catch (error) {
                        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleUserResponse] verifyWallet threw error', { error });
                        throw error;
                    }
                }
                else {
                    // Post-auth sign: emit the signMessage event with the requestId and message
                    // so the listener from signMessage() can match and self-cleanup
                    const requestId = (_d = phantomRedirectConnector.consumeRequestId) === null || _d === void 0 ? void 0 : _d.call(phantomRedirectConnector);
                    logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleUserResponse] emitting signMessage event (post-auth sign)', {
                        message,
                        requestId,
                        signature,
                        signatureLength: signature === null || signature === void 0 ? void 0 : signature.length,
                    });
                    phantomRedirectConnector.emit('signMessage', {
                        message,
                        requestId,
                        signature,
                    });
                }
                break;
            }
        }
    }), [
        phantomRedirectConnector,
        setSelectedWalletConnectorKey,
        user,
        appName,
        siweStatement,
        completeWalletTransfer,
        pushView,
        verifyWallet,
        getCaptchaToken,
    ]);
    const handleErrorResponse = useCallback((params) => {
        var _a;
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleErrorResponse] called', {
            errorCode: params.get('errorCode'),
            errorMessage: params.get('errorMessage'),
        });
        if (!phantomRedirectConnector) {
            logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleErrorResponse] no phantomRedirectConnector');
            return;
        }
        const errorCode = params.get('errorCode');
        const errorMessage = (_a = params.get('errorMessage')) !== null && _a !== void 0 ? _a : undefined;
        if (!errorCode) {
            logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleErrorResponse] no errorCode');
            return;
        }
        instrumentAuthLoginFailed({ code: errorCode, message: errorMessage }, { authOrigin: 'phantom-redirect' });
        const method = phantomRedirectConnector.consumeMethod();
        // Phantom relays its own signing failures back through the redirect URL
        // (e.g. the active account has no usable key to sign). These come with a
        // generic, unmapped code, which would otherwise surface the default
        // "Something went wrong" message. When the failed operation was a signing
        // request, normalize unmapped codes to an actionable Phantom message.
        const isUnmappedSigningError = method !== undefined && getMappedErrorMessage(errorCode) === undefined;
        const errorMessageKey = isUnmappedSigningError
            ? PHANTOM_SIGNING_FAILED_ERROR_CODE
            : errorCode;
        setErrorMessage(errorMessageKey, errorMessage, 'phantom-redirect');
        logger.logVerboseTroubleshootingMessage('[PhantomRedirect handleErrorResponse] consumed method, emitting error', { errorCode, errorMessage, method });
        switch (method) {
            case 'signAndSendTransaction':
                phantomRedirectConnector.emit('signAndSendTransaction', {
                    errorCode,
                    errorMessage,
                });
                break;
            case 'signAllTransactions':
                phantomRedirectConnector.emit('signAllTransactions', {
                    errorCode,
                    errorMessage,
                });
                break;
            case 'signTransaction':
                phantomRedirectConnector.emit('signTransaction', {
                    errorCode,
                    errorMessage,
                });
                break;
            case 'signMessage':
                phantomRedirectConnector.emit('signMessage', {
                    errorCode,
                    errorMessage,
                });
                break;
        }
    }, [phantomRedirectConnector, setErrorMessage]);
    return {
        handleConnectResponse,
        handleErrorResponse,
        handleUserResponse,
        phantomRedirectConnector,
    };
};

export { useResponseHandlers };
