'use client'
import { __awaiter } from '../../../../../_virtual/_tslib.js';
import { useMemo, useCallback, useEffect } from 'react';
import '@dynamic-labs-sdk/client/core';
import '@dynamic-labs/sdk-api-core';
import '../../../client/client.js';
import '@dynamic-labs-sdk/client';
import '../../../config/ApiEndpoint.js';
import '@dynamic-labs/iconic';
import '@dynamic-labs/wallet-connector-core';
import 'react/jsx-runtime';
import '../../../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 { USER_NOT_LOGGED_IN } from '../../constants/errors.js';
import '@dynamic-labs/multi-wallet';
import 'react-international-phone';
import '../../../store/state/nonce/nonce.js';
import { logResponseError } from '../../../data/api/utils.js';
import '@dynamic-labs/locale';
import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
import '../../../store/state/primaryWalletId/primaryWalletId.js';
import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
import '../../../events/dynamicEvents.js';
import { getUserProfile } from '../../../client/extension/user/getUserProfile/getUserProfile.js';
import { getProjectSettings } from '../../../client/extension/projectSettings/getProjectSettings/getProjectSettings.js';
import { getAuthMode } from '../../../store/state/authMode/authMode.js';
import { useMultichainTokenBalancesState, setMultichainTokenBalanceVariable } from '../../../store/state/multichainBalances.js';
import { useGetMultichainTokenBalances } from '../useGetMultichainTokenBalances/useGetMultichainTokenBalances.js';

// Hook to fetch multichain token balances with caching to reduce re-querying
const useMultichainTokenBalances = (props) => {
    const { requests, forceRefresh = false, filterSpamTokens = true } = props;
    const multichainTokenBalancesState = useMultichainTokenBalancesState();
    const getMultichainTokenBalances = useGetMultichainTokenBalances();
    const { multichainTokenBalances, isLoading, error, requestsKey } = multichainTokenBalancesState;
    // Create a stable key for the current request to avoid unnecessary re-fetching
    const currentRequestsKey = useMemo(() => {
        if (!requests || requests.length === 0)
            return '';
        return JSON.stringify(requests
            .map(({ chain, address, networkIds }) => ({
            address,
            chain,
            networkIds: [...networkIds].sort((a, b) => a - b),
        }))
            .sort((a, b) => a.address.localeCompare(b.address)));
    }, [requests]);
    // Helper function to check if user is authorized to fetch balances
    const checkAuthorization = useCallback(() => {
        var _a;
        const user = getUserProfile();
        const authMode = getAuthMode();
        if (authMode !== 'connect-only' && !user) {
            setMultichainTokenBalanceVariable('error', USER_NOT_LOGGED_IN);
            return false;
        }
        const projectSettings = getProjectSettings();
        if (authMode === 'connect-only' &&
            !((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.featureFlags) === null || _a === void 0 ? void 0 : _a.connectOnlyMultiAsset)) {
            return false;
        }
        return true;
    }, []);
    // Helper function to check if we can use cached data
    const canUseCachedData = useCallback((shouldForceRefresh) => !shouldForceRefresh &&
        !forceRefresh &&
        requestsKey === currentRequestsKey &&
        Boolean(multichainTokenBalances) &&
        !isLoading, [
        forceRefresh,
        requestsKey,
        currentRequestsKey,
        multichainTokenBalances,
        isLoading,
    ]);
    // Helper function to validate requests
    const validateRequests = useCallback(() => {
        if (!requests || requests.length === 0) {
            setMultichainTokenBalanceVariable('multichainTokenBalances', undefined);
            setMultichainTokenBalanceVariable('requestsKey', undefined);
            return false;
        }
        const isValidRequest = requests.every((request) => request.address &&
            request.chain &&
            request.networkIds &&
            request.networkIds.length > 0);
        if (isLoading || !isValidRequest) {
            setMultichainTokenBalanceVariable('multichainTokenBalances', undefined);
            setMultichainTokenBalanceVariable('requestsKey', undefined);
            return false;
        }
        return true;
    }, [requests, isLoading]);
    // Helper function to get error message from exception
    const getErrorMessage = useCallback((error) => {
        if ((error === null || error === void 0 ? void 0 : error.code) === 429) {
            return 'Too many requests fetching multichain balances';
        }
        if (error === null || error === void 0 ? void 0 : error.message) {
            return error.message;
        }
        return 'error fetching multichain token balances';
    }, []);
    const fetchMultichainBalances = useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* (shouldForceRefresh = false) {
        // Check authorization
        if (!checkAuthorization()) {
            return;
        }
        // Check if we can use cached data
        if (canUseCachedData(shouldForceRefresh)) {
            logger.logVerboseTroubleshootingMessage('[useMultichainTokenBalances] using cached data', { currentRequestsKey, requestsKey });
            return;
        }
        // Validate requests
        if (!validateRequests()) {
            return;
        }
        logger.logVerboseTroubleshootingMessage('[useMultichainTokenBalances] will try to fetch multichain token balances', { isLoading, requests });
        setMultichainTokenBalanceVariable('isLoading', true);
        try {
            const response = yield getMultichainTokenBalances({
                balanceRequests: requests,
                filterSpamTokens,
            });
            if (!response) {
                setMultichainTokenBalanceVariable('error', 'No multichain token balances found');
                return;
            }
            setMultichainTokenBalanceVariable('error', undefined);
            setMultichainTokenBalanceVariable('multichainTokenBalances', response);
            setMultichainTokenBalanceVariable('requestsKey', currentRequestsKey);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
        }
        catch (e) {
            const logLevel = (e === null || e === void 0 ? void 0 : e.code) >= 500 || (e === null || e === void 0 ? void 0 : e.code) < 400 ? 'error' : 'warn';
            yield logResponseError(e, 'Error getting multichain token balances', logLevel);
            const errorMessage = getErrorMessage(e);
            setMultichainTokenBalanceVariable('error', errorMessage);
        }
        finally {
            setMultichainTokenBalanceVariable('isLoading', false);
        }
    }), [
        checkAuthorization,
        canUseCachedData,
        validateRequests,
        getErrorMessage,
        getMultichainTokenBalances,
        requests,
        currentRequestsKey,
        requestsKey,
        isLoading,
    ]);
    // Only fetch when the requests key changes to prevent unnecessary re-fetching
    useEffect(() => {
        if (currentRequestsKey && requestsKey !== currentRequestsKey) {
            fetchMultichainBalances();
        }
        // Removed fetchMultichainBalances from the dependency array to prevent unnecessary re-fetching (infinite loop)
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [currentRequestsKey, requestsKey]);
    return {
        error,
        fetchMultichainBalances,
        isError: Boolean(error),
        isLoading,
        multichainTokenBalances,
    };
};

export { useMultichainTokenBalances };
