import { PublicClientApplication, EventType } from '@azure/msal-browser';
import { ConfigService } from '../../configService';
/** @type {import('@azure/msal-browser').PublicClientApplication | null} */
let signInAuthProviderInstance = null;
/** @type {import('@azure/msal-browser').RedirectRequest | null} */
let loginRequestInstance = null;
/** @type {import('@azure/msal-browser').SilentRequest | null} */
let tokenRequestInstance = null;
/** @type {string | null} */
let apiAccessScopeValue = null;
/**
 * Initializes the MSAL auth provider and request templates.
 * @returns {Promise<void>}
 */
export async function initSignInAuthProvider() {
    var _a;
    if (signInAuthProviderInstance) {
        return; // Already initialized
    }
    const PUBLIC_URL = new URL(import.meta.env.BASE_URL || '/', window.location.origin).href.replace(/\/$/, '');
    const REDIRECT_URL_BASE = ConfigService.config.USE_AAD_REDIRECT
        ? ConfigService.config.UNITY_URL
        : PUBLIC_URL;
    if (!ConfigService.config.MSAL_TENANT)
        throw new Error('MSAL_TENANT not configured');
    if (!ConfigService.config.MSAL_CLIENT_ID)
        throw new Error('MSAL_CLIENT_ID not configured');
    const tenant = ConfigService.config.MSAL_TENANT;
    // Determine idp_target and id_token_hint for Unified Policy
    const currentPath = window.location.pathname;
    const searchParams = new URLSearchParams(window.location.search);
    let domainHint = searchParams.get('domain_hint');
    if (currentPath === '/sso/entra') {
        domainHint = 'entra';
    }
    if (currentPath === '/sso/entra') {
        domainHint = 'entra';
        window.history.replaceState(null, '', '/');
    }
    const idTokenHint = searchParams.get('id_token_hint');
    const signInPolicy = ConfigService.config.SIGN_IN_POLICY;
    const applicationID = ConfigService.config.MSAL_CLIENT_ID;
    const reactRedirectUri = `${REDIRECT_URL_BASE}/${ConfigService.config.USE_AAD_REDIRECT ? 'aad_redirect' : 'aad_callback'}`;
    const tenantSubdomain = tenant.split('.')[0];
    const instance = `https://${tenantSubdomain}.b2clogin.com/`;
    const signInAuthority = `${instance}${tenant}/${signInPolicy}`;
    apiAccessScopeValue = `https://${tenant}/${ConfigService.config.MSAL_API_ACCESS_SCOPE}`;
    const ua = window.navigator.userAgent;
    const msie = ua.indexOf('MSIE ');
    const msie11 = ua.indexOf('Trident/');
    const msedge = ua.indexOf('Edge/');
    const firefox = ua.indexOf('Firefox');
    const isIE = msie > 0 || msie11 > 0;
    const isEdge = msedge > 0;
    const isFirefox = firefox > 0; // Only needed if you need to support the redirect flow in Firefox incognito
    // Msal Configurations
    const signInConfig = {
        auth: {
            authority: signInAuthority,
            knownAuthorities: [`${tenantSubdomain}.b2clogin.com`],
            clientId: applicationID,
            redirectUri: reactRedirectUri,
            postLogoutRedirectUri: PUBLIC_URL + '/',
            navigateToLoginRequestUrl: false,
        },
        cache: {
            cacheLocation: 'sessionStorage',
            storeAuthStateInCookie: isIE || isEdge || isFirefox,
        },
        system: {
            allowRedirectInIframe: true,
        },
    };
    signInAuthProviderInstance = new PublicClientApplication(signInConfig);
    await signInAuthProviderInstance.initialize();
    if (!signInAuthProviderInstance.getActiveAccount() &&
        signInAuthProviderInstance.getAllAccounts().length > 0) {
        signInAuthProviderInstance.setActiveAccount(signInAuthProviderInstance.getAllAccounts()[0]);
    }
    // Check if the active account is an Entra account to set the hint
    const activeAccount = signInAuthProviderInstance.getActiveAccount();
    if (activeAccount && !domainHint) {
        const idp = (_a = activeAccount.idTokenClaims) === null || _a === void 0 ? void 0 : _a.idp;
        if (idp && idp.includes('login.microsoftonline.com')) {
            domainHint = 'entra';
        }
    }
    signInAuthProviderInstance.addEventCallback((event) => {
        if (event.eventType === EventType.LOGIN_SUCCESS && event.payload.account) {
            const account = event.payload.account;
            signInAuthProviderInstance.setActiveAccount(account);
        }
    });
    tokenRequestInstance = { scopes: [apiAccessScopeValue] };
    loginRequestInstance = {
        scopes: [apiAccessScopeValue, 'openid', 'offline_access'],
        state: `${PUBLIC_URL}/aad_callback`,
        extraQueryParameters: Object.assign(Object.assign({}, (idTokenHint && { id_token_hint: idTokenHint, flow: 'redeem' })), (domainHint && !idTokenHint && { domain_hint: 'entra' })),
    };
}
export const getSignInAuthProvider = () => {
    if (!signInAuthProviderInstance) {
        throw new Error('signInAuthProvider is not initialized. Call initSignInAuthProvider first.');
    }
    return signInAuthProviderInstance;
};
/**
 * @returns {import('@azure/msal-browser').RedirectRequest}
 */
export const getLoginRequest = () => {
    if (!loginRequestInstance) {
        throw new Error('loginRequest is not initialized. Call initSignInAuthProvider first.');
    }
    return loginRequestInstance;
};
/**
 * @returns {import('@azure/msal-browser').SilentRequest}
 */
export const getTokenRequest = () => {
    if (!tokenRequestInstance) {
        throw new Error('tokenRequest is not initialized. Call initSignInAuthProvider first.');
    }
    return tokenRequestInstance;
};
export const getApiAccessScope = () => {
    if (!apiAccessScopeValue) {
        throw new Error('apiAccessScope is not initialized. Call initSignInAuthProvider first.');
    }
    return apiAccessScopeValue;
};
//# sourceMappingURL=signInAuthProvider.js.map