'use strict';

// Session module. Provide session factory $sessionFactory
angular.module('angularJSApp.session', ['ngCookies', 'ngToast', 'angularJSApp.utils', 'angularJSApp.constant', 'angularJSApp.config_server'])

    // Session
    .factory('session', ['$cookies', 'ngToast', 'AppConfig', 'Util', '$state', '$q', '$rootScope', '$http',
        '$translate', 'moment', 'userConfig', 'redirectToUrlAfterLogin', '$timeout', '$location', 'paymentType',
        'SessionType', 'localStorageKey', 'configServer', 'packageUpgrade', 'TeamStatus', 'PACKAGE_NAME',
        function ($cookies, ngToast, AppConfig, Util, $state, $q, $rootScope, $http,
                  $translate, moment, userConfig, redirectToUrlAfterLogin, $timeout, $location, paymentType,
                  SessionType, localStorageKey, configServer, packageUpgrade, TeamStatus, PACKAGE_NAME) {
            // store current user
            var sessionUser;
            var currentUser = "t";
            var otpToken;
            var keepLogin;
            var firstTimeLoginToken;

            function getRedirectPath(roleId) {
                var redirectPath;
                switch (roleId) {
                    case userConfig.TEAM_ADMIN.role :
                    case userConfig.MANAGER.role :
                    case userConfig.MEMBER.role :
                    case userConfig.GUEST.role :
                        redirectPath = (redirectToUrlAfterLogin.url !== '/')
                            ? redirectToUrlAfterLogin.url : userConfig.TEAM_ADMIN.landing_page;
                        break;
                    default:
                        redirectPath = "login";
                        break;
                }
                return redirectPath;
            }

            var service = {

                // Get token from cookie
                getAccessToken: function () {
                    // return $cookies.get(AppConfig.TOKEN_COOKIE_NAME);
                    // return sessionStorage.getItem(AppConfig.TOKEN_COOKIE_NAME);
                    return localStorage.getItem(AppConfig.TOKEN_COOKIE_NAME);
                },

                // Set token
                setAccessToken: function (token, expirationDate) {
                    if (token) {
                        if (expirationDate) {
                            var expireDate = new Date(expirationDate);
                            localStorage.setItem(AppConfig.TOKEN_COOKIE_NAME, token);
                        } else
                            localStorage.setItem(AppConfig.TOKEN_COOKIE_NAME, token);
                    }
                },

                // get first time login token
                getFirstTimeLoginToken: function () {
                    return firstTimeLoginToken;
                },
                // set first time login token
                setFirstTimeLoginToken: function (token) {
                    firstTimeLoginToken = token;
                },

                // Get user
                getUser: function () {
                    return sessionUser;
                },
                // Set user
                setUser: function (user) {
                    // Set user
                    if (angular.isObject(user)) {
                        $rootScope.currentUser = sessionUser = user;
                    }
                },

                saveAttemptUrl: function () {
                    if (!$location.path().toLowerCase().match(/login/g)) {
                        redirectToUrlAfterLogin.url = $location.path();
                    } else {
                        redirectToUrlAfterLogin.url = '/';
                    }
                },

                authenticationRequiredHandler: function () {
                    //Save redirect url after login again
                    service.saveAttemptUrl();

                    // Transition to login page
                    $timeout(function () {
                        $state.go('login');
                    });
                },

                getPasswordPolicySetting: function (key, cb) {
                    var paramsPasswordPolicy = {
                        auth_token: key,
                    };
                    return Util.createRequest(configServer.API_URL + "/team/settings/password_policy", "GET",
                        paramsPasswordPolicy, function (data) {
                            localStorage.setItem(localStorageKey.PASSWORD_POLICY, JSON.stringify(data.data));
                            cb && cb(key);
                        }, function (error) {

                        });
                },

                userLogin: function (loginParams, cb, err) {
                    return Util.createRequest(configServer.API_URL + "/auth/user/login", "POST", loginParams, function (data) {
                        if (data && data.status === 200) {
                            // Login success
                            if (dataLayer) {
                              dataLayer.push({
                                event: "sign_in_success",
                              });
                            }
                            if (data.data.type === SessionType.PRIMARY_SESSION) { // primary type
                                service.setAccessToken(data.data.session_id, data.data.expiration_date);
                            } else if (data.data.type === SessionType.PASSWORD_POLICY_SESSION) { // check first time login
                                if (data.data.password_expire === true) { // password expire
                                    Util.createToast({className: 'danger', content: 'ERROR.PASSWORD_EXPIRE'});
                                } else { // check first time login
                                    service.setFirstTimeLoginToken(data.data.session_id);
                                    Util.createToast({className: 'danger', content: 'ERROR.FIRST_TIME_LOGIN'});
                                }
                            } else if (data.data.type === SessionType.OTP_SESSION) { // check 2-FA
                                service.setOTPToken(data.data.session_id);
                                service.setKeepLogin(loginParams.keep_login);
                            } else {
                                //not support this team
                                err && err('unSupport');
                            }

                            var redirectPath = getRedirectPath(data.data.role_id);
                            cb && cb(data, redirectPath);

                            //reset redirect url
                            redirectToUrlAfterLogin.url = "/";
                        } else {
                            err && err(data);
                            // Login fail
                        }
                    }, function (error) {
                        ngToast.create({
                            className: 'error',
                            content: 'There are some error occur !'
                        });
                        err && err(error);
                    });
                },

                logout: function (callback) {
                    return Util.createRequest(configServer.API_URL + "/auth/logout", "POST", {}, function (data) {
                        // reset redirect url
                        redirectToUrlAfterLogin.url = "/";

                        callback && callback(data);
                    }, function (error) {
                    }).finally(function () {
                        $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                        localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                        sessionUser = undefined;

                        $state.go('login');
                    });
                },

                getAuthUser: function (cb, err) {
                    Util.createRequest(configServer.API_URL + "/auth/info", "GET", {}, function (response) {
                        var status = response.status;
                        if (status === 200) {
                            // store user into session
                            cb && cb(response.data);
                        } else {
                            err && err(response.data);
                        }

                    }, function (errResponse) {
                        if (errResponse.status !== 401) {
                            Util.createToast({
                                className: 'danger',
                                content: 'SERVER_ERROR.' + errResponse.status
                            });
                        } else {
                            $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                            localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                        }
                    });
                },

                checkUserGroups: function (currentUser, groupIds, cb, error) {
                    Util.createRequest(configServer.API_URL + "/users/" + currentUser.user_id, "GET", {}, function (data) {
                        if (data && data.status === 200) {
                            var filtered_ids = _.filter(data.data.group_user_list, function (p) {
                                return _.includes(groupIds, p.group_user_id);
                            });
                            if (filtered_ids.length === 0) {
                                error && error();
                            } else {
                                cb && cb(filtered_ids);
                            }
                        } else {
                            error && error();
                        }

                    }, function (error) {
                        Util.createToast({
                            className: 'danger',
                            content: 'SERVER_ERROR.' + error.status
                        });
                        error && error();
                    });
                },

                goHome: function () {
                    $state.go('home');
                },
                getUserFolderId: function () {
                    return sessionStorage.getItem(AppConfig.USER_FOLDER_ID);
                },
                // Get user
                setUserFolderId: function (id) {
                    sessionStorage.setItem(AppConfig.USER_FOLDER_ID, id);
                },
                init: function (redirectPath) {
                    var defer = $q.defer();
                    // validate session
                    if (service.getAccessToken()) {
                        // get user info
                        this.getAuthUser(function (response) {

                            $rootScope.isFreePackage = false;
                            // store user into session
                            var userProfile = response;

                            service.setUser(userProfile);

                            service.changeLanguage(userProfile.lang);

                            var packageName = userProfile.package_object.package_name || "";
                            if (packageName && packageName.toUpperCase() === PACKAGE_NAME.FREE) {
                                $rootScope.isFreePackage = true;
                                $rootScope.title_package = packageUpgrade.FREE;

                            }
                            $rootScope.packageName = packageName;
                            $rootScope.title_package = packageName;

                            // if (userProfile.team_status === TeamStatus.Trial) {
                            //     $rootScope.isTrial = true;
                            //     // expiry trial days inform
                            //     var currentDate = new Date();
                            //     var teamCreateDate = new Date(userProfile.team_created_date);
                            //
                            //     $rootScope.expiryTrialDays = 0;
                            //     $rootScope.days = currentDate.getTime() - teamCreateDate.getTime();
                            //     $rootScope.days = Math.round($rootScope.days / 1000 / 60 / 60 / 24);
                            //
                            //     if ($rootScope.days <= 30) {
                            //         $rootScope.expiryTrialDays = 30 - $rootScope.days;
                            //     }
                            // }

                            var originName = userProfile.first_name + ' ' + userProfile.last_name;
                            $rootScope.displayName = (originName.length > 15) ? originName.substring(0, 15) + '...' : originName;
                            $rootScope.userRoleId = userProfile.role_id;
                            $rootScope.isTeamAdmin = (userProfile.role_id === userConfig.TEAM_ADMIN.role);
                            $rootScope.isPaymentOnline = (userProfile.payment_type === paymentType.ONLINE);
                            console.log("$rootScope.isPaymentOnline", $rootScope.isPaymentOnline)
                            // if (userProfile.package_object.user_price_id === configServer.USER_PRICE_ID_FREE
                            //     && userProfile.package_object.storage_price_id === configServer.STORAGE_PRICE_ID_FREE ||
                            //     userProfile.package_object.user_price_id === configServer.USER_PRICE_ID_FREE_JA
                            //     && userProfile.package_object.storage_price_id === configServer.STORAGE_PRICE_ID_FREE_JA) {
                            //     $rootScope.isFreePackage = true;
                            //     $rootScope.title_package = packageUpgrade.FREE;
                            // }
                            // if (userProfile.package_object.user_price_id === configServer.USER_PRICE_ID_PRO
                            //     && userProfile.package_object.storage_price_id === configServer.STORAGE_PRICE_ID_PRO ||
                            //     userProfile.package_object.user_price_id === configServer.USER_PRICE_ID_PRO_JA
                            //     && userProfile.package_object.storage_price_id === configServer.STORAGE_PRICE_ID_PRO_JA) {
                            //     $rootScope.title_package = packageUpgrade.PRO;
                            // }
                            $rootScope.isPaymentSession = false;
                            // payment method - 0: Online, 1: Offline
                            if (!$rootScope.isPaymentOnline) {
                                if ($rootScope.toState.name === 'teamPayment' || $rootScope.toState.name === 'upgradeAccount') {
                                    $state.go("dashboard");
                                }
                            } else {
                                if (userProfile.is_card_empty === true && AppConfig.TURN_ON_ADD_CARD) {
                                    if ($rootScope.toState.name !== 'teamPayment') {
                                        $state.go("teamPayment");
                                    }
                                } else if (userProfile.team_status === TeamStatus.Suspecting) {
                                    $rootScope.isPaymentSession = true;
                                    //get expiated date of payment team
                                    Util.createRequest(configServer.API_URL + "/payments/team/" + userProfile.team_id,
                                        "GET", {}, function (response) {
                                            var status = response.status;
                                            if (status === 200) {
                                                var now = moment(new Date(), 'DD/MM/YYYY');
                                                var expiryDate = moment(new Date(response.data.expiry_date), 'DD/MM/YYYY');
                                                $rootScope.countDays = AppConfig.EXPIRY_DAYS_NOTIFICATION - now.diff(expiryDate, 'days');
                                            } else {
                                                Util.createToast({
                                                    className: 'danger',
                                                    content: 'SERVER_ERROR.' + status
                                                });
                                            }
                                        }, function (errResponse) {
                                            Util.createToast({
                                                className: 'danger',
                                                content: 'SERVER_ERROR.' + errResponse.status
                                            });
                                        });
                                }
                            }
                            if ($rootScope.toState.name === 'login') {
                                $state.go("dashboard");
                            }
                            defer.resolve(userProfile);
                        }, function (errResponse) {
                            // clear user into session
                            $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                            localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);

                            $state.go('login');
                            defer.reject(errResponse);
                        }, true);
                    } else {
                        // clear user into session
                        localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                        $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                        // redirect to login page

                        $state.go('login');
                        defer.reject();
                    }

                    if (redirectPath) {
                        window.location.href = redirectPath;
                    }
                    return defer.promise;
                },
                detectBrowserLang: function () {
                    var lang = navigator.languages && navigator.languages[0] || // Chrome / Firefox
                        navigator.language ||   // All browsers
                        navigator.userLanguage; // IE <= 10 // Language code: http://4umi.com/web/html/languagecodes.php || http://msdn.microsoft.com/en-us/library/ie/ms533052.aspx
                    var language = lang.substr(0, 2);
                    switch (language) {
                        case 'vi':
                        case 'en':
                        case 'ja':
                            return language;
                        default:
                            return "en"; // default
                    }
                },
                // Do change language
                changeLanguage: function (lang) {
                    if (!angular.isDefined(lang))
                        return;
                    if (lang === 'auto')
                        lang = this.detectBrowserLang();

                    // Listen event changing process is done
                    var dfd = $q.defer();

                    $translate.use(lang);
                    // load 'en' table on startup
                    // $translate.preferredLanguage(lang);
                    // // Wrap HTML in $sce.trustAsHtml(value)
                    // $translate.useSanitizeValueStrategy('sce');

                    var call = $rootScope.$on('translateLanguageChange', function (event, lang) {
                        dfd.resolve(lang, event);
                        // Unregister
                        call();
                    });

                    return dfd.promise;
                },

                getCurrentLanguage: function () {
                    // Get lanage from browser
                    var browserLanguage = this.detectBrowserLang();
                    if ($rootScope.currentUser && $rootScope.currentUser.lang) {
                        var currentUserLanguage = $rootScope.currentUser.lang;
                        if (currentUserLanguage === 'auto')
                            return browserLanguage;
                        else
                            return $rootScope.currentUser.lang;
                    } else {
                        return browserLanguage;
                    }
                },
                getOTPToken: function () {
                    return otpToken;
                },
                // Get user
                setOTPToken: function (token) {
                    otpToken = token;
                },
                getKeepLogin: function () {
                    return keepLogin;
                },
                // Get user
                setKeepLogin: function (isKeepLogin) {
                    keepLogin = isKeepLogin;
                },
                loginOTP: function (params, cb, err) {
                    return $http.post(configServer.API_URL + "/auth/user/otp/login", {
                            'auth_code': params.auth_code,
                            'keep_login': params.keep_login
                        },
                        {headers: {'Content-Type': 'application/json', 'otp-token': params.auth_token}})
                        .then(function (data) {
                            var result = data.data;
                            if (result && result.status === 200) {
                                if (dataLayer) {
                                  dataLayer.push({
                                    event: "sign_in_success",
                                  });
                                }
                                if(result.data.type === SessionType.PRIMARY_SESSION){
                                    service.setAccessToken(result.data.session_id, result.data.expiration_date);
                                    redirectToUrlAfterLogin.url = "/";
                                }
                                var redirectPath = getRedirectPath(result.data.role_id);
                                cb && cb(result, redirectPath);
                            } else {
                                Util.createToast({className: 'danger', content: 'SERVER_ERROR.' + result.status});
                                //reset redirect url

                            }
                        }, function (error) {
                            ngToast.create({
                                className: 'error',
                                content: 'There are some error occur !'
                            });
                            err && err(error);
                        });
                }
            };

            return service;
        }
    ]);
