class TokenHandlerMsal {
    loginAuthScopes = '';
    sessionId = '';
    SPHostUrl = '';
    sessionStorageKey = "";
    userLoginName = "";
    SPLanguage = "";
    tokenExpiryDateKey = "";
    SPClientTag = "";
    SPProductNumber = "";
    myMSALObj = {};
    loginRequest = {
        scopes: [],
    };
    queryString = '';
    constructor(loginAuthScopes, SPHostUrl, sessionId, userLoginName, SPLanguage, SPClientTag, SPProductNumber, myMSALObj) {

        this.loginAuthScopes = loginAuthScopes;
        this.sessionId = sessionId;
        this.SPHostUrl = SPHostUrl;
        this.sessionStorageKey = "wzTokenValidTo." + SPHostUrl + "." + sessionId;
        this.SPLanguage = SPLanguage;
        this.SPClientTag = SPClientTag;
        this.SPProductNumber = SPProductNumber;
        this.myMSALObj = myMSALObj;

        this.userLoginName = "";
        this.requestedUserLoginName = userLoginName;
        this.tokenExpiryDateKey = "wzMsalTokenExpiryDateKey";
        this.buildQueryString();
    }

    buildQueryString() {
        this.queryString = "?SPHostUrl=" + this.SPHostUrl + "&userLoginName=" + this.userLoginName + "&SPLanguage=" + this.SPLanguage + "&SPClientTag=" + this.SPClientTag;
    }

    isPopupEnabled() {
        let urlpopup = "_blank";
        var newWin = window.open(urlpopup, "popup");

        if (!newWin || newWin.closed || typeof newWin.closed == 'undefined') {
            //alert("popup blocked");
            return false;
        }
        newWin.close();
        return true;
    }

    getTokenFromParent() {
        return new Promise((resolve, reject) => {
            const messageHandler = (event) => {
                if (event.data && event.data.type === "STORAGE_RESPONSE") {
                    window.removeEventListener('message', messageHandler);
                    resolve(event.data.value);
                }
            };
            window.addEventListener('message', messageHandler);
            try {
                window.parent.postMessage({ type: 'MSTeams.GetWizdomAccessToken' }, '*');

            } catch (e) {
                window.removeEventListener('message', messageHandler);
                reject(e);
            }
            setTimeout(() => {
                window.removeEventListener('message', messageHandler);
                reject(new Error('Timeout waiting for token from parent'));
            }, 10000);
        });
    }

    async msalGenerateToken(forceRenewContext = false) {
        if (navigator.userAgent.indexOf('Teams') > -1) {
            try {
                const accessToken = await this.getTokenFromParent();
                return accessToken;
            } catch (e) {
                console.warn('Failed to get token from parent window', e);
            }
        }

        await this.myMSALObj.initialize();
        this.loginRequest.scopes = this.loginAuthScopes;

        let account = this.myMSALObj.getActiveAccount();
        let accounts = this.myMSALObj.getAllAccounts();

        let existingLoginName = window["wizdomLoginName"] ? window["wizdomLoginName"] : localStorage.getItem("wizdomLoginName");

        if (this.requestedUserLoginName && this.requestedUserLoginName != "undefined" && existingLoginName && this.requestedUserLoginName.toLowerCase() != existingLoginName.toLowerCase()) {
            forceRenewContext = true;
            localStorage.removeItem(this.tokenExpiryDateKey);
            localStorage.removeItem('WizdomAccessToken');
            localStorage.removeItem('wizdomLoginName');
            localStorage.removeItem('wizdomDisplayName');
            if (account || accounts.length > 0) {
                this.myMSALObj.clearCache({ account: account || accounts[0] });
                account = null;
                accounts = [];
            }
        }

        if (!forceRenewContext) {
            let valToken = this.validateToken();
            if (valToken.IsTokenValid) {
                window["wizdomLoginName"] = window["wizdomLoginName"] ? window["wizdomLoginName"] : localStorage.getItem("wizdomLoginName");
                return localStorage.getItem('WizdomAccessToken');
            }
        }

        if (account || accounts.length > 0) {
            this.loginRequest.account = account || accounts[0];
        }

        let tokenResponse;
        try {
            tokenResponse = await this.myMSALObj.acquireTokenSilent(this.loginRequest);
        } catch (error) {
            if (error.errorCode === "interaction_in_progress") {
                // Clear stale interaction status only when we know no real interaction is in progress
                sessionStorage.removeItem('msal.interaction.status');
            }
            tokenResponse = await this.myMSALObj.acquireTokenPopup(this.loginRequest);
            this.myMSALObj.setActiveAccount(tokenResponse.account);
        }

        localStorage.setItem('WizdomAccessToken', tokenResponse.accessToken);
        localStorage.setItem(this.tokenExpiryDateKey, tokenResponse.expiresOn);
        localStorage.setItem("wizdomLoginName", tokenResponse.account.username);
        localStorage.setItem("wizdomDisplayName", tokenResponse.account.name);
        this.userLoginName = tokenResponse.account.username;
        window.loginName = tokenResponse.account.username;
        window.localStorage.setItem("wizLoginName", this.userLoginName);
        window["wizdomLoginName"] = tokenResponse.account.username;
        return tokenResponse.accessToken;
    }


    validateToken() {
        const accessToken = localStorage.getItem('WizdomAccessToken');
        const expiry = localStorage.getItem(this.tokenExpiryDateKey);

        if (!accessToken || !expiry) {
            return { IsTokenValid: false, ValidTo: null, sessionId: this.sessionId };
        }

        const expiryDate = new Date(expiry);
        const now = new Date();

        const isValid = expiryDate > now;

        return {
            IsTokenValid: isValid,
            ValidTo: expiryDate,
            sessionId: this.sessionId
        };
    }
    async createContextToken(token) {
        try {
            var urlCreateContext = window.location.origin + '/Base/WizdomCorsProxy.aspx/CreateContextWithToken' + this.queryString;
            var responseCreateContext = await fetch(urlCreateContext, {
                method: "POST", // *GET, POST, PUT, DELETE, etc.
                mode: "cors", // no-cors, *cors, same-origin
                cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
                credentials: "same-origin", // include, *same-origin, omit
                headers: {
                    "Content-Type": "application/json; charset=utf-8",
                    "LTToken": token,
                    "SPProductNumber": this.SPProductNumber,
                    "sessionId": this.sessionId
                    // 'Content-Type': 'application/x-www-form-urlencoded',
                },
                redirect: "follow", // manual, *follow, error
                referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url

            });
            let response = await responseCreateContext.json();
            response = response.d;

            return response;
        } catch (e) {

        }
    }
}