// for development
//  AUTH0_CLIENT_ID: 'sgkuvzrSafF51POjpx3uOS4NHU1NnFJ8'

// for production, with Azure static web site URLs
//  AUTH0_CLIENT_ID: 'cz4y1PzGm6RXiUOeiynEbv3wGQaJJ7Du'
// for production, with www.invisiblesolutionslenses.com URL
//  AUTH0_CLIENT_ID: 'YBp10bYA3akRA0vJGhlaUPfSXrUp3q7J'

const authUtils = {

    COOKIE_STATE_KEY: 'state',
    COOKIE_CODE_KEY: 'code',

    QUERY_STRING_STATE_KEY: 'state',
    QUERY_STRING_CODE_KEY: 'code',

    AUTH0_DOMAIN: 'invisiblesolutions.auth0.com',
    AUTH0_CLIENT_ID: 'sgkuvzrSafF51POjpx3uOS4NHU1NnFJ8',

    _auth0Client: null,

    setAuth0Client: function setAuth0Client(client) {
        log('authUtils.setAuth0Client: enter');

        authUtils._auth0Client = client;
        // store the client object
        // according to the Auth0 object, we should only have one of these
        // so don't write the other methods in authUtils to create additional client objects

        log('authUtils.setAuth0Client: leave');
    },

    isUserAuthenticatedAsync: async function isUserAuthenticatedAsync() {
        log('authUtils.isUserAuthenticated: enter');

        const client = authUtils._auth0Client;
        // get the Auth0 client

        if (client === null) {
            // if none stored

            log('authUtils.isUserAuthenticated: _auth0Client is NULL, so we will return false');
            log('authUtils.isUserAuthenticated: leave');
            return false;
        }

        const authenticated = await client.isAuthenticated();
        // is the current user authenticated?

        log('authUtils.isUserAuthenticated: authenticated=' + authenticated);
        log('authUtils.isUserAuthenticated: leave');

        return authenticated;
    },

    getUserAsync: async function getUserAsync() {
        log('authUtils.getUserAsync: enter');
        log('authUtils.getUserAsync: atc createAuth0Client');

        const client = authUtils._auth0Client;
        // get the Auth0 client

        if (client === null) {
            // if none stored

            log('authUtils.getUserAsync: _auth0Client is NULL, so we will return NULL');
            log('authUtils.getUserAsync: leave');
            return null;
        }

        const authenticated = await client.isAuthenticated();
        // is the current user authenticated?

        log('authUtils.getUserAsync: authenticated=' + authenticated);

        if (!authenticated) {
            // if not

            log('authUtils.getUserAsync: user is NOT authenticated, so we will return NULL');
            log('authUtils.getUserAsync: leave');
            return null;
        }

        log('authUtils.getUserAsync: atc auth0Client.getUser');

        var user = await client.getUser();
        // get the current user or null if not found

        log('authUtils.getUserAsync: bf auth0Client.getUser');

        if (typeof user === 'undefined') {
            user = null;
        }

        log('authUtils.getUserAsync: leave');

        return user;
    },

    logUserAsync: async function logUserAsync() {

        log('authUtils.logUserAsync: enter');

        const user = await authUtils.getUserAsync();

        if (user === null) {
            log('authUtils.logUserAsync: getUserAsync returned null');
        }
        else {
            log('authUtils.logUserAsync: email: ' + user.email);
            log('authUtils.logUserAsync: given_name: ' + user.given_name);
            log('authUtils.logUserAsync: family_name: ' + user.family_name);
            log('authUtils.logUserAsync: picture: ' + user.picture);
        }

        log('authUtils.logUserAsync: leave');

        return user;
    },

    getAuthCode: function getAuthCode() {
        log('authUtils.getAuthCode: enter');

        var authCode = Cookies.get(this.COOKIE_CODE_KEY);

        if (typeof authCode === 'undefined')
            authCode = '';

        log('authUtils.getAuthCode: authCode=' + authCode);
        log('authUtils.getAuthCode: leave');
        return authCode;
    },

    setAuthCode: function setAuthCode(code) {
        log('authUtils.setAuthCode: enter');
        log('authUtils.setAuthCode: authCode=' + code);

        Cookies.set(this.COOKIE_CODE_KEY, code);

        log('authUtils.setAuthCode: leave');
    },

    getAuthState: function getAuthState() {
        log('authUtils.getAuthState: enter');

        var authState = Cookies.get(this.COOKIE_STATE_KEY);

        if (typeof authState === 'undefined')
            authState = '';

        log('authUtils.getAuthState: authState=' + authState);
        log('authUtils.getAuthState: leave');
        return authState;
    },

    setAuthState: function setAuthState(state) {
        log('authUtils.setAuthState: enter');
        log('authUtils.setAuthState: authState=' + state);

        Cookies.set(this.COOKIE_STATE_KEY, state);

        log('authUtils.setAuthState: leave');
    },

    doLogoutAsync: async function doLogoutAsync() {
        log('doLogoutAsync: enter');

        const client = authUtils._auth0Client;
        // get the Auth0 client

        if (client === null) {
            // if none stored

            log('authUtils.doLogoutAsync: _auth0Client is NULL, so we are done');
            log('authUtils.doLogoutAsync: leave');
            return;
        }

        log('doLogoutAsync: atc auth0.logout');

        const theURL = window.location.origin;

        log('doLogoutAsync: theURL=' + theURL);

        client.logout({
            returnTo: theURL
        });

        log('doLogoutAsync: bf auth0.logout');
        log('doLogoutAsync: leave');
    },

    doLoginAsync: async function doLoginAsync(redirectUrl) {
        const logHdr = 'authUtils.doLoginAsync: ';
        log(logHdr + 'enter');

        if (typeof redirectUrl === "undefined") {
            // if the caller did not pass a URL

            log(logHdr + 'caller failed to pass redirectUrl, so we throw an exception');

            throw 'authUtils.doLoginAsync: caller failed to pass redirectUrl';
        }

        if (redirectUrl === '') {
            // if empty string

            log(logHdr + 'caller passed empty redirectUrl, so we throw an exception');

            throw 'authUtils.doLoginAsync: caller passed empty redirecUrl';
        }

        log('doLoginAsync: redirectUrl=' + redirectUrl);

        // NOTE: we haven't authenticated yet, so we allocate a new Auth0 client here
        // rather than reading it from our _auth0Client property.

        const auth0Client = await createAuth0Client({ domain: this.AUTH0_DOMAIN, client_id: this.AUTH0_CLIENT_ID });
        // allocate an Auth0 object
        // if the user has already authenticated, the auth0 object will be populated with an access token and user profile

        if (auth0Client === null) {
            log(logHdr + 'createAuth0Client returned null, so we give up');

            throw 'authUtils.doLoginAsync: createAuth0Client returned null';
        }

        log(logHdr + 'atc auth0Client.loginWithRedirect');

        await auth0Client.loginWithRedirect({ redirect_uri: redirectUrl });
        // after login, redirect to the same page

        log(logHdr + 'bf auth0Client.loginWithRedirect');
        log(logHdr + 'leave');
    }
};

const authUIUtils = {
    updateUIForUser: function updateUIForUser(userName, imageURL) {
        log('updateUIForUser: enter');
        log('updateUIForUser: userName=' + userName);
        log('updateUIForUser: imageURL=' + imageURL);

        $('#spanAuthUserName').html(userName);

        $('#imgAuthUser').attr('src', imageURL);

        log('updateUIForUser: leave');
    }
};