var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { useMemo } from 'react';
import { Route } from 'react-router-dom';
import { useTheme } from '../utilities/theme';
import { useTranslation } from 'react-i18next';
import { InteractionType, InteractionStatus } from '@azure/msal-browser';
import { MsalAuthenticationTemplate, useMsal } from '@azure/msal-react';
import { useIsUnityAuthenticated } from '../utilities/auth/useIsUnityAuthenticated';
import { useUser } from '../utilities/auth/useUser';
import { PageForbiddenRoute } from './components/PageForbiddenRoute';
import { useMenuContext } from '../utilities/menus/MenuProvider';
import { useRegisterRoute } from './useRegisterRoute';
import { LoadingIndicator } from '../UI/loading/LoadingIndicator';
import { PasswordResetRedirect } from './components/PasswordResetRedirect';
import { getLoginRequest } from '../utilities/auth/signInAuthProvider';
import { useTenant } from '../utilities/tenant';
import { storeRedirectPath } from '../utilities/redirect/LocalRedirectUrlStorage';
export const PrivateRoute = (_a) => {
    var _b, _c, _d;
    var _e, _f, _g;
    var { rolesMap: propRolesMap, menuActiveMap: propMenuActiveMap } = _a, routeProps = __rest(_a, ["rolesMap", "menuActiveMap"]);
    const location = useRegisterRoute({ isPublic: false });
    const isAuthenticated = useIsUnityAuthenticated();
    const { inProgress } = useMsal();
    const user = useUser();
    const tenant = useTenant();
    const theme = useTheme();
    const { t } = useTranslation();
    const menuContext = useMenuContext === null || useMenuContext === void 0 ? void 0 : useMenuContext();
    const rolesMap = (_e = menuContext === null || menuContext === void 0 ? void 0 : menuContext.rolesMap) !== null && _e !== void 0 ? _e : propRolesMap;
    const menuActiveMap = (_f = menuContext === null || menuContext === void 0 ? void 0 : menuContext.menuActiveMap) !== null && _f !== void 0 ? _f : propMenuActiveMap;
    const userRoles = useMemo(() => {
        return Array.isArray(user === null || user === void 0 ? void 0 : user.roles)
            ? user.roles.map((role) => role.roleId).filter(Boolean)
            : [];
    }, [user === null || user === void 0 ? void 0 : user.roles]);
    const userHasRoles = useMemo(() => {
        var _a, _b;
        if ((rolesMap === null || rolesMap === void 0 ? void 0 : rolesMap.size) > 0) {
            if (!rolesMap.has((_a = routeProps.location) === null || _a === void 0 ? void 0 : _a.pathname)) {
                return false;
            }
            const routeRoles = rolesMap.get((_b = routeProps.location) === null || _b === void 0 ? void 0 : _b.pathname);
            if (!(routeRoles === null || routeRoles === void 0 ? void 0 : routeRoles.length)) {
                return true;
            }
            return routeRoles.some((element) => userRoles.includes(element));
        }
        return true;
    }, [userRoles, rolesMap, (_b = routeProps.location) === null || _b === void 0 ? void 0 : _b.pathname]);
    const menuIsActive = useMemo(() => {
        var _a, _b;
        if ((menuActiveMap === null || menuActiveMap === void 0 ? void 0 : menuActiveMap.size) > 0 &&
            menuActiveMap.has((_a = routeProps.location) === null || _a === void 0 ? void 0 : _a.pathname)) {
            return menuActiveMap.get((_b = routeProps.location) === null || _b === void 0 ? void 0 : _b.pathname);
        }
    }, [menuActiveMap, (_c = routeProps.location) === null || _c === void 0 ? void 0 : _c.pathname]);
    const activeTenant = (_g = tenant === null || tenant === void 0 ? void 0 : tenant.activeTenant) !== null && _g !== void 0 ? _g : null;
    const isUserInitialized = Boolean(user === null || user === void 0 ? void 0 : user.userId);
    const isTenantInitialized = Boolean(activeTenant === null || activeTenant === void 0 ? void 0 : activeTenant.tenantId);
    const isThemeInitialized = Boolean(theme === null || theme === void 0 ? void 0 : theme.isInitialized);
    const shouldWaitForProtectedContext = isAuthenticated && (!isUserInitialized || !isTenantInitialized);
    const shouldWaitForTheme = isAuthenticated && !isThemeInitialized;
    if (shouldWaitForProtectedContext || shouldWaitForTheme) {
        return React.createElement(LoadingIndicator, null);
    }
    if (!isAuthenticated) {
        // Prevent login redirect loops while MSAL is still processing the redirect response.
        if (inProgress === InteractionStatus.Startup || inProgress === InteractionStatus.HandleRedirect) {
            return React.createElement(LoadingIndicator, null);
        }
        if (inProgress !== InteractionStatus.None) {
            return React.createElement(LoadingIndicator, null);
        }
        storeRedirectPath(location.pathname, location.search);
        let loginRequest = null;
        try {
            loginRequest = getLoginRequest();
        }
        catch (_h) {
            loginRequest = null;
        }
        if (!loginRequest) {
            return React.createElement(LoadingIndicator, null);
        }
        return (React.createElement(MsalAuthenticationTemplate, { interactionType: InteractionType.Redirect, authenticationRequest: loginRequest, loadingComponent: () => React.createElement(LoadingIndicator, null), errorComponent: (props) => {
                var _a, _b;
                var _c;
                if (inProgress !== InteractionStatus.None) {
                    return React.createElement(LoadingIndicator, null);
                }
                const hasMsalError = Boolean((_a = props === null || props === void 0 ? void 0 : props.error) === null || _a === void 0 ? void 0 : _a.errorMessage) ||
                    /(^|&)(error|error_description)=/.test((_c = (_b = window.location.hash) === null || _b === void 0 ? void 0 : _b.replace(/^#/, '')) !== null && _c !== void 0 ? _c : '');
                if (!hasMsalError) {
                    return React.createElement(LoadingIndicator, null);
                }
                return React.createElement(PasswordResetRedirect, Object.assign({}, props));
            } }, React.createElement(Route, Object.assign({}, routeProps))));
    }
    if ((rolesMap === null || rolesMap === void 0 ? void 0 : rolesMap.has((_d = routeProps.location) === null || _d === void 0 ? void 0 : _d.pathname)) && !menuIsActive) {
        return (React.createElement(Route, { path: "*", render: () => (React.createElement(PageForbiddenRoute, { message: t('Trying to access inactive menu. Please check your menu configurations'), showButton: false })) }));
    }
    if (!(user === null || user === void 0 ? void 0 : user.isUnitySystemAdmin) && (rolesMap === null || rolesMap === void 0 ? void 0 : rolesMap.size) > 0 && !userHasRoles) {
        return (React.createElement(Route, { path: "*", render: () => (React.createElement(PageForbiddenRoute, { message: t('You do not have the required roles to access this page. Please contact an administrator to get access'), showButton: false })) }));
    }
    if (isUserInitialized) {
        return React.createElement(Route, Object.assign({}, routeProps));
    }
    return React.createElement(LoadingIndicator, null);
};
//# sourceMappingURL=PrivateRoute.js.map