import React, { lazy, Suspense, useCallback, useMemo, useEffect, useContext } from 'react';
import { useUser } from '../auth/useUser';
import { UserDispatchContext } from '../auth/internal';
import { useApiQuery } from '../useApiQuery';
import { TenantContext } from './tenantContext';
import { ConfigService } from '../../configService';
import { useAccount } from '@azure/msal-react';
import { MenuProvider } from '../menus/MenuProvider';
import { storeTenant } from '../storage/UnitySessionStorage';
import { TenantTypeEnums } from '../../enums/unitySystemEnums';
import { useTenantStore } from '../../stores/tenantStore';
import { useProductsStore } from '../../stores/productsStore';
import { LoadingIndicator } from '../../UI/loading/LoadingIndicator';
// Lazy-load the tenant dialogs — they render the stencil-based UdpDialog /
// UdpAutocomplete components which transitively pull in udp-fluent-icon
// (~574 KB), @fluentui/web-components, @microsoft/fast-element, etc. Tenant
// mismatch / no-tenants paths are rare, so this whole tree should only load
// when actually needed.
const TenantAccessDialog = lazy(() => import('./TenantAccessDialog').then((m) => ({ default: m.TenantAccessDialog })));
const UdpDialog = lazy(() => import('../../UI/fluent-web-components/UdpDialog').then((m) => ({ default: m.UdpDialog })));
const useTenantStoreSync = (activeTenant) => {
    const setCurrentTenant = useTenantStore((state) => state.setCurrentTenant);
    useEffect(() => {
        var _a, _b, _c, _d;
        if (!(activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantId))
            return;
        const current = useTenantStore.getState().currentTenant;
        const theme = (_a = activeTenant.theme) !== null && _a !== void 0 ? _a : null;
        const name = (_b = activeTenant.tenantName) !== null && _b !== void 0 ? _b : null;
        const tenantType = activeTenant.tenantType;
        if ((current === null || current === void 0 ? void 0 : current.tenantId) === activeTenant.tenantId &&
            (current === null || current === void 0 ? void 0 : current.tenantType) === tenantType &&
            ((_c = current === null || current === void 0 ? void 0 : current.name) !== null && _c !== void 0 ? _c : null) === name &&
            ((_d = current === null || current === void 0 ? void 0 : current.theme) !== null && _d !== void 0 ? _d : null) === theme) {
            return;
        }
        setCurrentTenant({
            tenantId: activeTenant.tenantId,
            name,
            tenantType,
            theme,
        });
    }, [
        activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantId,
        activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantName,
        activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantType,
        activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.theme,
        setCurrentTenant,
    ]);
};
export const TenantProvider = ({ children }) => {
    var _a;
    const user = useUser();
    const activeAccount = useAccount();
    const { changeTenant } = useContext(UserDispatchContext);
    const { data: tenants, isLoading: tenantsLoading, refetch: refresh, } = useApiQuery(ConfigService.securityV2ApiUrl, `user/tenants?productId=${ConfigService.config.UNITY_PRODUCT_ID}`, { skipTenantHeader: true }, {
        enabled: !!(activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.idTokenClaims),
    });
    const { data: selectedProduct, isLoading: productsLoading } = useApiQuery(ConfigService.tenantV2ApiUrl, `product/${ConfigService.config.UNITY_PRODUCT_ID}`, { skipTenantHeader: true }, {
        enabled: !!(activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.idToken),
    });
    const hasTenantsData = Array.isArray(tenants);
    const userHasLoaded = user && user.statusCode !== undefined;
    const activeTenant = (user === null || user === void 0 ? void 0 : user.currentTenantId) && hasTenantsData
        ? ((_a = tenants.find((t) => t.tenantId === user.currentTenantId)) !== null && _a !== void 0 ? _a : null)
        : null;
    const isProductTenant = (activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantType) === TenantTypeEnums.Product;
    useTenantStoreSync(activeTenant);
    if ((selectedProduct === null || selectedProduct === void 0 ? void 0 : selectedProduct.isUnityDefault) && (activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantId)) {
        useProductsStore.getState().fetchProducts(activeTenant.tenantId);
    }
    const handleTenantChange = useCallback((tenant) => {
        if (!tenant)
            return;
        storeTenant(tenant.tenantId);
        changeTenant(tenant.tenantId);
    }, [changeTenant]);
    // Hook moved BEFORE any early returns
    const contextValue = useMemo(() => ({
        tenantsList: tenants !== null && tenants !== void 0 ? tenants : null,
        filteredTenantsList: tenants !== null && tenants !== void 0 ? tenants : null,
        activeTenant,
        isProductTenant,
        refresh,
    }), [tenants, activeTenant, isProductTenant, refresh]);
    // Only block rendering on initial load — not on background refetches
    // when we already have data to display
    const shouldBlockForTenantData = Boolean(activeAccount) &&
        ((tenantsLoading && !tenants) || (productsLoading && !selectedProduct));
    if (shouldBlockForTenantData) {
        return React.createElement(LoadingIndicator, null);
    }
    const noTenantsAvailable = hasTenantsData && tenants.length === 0 && userHasLoaded;
    const currentTenantAllowed = hasTenantsData
        ? tenants.some((t) => t.tenantId === (user === null || user === void 0 ? void 0 : user.currentTenantId))
        : false;
    const shouldShowTenantMismatchDialog = userHasLoaded && hasTenantsData && !noTenantsAvailable && !currentTenantAllowed;
    if (noTenantsAvailable) {
        return (React.createElement(Suspense, { fallback: React.createElement(LoadingIndicator, null) }, React.createElement(UdpDialog, { open: true, dialogTitle: "No Access", type: "alert", showHeaderCloseButton: false }, "Your user does not have access to any tenants for this product. Please contact your suppor team")));
    }
    return (React.createElement(TenantContext.Provider, { value: contextValue }, React.createElement(MenuProvider, null, shouldShowTenantMismatchDialog && (React.createElement(Suspense, { fallback: React.createElement(LoadingIndicator, null) }, React.createElement(TenantAccessDialog, { open: shouldShowTenantMismatchDialog, tenants: tenants, onTenantChange: handleTenantChange, productName: selectedProduct === null || selectedProduct === void 0 ? void 0 : selectedProduct.productName }))), !shouldShowTenantMismatchDialog && children)));
};
//# sourceMappingURL=TenantProvider.js.map