import React, { lazy, Suspense, useCallback, useEffect, useState, useMemo } from 'react';
import { keepPreviousData } from '@tanstack/react-query';
import { UserContext, UserDispatchContext } from './internal';
import { User } from './user';
import { LoadingIndicator } from '../../UI/loading/LoadingIndicator';
import { useAccount } from '@azure/msal-react';
import { storeTenant, getStoredTenant } from '../storage/UnitySessionStorage';
import { useApiQuery } from '../useApiQuery';
import { TenantProvider } from '../tenant/TenantProvider';
import { ConfigService } from '../../configService';
import { getSignInAuthProvider } from './signInAuthProvider';
// Lazy-load the error modal — it only renders when the user-info API call
// fails, which is rare. Statically importing UdpDialog/UdpText/UdpButton drags
// the entire stencil web-component graph (incl. ~574 KB udp-fluent-icon) into
// the entry chunk for every user.
const UserErrorModal = lazy(() => import('./UserErrorModal'));
const UserProvider = (props) => {
    const { children, isWhiteListed, doNotWaitForTenant = false, unityTenantId } = props;
    const activeAccount = useAccount();
    const [activeTenantId, setActiveTenantId] = useState(() => {
        const params = new URLSearchParams(window.location.search);
        const urlTenant = params.get('tenantId');
        if (urlTenant)
            return urlTenant;
        const storedTenant = getStoredTenant();
        if (storedTenant)
            return storedTenant;
        return unityTenantId || null;
    });
    const unityUserUrl = activeTenantId
        ? `user/unityuser?tenantId=${encodeURIComponent(activeTenantId)}`
        : 'user/unityuser';
    const { data: userInfo, error: userError, isLoading: userInfoLoading, } = useApiQuery(ConfigService.securityV2ApiUrl, unityUserUrl, {}, {
        enabled: !!activeAccount,
        staleTime: 0,
        placeholderData: keepPreviousData,
    });
    const user = useMemo(() => (userInfo ? new User(userInfo) : null), [userInfo]);
    const isErrorModalOpen = Boolean(userError);
    const errorMessage = userError ? 'Unable to get user details. Please try again.' : '';
    useEffect(() => {
        if (user === null || user === void 0 ? void 0 : user.userId)
            sessionStorage.setItem('user-id', user.userId);
        if ((user === null || user === void 0 ? void 0 : user.currentTenantId) && !activeTenantId) {
            storeTenant(user.currentTenantId);
            setActiveTenantId(user.currentTenantId);
        }
    }, [user, activeTenantId]);
    const changeTenant = useCallback((newTenantId) => {
        if (!newTenantId)
            return;
        storeTenant(newTenantId);
        setActiveTenantId(newTenantId);
    }, []);
    // Only block on initial load — when switching tenants we keep the previous
    // user rendered (placeholderData) so children don't unmount and flash a loader.
    const loadingValue = Boolean(activeAccount) && !user && !userError && userInfoLoading;
    const shouldBlockForUser = loadingValue && !isWhiteListed;
    if (isErrorModalOpen) {
        return (React.createElement(Suspense, { fallback: React.createElement(LoadingIndicator, null) }, React.createElement(UserErrorModal, { errorMessage: errorMessage })));
    }
    if (!doNotWaitForTenant && shouldBlockForUser) {
        return React.createElement(LoadingIndicator, null);
    }
    return (React.createElement(UserContext.Provider, { value: user }, React.createElement(UserDispatchContext.Provider, { value: { changeTenant } }, React.createElement(TenantProvider, null, children))));
};
export default UserProvider;
//# sourceMappingURL=UserProvider.js.map