/*
    Service that will be a wrapper for all api calls
*/
const ApiService = function ($http, $window, $rootScope, $state, $timeout, $q) {

    //let userId = -1;
    //let login_key = "session";
    //let login_event = 'login-change';
    const token_key = "auth_token";
    const admin_key = "admin_key";
    let auth_info = null;
    let self = this;
    let is_admin = false;
    let list_user_ids = null;

    auth_info = ($window.localStorage.getItem(token_key));
    is_admin = ($window.localStorage.getItem(admin_key));

    //Helper function for get api requests
    function _get(url, parameters) {
        if (parameters === null || parameters === undefined)
            parameters = {};
        return $http.get(url, { params: parameters });
    };

    function _post(url, data) {
        return $http.post(url, data);
    };

    function onAuthChanged() {
        $timeout(function () {
            $rootScope.$broadcast('auth-changed');
        });
    }

    //resets all variables, removes local storage, and takes user to login page. 
    this.reset = function(){
        auth_info = null;
        is_admin = false;
        list_user_ids = null;
        $window.localStorage.removeItem(token_key);
        $window.localStorage.removeItem(admin_key);
        onAuthChanged();
        $state.go("login", {}, { reload: true });
    }


    //removes session and marks users as inactive in DB. 
    //also sets host name to null in DB
    this.setInactive = function (authToken) {
        return _get('/api/session/setInactive', { session: authToken });
    }

    //login
    this.isLoggedIn = function (response) {
        if (auth_info == null) {
            return false;
        }
        return true;
    };

    //login that checks if client session token exists in DB
    //returns true or false in response.data; 
    this.isSessionValid = function () {
        return _get("api/session/isSessionValid", {session: auth_info}).then(function(response){
            return response.data; 
        })
    }

    this.redirectToLogin = function () {
        $state.go('login');
    }

    this.getAuthToken = function () {
        return auth_info;
    }

    this.isAdmin = function () {
        return is_admin;
    }

    this.logOff = function () {
        if (self.isLoggedIn()) {
            self.setInactive(auth_info).then(function (response) {

                //SP5
                if (response.status=="403"){
                    Console.log("Some Authentication error on logOff");
                }


                //console.log("able to delete session and sets users to inactive? " + response.data);
                $window.localStorage.removeItem(token_key);
                $window.localStorage.removeItem(admin_key);
                is_admin = false;
                auth_info = null;
                onAuthChanged(); //broadcasts that user is logged of
                $rootScope.$broadcast('state-change');
                $state.go("login", {}, { reload: true });
            });
        }
    }

    this.logIn = function (loginmodels) {

        return _post("/api/session", loginmodels).then(function (response) {
            var token = response.data;

            if (token != "false" && !token.includes("is logged in machine")) {
                $window.localStorage.setItem(token_key, token);
                auth_info = token;
                onAuthChanged();

                loginmodels.forEach(function (user) {
                    if (user.name == 'admin') {
                        is_admin = true;
                        $window.localStorage.setItem(admin_key, 'true');
                    }
                });

                self.getUserIds();
            }

            return response;
        });

    }

    this.getActivityScript = function () {
        //SHOULD BE CHANGED TO USERS GROUP IDK WHAT TODO
        return _get("/api/activities.json");
    }

    this.submitStory = function (storyText) {
        //console.log(storyText); 
        var promises = [];

        list_user_ids.forEach(function (userId) {
            var promise = _post("/api/story/submit", { userID: userId, text: storyText });
            promises.push(promise);
        });

        return $q.all(promises);
    }

    //SP3 to be able to grab the values from 
    this.getUserStory = function () {
        return _get("/api/story/submit");
    }

    this.completeActivity = function (activityId) {
        var promises = [];

        list_user_ids.forEach(function (userId) {
            var promise = _post("/api/progress", { userId: userId, activityId: activityId, });
            promises.push(promise);
        });

        return $q.all(promises);

    }

    this.getProgress = function () {
        return _get("/api/progress/session", { session: self.getAuthToken() })
    }

    this.getActivityStatus = function () {
        return _get("/api/progress")
    }

    //users
    this.getUsers = function () {
        return _get("/api/user");
    }

    this.postUser = function (user) {
        return _post("/api/user", user);
    }

    this.getUserIds = function () {
        return _get("/api/session", { session: this.getAuthToken() }).then(function (response) {
            list_user_ids = response.data;

            return response;
        });
    }

    this.deleteActivityProgress = function (activityId) {
        var promises = [];

        list_user_ids.forEach(function (userId) {
            var promise = _get("api/progress/delete", { userId: userId, activityId: activityId });
            promises.push(promise);
        });

        return $q.all(promises);
    }

    this.getActivity = function (activityId) {
        return _get("api/activity/" + activityId);
    }

    this.getActivities = function () {
        return _get("api/activity");
    }

    this.setActivitiesStatus = function (statusArray) {
        return _post("api/activity/setStatus", statusArray);
    }

    //kicks the userID, using the adminToken as authentication for the action
    this.kickUser = function (userId, adminToken) {
        var data = adminToken+","+userId;
        //var data = {adminToken: adminToken, userId: userId}
        return $http.post('/api/session/kickUser', data);
    }

    //init
    if (self.isLoggedIn()) {
        self.getUserIds();
    }


};