'use client'
import { __awaiter } from '../../../../_virtual/_tslib.js';
import { jsx, jsxs } from 'react/jsx-runtime';
import { useState, useMemo, useRef, useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import bs58 from 'bs58';
import { isAccountAbstractionConnector } from '@dynamic-labs/wallet-connector-core';
import { TransactionGasCannotBeSponsoredError } from '@dynamic-labs/utils';
import { ChainEnum } from '@dynamic-labs/sdk-api-core';
import '../../context/DynamicContext/DynamicContext.js';
import '../../store/state/loadingAndLifecycle/loadingAndLifecycle.js';
import '@dynamic-labs/iconic';
import '../../context/ViewContext/ViewContext.js';
import { logger } from '../../shared/logger.js';
import '@dynamic-labs/wallet-book';
import '../../utils/constants/colors.js';
import '../../utils/constants/values.js';
import '../../shared/consts/index.js';
import '../../events/dynamicEvents.js';
import '../../context/CaptchaContext/CaptchaContext.js';
import '../../context/ErrorContext/ErrorContext.js';
import '@dynamic-labs/multi-wallet';
import 'react-international-phone';
import '../../store/state/nonce/nonce.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 { simulateBlockaidUserOperation, simulateBlockaidSVMTransaction, simulateBlockaidEVMTransaction } from '../../data/api/transactions/blockaid.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 '../../context/VerificationContext/VerificationContext.js';
import 'react-dom';
import '../../utils/functions/compareChains/compareChains.js';
import '../Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js';
import '../../context/ThemeContext/ThemeContext.js';
import { useForceUpdate } from '../../utils/hooks/useForceUpdate/useForceUpdate.js';
import { useInterval } from '../../utils/hooks/useInterval/useInterval.js';
import '../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
import { useMutation } from '../../utils/hooks/useMutation/useMutation.js';
import { usePromise } from '../../utils/hooks/usePromise/usePromise.js';
import '@dynamic-labs/types';
import '../../context/SocialRedirectContext/SocialRedirectContext.js';
import '../../context/LoadingContext/LoadingContext.js';
import '../../context/WalletContext/WalletContext.js';
import '../../utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js';
import 'yup';
import '../../context/MockContext/MockContext.js';
import '../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 '../../components/Accordion/components/AccordionItem/AccordionItem.js';
import { Alert } from '../../components/Alert/Alert.js';
import { Typography } from '../../components/Typography/Typography.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 { useFetchCurrency } from '../../widgets/DynamicWidget/hooks/useFetchCurrency/useFetchCurrency.js';
import 'formik';
import '../../utils/hooks/useSubdomainCheck/useSubdomainCheck.js';
import { useEffectOnce } from '../../utils/hooks/useEffectOnce/useEffectOnce.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 '../ExchangeWhitelistWarning/ExchangeWhitelistWarning.js';
import '../../context/ErrorContext/hooks/useErrorText/useErrorText.js';
import '../../context/FooterAnimationContext/index.js';
import '../MfaChooseDeviceView/useGetMfaOptions/useGetMfaOptions.js';
import '../../context/PasskeyContext/PasskeyContext.js';
import '../../context/OnrampContext/OnrampContext.js';
import '../../store/state/sendBalances.js';
import { TransactionConfirmationPageLayout } from '../../components/TransactionConfirmationPageLayout/TransactionConfirmationPageLayout.js';
import '../../store/state/connectorsInitializing/connectorsInitializing.js';
import '../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.js';
import '../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.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';
import { useTransactionTotal } from './hooks/useTransactionTotal/useTransactionTotal.js';
import { transactionErrorMessage } from './helpers/transactionErrorMessage.js';

const FEE_REFRESH_INTERVAL = 20000;
var SimulationStatus;
(function (SimulationStatus) {
    SimulationStatus["LOADING"] = "loading";
    SimulationStatus["FAILED"] = "failed";
    SimulationStatus["SKIPPED"] = "skipped";
    SimulationStatus["SUCCESS"] = "success";
})(SimulationStatus || (SimulationStatus = {}));
const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation, onClickBack, walletConnector, onClickClose, title, displayPoweredByDynamicFooter = false, copykey, hideModal, currentToken, isNativeToken, transactionValue, isModal, sendBalanceTransaction, }) => {
    const { primaryWallet, environmentId } = useInternalDynamicContext();
    const [isGasSponsored, setIsGasSponsored] = useState(false);
    const [isGasSponsoredLoading, setIsGasSponsoredLoading] = useState(false);
    const update = useForceUpdate();
    const { t } = useTranslation();
    const { currency } = useFetchCurrency(walletConnector);
    // Update the chainId access to handle undefined case
    const chainId = useMemo(() => {
        if (!(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector)) {
            return undefined;
        }
        const connector = primaryWallet.connector;
        return connector._selectedChainId || connector.lastUsedChainId;
    }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector]);
    const [simulationState, setSimulationState] = useState({
        status: SimulationStatus.LOADING,
    });
    const [recipient, setRecipient] = useState(undefined);
    const isFetchingSimulationRef = useRef(false);
    const fetchSimulationResult = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        var _a, _b, _c, _d, _e, _f, _g;
        if (simulationState.status !== SimulationStatus.LOADING) {
            return;
        }
        if (isFetchingSimulationRef.current) {
            // Already fetching, prevent duplicate call
            return;
        }
        isFetchingSimulationRef.current = true;
        if (sendBalanceTransaction || hideModal) {
            setSimulationState({ status: SimulationStatus.SKIPPED });
            isFetchingSimulationRef.current = false;
            return;
        }
        if (!primaryWallet || (!chainId && (primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain) !== 'SOL')) {
            logger.error('[TransactionConfirmationView] Simulation failed:', {
                chain: primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain,
                chainId,
                primaryWallet,
            });
            setSimulationState({ status: SimulationStatus.FAILED });
            isFetchingSimulationRef.current = false;
            return;
        }
        try {
            let result;
            if (primaryWallet.connector.key === 'zerodev') {
                const connector = primaryWallet.connector;
                const { userOperation, sponsored } = yield connector.getCurrentUserOperation(transaction);
                setIsGasSponsored(sponsored);
                setIsGasSponsoredLoading(false);
                if (userOperation) {
                    const formattedUserOperation = yield connector.formatUserOperation(userOperation);
                    // Set the gas fee on the transaction, only for zero dev
                    transaction.fee.gas = calculateGasUnits(userOperation);
                    const entryPoint = yield ((_a = connector.getAccountAbstractionProvider()) === null || _a === void 0 ? void 0 : _a.account.entryPoint);
                    if (!entryPoint) {
                        logger.error('[TransactionConfirmationView] Simulation failed: No entry point address found');
                        setSimulationState({ status: SimulationStatus.FAILED });
                        return;
                    }
                    setRecipient((_b = transaction === null || transaction === void 0 ? void 0 : transaction.getTransactionRecipient) === null || _b === void 0 ? void 0 : _b.call(transaction));
                    result = yield simulateBlockaidUserOperation({
                        chainId: String(chainId),
                        entryPoint,
                        environmentId,
                        userOperation: formattedUserOperation,
                        value: ((_c = transaction.value) === null || _c === void 0 ? void 0 : _c.toString()) || '0',
                    });
                }
                else {
                    setSimulationState({ status: SimulationStatus.FAILED });
                    return;
                }
            }
            else {
                // Handle SOLANA
                if ((walletConnector === null || walletConnector === void 0 ? void 0 : walletConnector.connectedChain) === 'SOL') {
                    const encodedTransactions = (_d = transaction.multipleTransactions) === null || _d === void 0 ? void 0 : _d.map((tx) => bs58.encode(tx.serialize({ requireAllSignatures: false })));
                    if (!encodedTransactions) {
                        logger.error('[TransactionConfirmationView] Simulation failed: No encoded transactions');
                        setSimulationState({ status: SimulationStatus.FAILED });
                        return;
                    }
                    result = yield simulateBlockaidSVMTransaction({
                        accountAddress: transaction.from,
                        chain: (yield (walletConnector === null || walletConnector === void 0 ? void 0 : walletConnector.getNetwork(true))),
                        environmentId,
                        transactions: encodedTransactions,
                    });
                }
                else if ((walletConnector === null || walletConnector === void 0 ? void 0 : walletConnector.connectedChain) === 'EVM') {
                    setRecipient((_e = transaction === null || transaction === void 0 ? void 0 : transaction.getTransactionRecipient) === null || _e === void 0 ? void 0 : _e.call(transaction));
                    // EVM
                    result = yield simulateBlockaidEVMTransaction({
                        chainId: String(chainId),
                        data: transaction.data || '0x',
                        environmentId,
                        from: transaction.from,
                        to: transaction.to || '',
                        value: ((_f = transaction.value) === null || _f === void 0 ? void 0 : _f.toString()) || '0',
                    });
                }
            }
            if (!result && ((_g = primaryWallet.connector) === null || _g === void 0 ? void 0 : _g.key) !== 'zerodev') {
                logger.warn('[TransactionConfirmationView] Simulation failed: No result');
                setSimulationState({ status: SimulationStatus.FAILED });
                return;
            }
            setSimulationState(result
                ? { result, status: SimulationStatus.SUCCESS }
                : { status: SimulationStatus.FAILED });
        }
        catch (error) {
            logger.error('[TransactionConfirmationView] Simulation failed:', error);
            setSimulationState({ status: SimulationStatus.FAILED });
        }
        finally {
            isFetchingSimulationRef.current = false;
        }
    }), [
        sendBalanceTransaction,
        hideModal,
        primaryWallet,
        chainId,
        environmentId,
        transaction,
        walletConnector,
        simulationState.status,
        setSimulationState,
    ]);
    useEffect(() => {
        if (simulationState.status === SimulationStatus.SUCCESS ||
            simulationState.status === SimulationStatus.SKIPPED) {
            return;
        }
        fetchSimulationResult();
    }, [fetchSimulationResult, primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, simulationState.status]);
    /**
     * Update transaction fee and trigger a react update
     * to reflect the new fee on the UI
     */
    const fetchTransactionFee = useCallback(() => {
        var _a;
        if (((primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain) === ChainEnum.Sol &&
            transaction.fee.gas !== undefined) ||
            (primaryWallet && ((_a = primaryWallet.connector) === null || _a === void 0 ? void 0 : _a.key) === 'zerodev')) {
            return;
        }
        transaction.fetchFee().finally(update);
    }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain, transaction, update]);
    useEffect(() => {
        var _a;
        // solana gas sponsorship check
        if ((_a = transaction.isGasSponsored) === null || _a === void 0 ? void 0 : _a.call(transaction)) {
            setIsGasSponsored(true);
        }
    }, [transaction]);
    const { mutate: send, isLoading, error: transactionError, } = useMutation(mutation, {
        onFailure: useCallback((error) => {
            fetchTransactionFee();
            if (TransactionGasCannotBeSponsoredError.isInstance(error)) {
                logger.debug(error);
                setIsGasSponsored(false);
                if (isAccountAbstractionConnector(walletConnector)) {
                    walletConnector.disableGasSponsorshipOnce();
                }
            }
            logger.error(error);
            onError === null || onError === void 0 ? void 0 : onError(error);
        }, [fetchTransactionFee, onError, walletConnector]),
        onSuccess: useCallback((tx) => onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(tx), [onSuccess]),
    });
    // Refresh transaction fee, Solana fees are static based on transaction data, dont need to refresh them
    useInterval(fetchTransactionFee, isLoading ? null : FEE_REFRESH_INTERVAL);
    useEffectOnce(fetchTransactionFee);
    const total = useTransactionTotal({
        gasTotalPrice: transaction.fee.gas,
        isGasSponsored,
        transactionValue: transaction.value,
    });
    const errorMessage = transactionError && transactionErrorMessage(transactionError);
    const { data: balance, isLoading: isBalanceLoading } = usePromise(() => transaction.getBalance());
    const hasInsufficientFunds = useMemo(() => {
        if (total === undefined || balance === undefined)
            return false;
        return balance < total;
    }, [balance, total]);
    const missingFunds = useMemo(() => {
        if (total === undefined || balance === undefined)
            return undefined;
        return total - balance;
    }, [total, balance]);
    const alert = useMemo(() => {
        if (errorMessage)
            return null;
        // Check for gas sponsorship errors
        if (TransactionGasCannotBeSponsoredError.isInstance(transactionError)) {
            return (jsx(Alert, { icon: 'error', variant: 'error', copykey: 'dyn_send_transaction.error_message.gas_not_sponsored', children: t('dyn_send_transaction.error_message.gas_not_sponsored') }));
        }
        // Check for insufficient gas funds
        if (!isGasSponsoredLoading &&
            !isBalanceLoading &&
            missingFunds === undefined &&
            transaction.fee.gas &&
            !isGasSponsored) {
            return (jsx(Alert, { icon: 'error', variant: 'warning', copykey: 'dyn_send_transaction.warning_message.insufficient_gas_funds', children: jsxs(Typography, { variant: 'body_small', color: 'current-color', "data-testid": 'warning_content', children: [jsx(Typography, { variant: 'body_normal', color: 'primary', copykey: 'dyn_send_transaction.warning_message.insufficient_gas_funds.title', children: t('dyn_send_transaction.warning_message.insufficient_gas_funds.title') }), jsx(Typography, { variant: 'body_normal', color: 'secondary', copykey: 'dyn_send_transaction.warning_message.insufficient_gas_funds.description', children: t('dyn_send_transaction.warning_message.insufficient_gas_funds.description', {
                                amountLeft: transaction.format(transaction.fee.gas, {
                                    precision: 6,
                                }),
                                currencySymbol: currency === null || currency === void 0 ? void 0 : currency.symbol,
                            }) })] }) }));
        }
        // Check for insufficient funds
        const showInsufficientFundsWarningMessage = hasInsufficientFunds && missingFunds;
        if (showInsufficientFundsWarningMessage) {
            const amountLeft = transaction.format(missingFunds, { precision: 6 });
            return (jsx(Alert, { icon: 'error', variant: 'error', copykey: 'dyn_send_transaction.warning_message.insufficient_funds', children: jsxs(Typography, { variant: 'body_small', color: 'current-color', "data-testid": 'warning_content', children: [jsx(Typography, { variant: 'body_normal', color: 'primary', copykey: 'dyn_send_transaction.warning_message.insufficient_funds.title', children: t('dyn_send_transaction.warning_message.insufficient_funds.title') }), jsx(Typography, { variant: 'body_normal', color: 'secondary', copykey: 'dyn_send_transaction.warning_message.insufficient_funds.description', children: t('dyn_send_transaction.warning_message.insufficient_funds.description', {
                                amountLeft,
                                currencySymbol: currency === null || currency === void 0 ? void 0 : currency.symbol,
                            }) })] }) }));
        }
        // Finally, check for simulation failure
        if (simulationState.status === SimulationStatus.FAILED) {
            return (jsx(Alert, { icon: 'error', variant: 'warning', copykey: 'dyn_send_transaction.warning_message.failed_simulation', children: jsxs(Typography, { variant: 'body_small', color: 'current-color', "data-testid": 'warning_content', children: [jsx(Typography, { variant: 'body_normal', color: 'primary', copykey: 'dyn_send_transaction.warning_message.failed_simulation.title', as: 'div', children: t('dyn_send_transaction.warning_message.failed_simulation.title') }), jsx(Typography, { variant: 'body_normal', color: 'secondary', copykey: 'dyn_send_transaction.warning_message.failed_simulation.description', as: 'div', children: t('dyn_send_transaction.warning_message.failed_simulation.description') })] }) }));
        }
        return null;
    }, [
        simulationState.status,
        errorMessage,
        transactionError,
        isGasSponsoredLoading,
        isBalanceLoading,
        missingFunds,
        transaction,
        isGasSponsored,
        hasInsufficientFunds,
        t,
        currency === null || currency === void 0 ? void 0 : currency.symbol,
    ]);
    useEffect(() => {
        var _a, _b;
        if (simulationState.status === SimulationStatus.SUCCESS &&
            !sendBalanceTransaction) {
            if (((_a = simulationState.result) === null || _a === void 0 ? void 0 : _a.outAssets.length) === 0 &&
                !chainId &&
                !((_b = transaction.isGasSponsored) === null || _b === void 0 ? void 0 : _b.call(transaction))) {
                // set failed but keep the result so that we have the native price
                setSimulationState({
                    result: simulationState.result,
                    status: SimulationStatus.FAILED,
                });
            }
        }
    }, [simulationState, chainId, transaction, sendBalanceTransaction]);
    const layoutProps = useMemo(() => {
        var _a;
        return ({
            alert,
            copykey,
            currentToken,
            disableSendButton: isBalanceLoading,
            displayPoweredByDynamicFooter,
            error: errorMessage,
            hideModal,
            isGasSponsored,
            isGasSponsoredLoading,
            isLoading,
            isNativeToken,
            onClickBack,
            onClickClose,
            onClickSend: () => send(),
            onSuccess: (tx) => onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(tx),
            recipient,
            sendBalanceTransaction,
            simulationResult: (_a = simulationState.result) !== null && _a !== void 0 ? _a : undefined,
            title,
            total,
            transaction,
            transactionValue,
            walletConnector,
            walletKey: (primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.key) || '',
        });
    }, [
        total,
        recipient,
        currentToken,
        transactionValue,
        isNativeToken,
        onClickBack,
        onClickClose,
        copykey,
        title,
        hideModal,
        isLoading,
        send,
        onSuccess,
        displayPoweredByDynamicFooter,
        isBalanceLoading,
        errorMessage,
        alert,
        walletConnector,
        transaction,
        isGasSponsored,
        isGasSponsoredLoading,
        primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.key,
        simulationState.result,
        sendBalanceTransaction,
    ]);
    return simulationState.status === SimulationStatus.LOADING ? null : (jsx(TransactionConfirmationPageLayout, Object.assign({}, layoutProps)));
};
const calculateGasUnits = (userOp) => {
    // Sum all gas units
    const totalGasUnits = BigInt(userOp.callGasLimit || 0) +
        BigInt(userOp.verificationGasLimit || 0) +
        BigInt(userOp.preVerificationGas || 0);
    // Multiply by maxFeePerGas to get the total gas cost in wei
    const gasCost = totalGasUnits * BigInt(userOp.maxFeePerGas || 0);
    return gasCost;
};

export { FEE_REFRESH_INTERVAL, TransactionConfirmationView };
