var SSOSessionKeepAlive = (function() {
    // Private variables and functions
    var oktaSessionRefreshTimer;

    function calculateDeferralInterval(timeUntilExpiration) {
        var minDeferralAdvance = 30 * 60 * 1000; // 30 minutes
        var maxDeferralAdvance = 45 * 60 * 1000; // 45 minutes
        var deferralAdvance =
            Math.floor(
                Math.random() * (maxDeferralAdvance - minDeferralAdvance + 1)
            ) + minDeferralAdvance;
        return Math.max(timeUntilExpiration - deferralAdvance, 0);
    }


    // Function to refresh the Okta session with domain and refresh flag as arguments using XMLHttpRequest
    function refreshOktaSession(oktaDomain) {
        var storedExpiresAt = localStorage.getItem("oktaSessionExpiresAt");
        var now = Date.now();

        if (storedExpiresAt) {
            var expiresAt = new Date(storedExpiresAt).getTime();
            var timeUntilExpiration = expiresAt - now;

            if (timeUntilExpiration > 3600000) {
                // 1 hour in milliseconds
                console.log(
                    "RefreshOktaSession: Session is valid for more than 1 hour, deferring the API call."
                );
                var deferralInterval = calculateDeferralInterval(timeUntilExpiration);
                clearTimeout(oktaSessionRefreshTimer);
                oktaSessionRefreshTimer = setTimeout(function() {
                    refreshOktaSession(oktaDomain);
                }, deferralInterval);
                return;
            }
        }

        // Okta Sessions endpoint
        var apiEndpoint = "https://" + oktaDomain + "/api/v1/sessions/me";

        // Create a new XMLHttpRequest
        var xhr = new XMLHttpRequest();
        xhr.open("GET", apiEndpoint, true);
        xhr.withCredentials = true; // To include cookies
        xhr.setRequestHeader("Accept", "application/json");
        xhr.setRequestHeader("Content-Type", "application/json");

        xhr.onerror = function() {
            console.log('Network Error');
        };

        xhr.onreadystatechange = function() {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    console.log(
                        "RefreshOktaSession: Okta session information retrieved successfully"
                    );
                    var session = JSON.parse(xhr.responseText);
                    if (session.expiresAt) {
                        var expiresAt = new Date(session.expiresAt).getTime();
                        var timeUntilExpiration = expiresAt - now;

                        var minRefreshAdvance = 3 * 60 * 1000; // 3 minutes
                        var maxRefreshAdvance = 5 * 60 * 1000; // 5 minutes
                        var refreshAdvance =
                            Math.floor(
                                Math.random() * (maxRefreshAdvance - minRefreshAdvance + 1)
                            ) + minRefreshAdvance;

                        var refreshInterval = Math.max(
                            timeUntilExpiration - refreshAdvance,
                            0
                        );

                        clearTimeout(oktaSessionRefreshTimer);
                        oktaSessionRefreshTimer = setTimeout(function() {
                            refreshOktaSession(oktaDomain);
                        }, refreshInterval);

                        localStorage.setItem("oktaSessionExpiresAt", session.expiresAt);
                    }
                } else {
                    console.log(
                        "RefreshOktaSession: Failed to retrieve Okta session expiration information", xhr.status, xhr.statusText
                    );
                }
            }
        };


        xhr.send();

    }


    // Public API
    return {
        init: function(isRefreshEnabled, oktaDomain) {
            if (!isRefreshEnabled) {
                console.log("RefreshOktaSession: Session refresh logic is disabled.");
                return;
            }

            if (!oktaDomain) {
                oktaDomain = 'ssosignon.servicenow.com';
            }

            refreshOktaSession(oktaDomain);

        },
    };
})();