'use strict';

// Session module. Provide session factory $sessionFactory
angular
    .module('session', ['ngCookies'])
    // Session
    .factory('session', [
        "APIName", "AppUtil", "Auth", "$injector", "$timeout", "$", "ClientInfo", "$state","configServer",
        "$location", "$q", "$rootScope", "util", "$i18next", 'userConfig', 'app', 'redirectToUrlAfterLogin', 'localStorageKey',

        function (APIName, AppUtil, Auth, $injector, $timeout, $, ClientInfo, $state, configServer,
                  $location, $q, $rootScope, util, $i18next, userConfig, app, redirectToUrlAfterLogin, localStorageKey) {

            var currentUser, TOKEN_COOKIE_NAME = "t";
            var listTeamUser;
            var currencySetting;
            var otpToken;
            var keepLogin;
            var firstTimeLoginToken

            // Check whether route service exists or not
            if ($injector.has) {
                var $route = $injector.has('$route') ? $injector.get('$route') : null;
            } else {
                var $route = $injector.get('$route');
            }

            // Check whether a route is public or not
            function isPublic(route) {
                return (route && (route.public === undefined || route.public === true));
            }

            // Check route auto redirect inside after authen or not
            function isRedirect(route) {
                return (route && (route.autoRedirect === true));
            }

            function getRedirectPath(roleId) {

                var redirectPath;
                switch (roleId) {

                    case userConfig.SUPER_ADMIN.role :
                        redirectPath = userConfig.SUPER_ADMIN.landing_page;
                        break;

                    case userConfig.COMPANY_ADMIN.role :
                        redirectPath = userConfig.COMPANY_ADMIN.landing_page;
                        break;
                }
                console.log("redirectPath",redirectPath)

                return redirectPath;
            }

            var service = {
                init: function () {
                    var resolvers = {
                        // Module resolver using for lazy loading
                        moduleResolver: function () {
                            // var mainModule = $ocLazyLoad.getModuleConfig( "main" );
                            // We got route
                            var currentRoute = $route.current.$$route;
                            // Get ocLazyModule for each route
                            var module = currentRoute && currentRoute.ocLazyModule;

                            if (module) {

                                return util.loadModule(module);
                            } else {

                                // Maybe we can use file config
                                var files = currentRoute && currentRoute.files;

                                if (files)
                                    return util.loadModule(files, true);
                            }
                            // return $ocLazyLoad.load( [ mainModule ] );
                            return true;
                        },
                        // Authenticate
                        auth: function () {
                            if ($route.current.$$route && $route.current.$$route.exception) {
                                return;
                            }
                            // Get token from cookie store
                            var cToken = $.cookie(TOKEN_COOKIE_NAME);

                            var deferred = $q.defer();
                            // Private route
                            if (isPublic($route ? $route.current.$$route : null) === false) {

                                if (cToken) {

                                    // Get user info with this token
                                    service.getUserInfo(function (data) {
                                        // Check whether language is the same or not
                                        // Set lang
                                        service.changeLanguage(data.lang).then(function () {
                                            deferred.resolve(data);
                                        });

                                    }, function () {
                                        // preLoginPath = window.location.href;
                                        // Invalid token
                                        deferred.reject("Unauthorized");
                                    });
                                } else {

                                    // preLoginPath = window.location.href;
                                    // Reset user info in case of token is expired
                                    service.reset();
                                    // Require authen - Redirect to login page
                                    service.authenticationRequiredHandler();
                                    // Reject this route
                                    deferred.reject('Unauthorized');
                                }
                            } else {
                                // Public route
                                if (cToken) {

                                    // Auto redirect based on that route's config
                                    // Login page
                                    if (isRedirect($route ? $route.current.$$route : null)) {

                                        service.getUserInfo(function () {

                                            service.authenticationSuccessHandler();

                                            deferred.resolve();
                                        }, function () {
                                            service.reset();
                                            deferred.resolve();
                                        });
                                    } else {

                                        deferred.resolve();
                                    }
                                } else {
                                    // Reset user info. Prevent display user info
                                    service.reset();
                                    deferred.resolve();
                                }
                            }
                            return deferred.promise;
                        }
                    };
                    // Set authen resolver for each route
                    for (var route in $route.routes) {
                        // Add resolver for user and permissions
                        $route.routes[route].resolve = ($route.routes[route].resolve || {});
                        angular.extend($route.routes[route].resolve, resolvers);
                    }
                },
                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("adminLogin");
                    });
                },
                authenticationSuccessHandler: function () {
                    $timeout(function () {
                        // Check current user
                        if (currentUser && angular.isDefined(currentUser)) {
                            var currentRole = currentUser.role_id;

                            switch (currentRole) {
                                case userConfig.SUPER_ADMIN.role :
                                    $state.go("companyList");
                                    break;
                                case userConfig.ADMIN.role :
                                case userConfig.MANAGER.role :
                                case userConfig.MEMBER.role :
                                case userConfig.GUEST.role :
                                    $state.go("projectList");
                                    break;
                                case userConfig.COMPANY_ADMIN.role :
                                    $state.go("teamList");
                                    break;
                            }
                        }
                    }, 500);
                },
                // Get token from cookie
                getToken: function () {
                    return $.cookie(TOKEN_COOKIE_NAME);
                },
                // Set token
                setToken: function (token, expirationDate) {
                    var expireDate = new Date(expirationDate);
                    // expireDate.setDate(expireDate.getDate() + 1);

                    $.cookie(TOKEN_COOKIE_NAME, token, {expires: expireDate, path: '/'});
                },
                // Set user
                setUser: function (user) {
                    // Set user
                    if (angular.isObject(user)) {
                        $rootScope.user = currentUser = user;
                    }

                    // Should remove. I'm keeping for other services using
                    Auth.setUser(user);
                },
                // Get user
                getUser: function () {
                    return currentUser;
                },
                // Get user
                getlistTeamUser: function () {
                    return listTeamUser;
                },
                // Get user
                setlistTeamUser: function (_listTeamUser) {
                    listTeamUser = _listTeamUser;
                },
                getOTPToken: function () {
                    return otpToken;
                },
                // Get user
                setOTPToken: function (token) {
                    otpToken = token;
                },
                // get first time login token
                getFirstTimeLoginToken: function () {
                    return firstTimeLoginToken;
                },
                // set first time login token
                setFirstTimeLoginToken: function (token) {
                    firstTimeLoginToken = token;
                },
                getKeepLogin: function () {
                    return keepLogin;
                },
                // Get user
                setKeepLogin: function (isKeepLogin) {
                    keepLogin = isKeepLogin;
                },
                // 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();

                    // Check change
                    if (lang === $i18next.options.lng) {
                        dfd.resolve(lang);
                    } else {

                        // Apply change
                        $i18next.options = {
                            lng: lang,
                            resGetPath: 'i18n/app.' + lang + '.json'
                        };

                        var call = $rootScope.$on('i18nextLanguageChange', function (event, lang) {

                            dfd.resolve(lang, event);
                            // Unregister
                            call();
                        });
                    }
                    return dfd.promise;
                },
                // Get team member
                getTeamMember: function (callback) {

                    if (!angular.isObject(currentUser))
                        return;

                    var teamId = currentUser.team_id || currentUser.teamId;

                    var objUrl = {
                        method: APIName.USER_LIST_ALL_BY_TEAM_ID.method,
                        name: APIName.USER_LIST_ALL_BY_TEAM_ID.name + teamId + APIName.USER_LIST_ALL_BY_TEAM_ID.surfix
                    };
                    return AppUtil.createRequest(objUrl, {}, function (data) {
                        callback && callback(data);
                    });
                },
                // Get team profile
                getTeamProfile: function (callback) {

                    if (!angular.isObject(currentUser))
                        return;
                    var teamId = currentUser.team_id || currentUser.teamId;
                    return AppUtil.createRequest({
                        name: APIName.GET_TEAM.name + teamId,
                        method: "GET"
                    }, {}, function (data) {
                        callback && callback(data.data);
                    });
                },
                getAddressBook: function (callback) {

                    if (!angular.isObject(currentUser))
                        return;

                    var params = {
                        search_key: "",
                        page_size: 10,
                        page_number: 1,
                        sort_field: "",
                        asc_sort: false
                    };

                    return AppUtil.createRequest(APIName.ADDRESS_BOOK_LIST, params, function (res) {
                        callback && callback(res);
                    });
                },
                // Get project member
                // Should move to project utilities
                getProjectMember: function (project_id, folder_id, callback) {

                    var folderId = (folder_id) ? folder_id : "0";
                    var objUrl = {
                        method: APIName.GET_USER_PROJECT.method,
                        name: APIName.GET_USER_PROJECT.name + folderId + APIName.GET_USER_PROJECT.suffix
                    };
                    return AppUtil.createRequest(objUrl, {project_id: project_id}, function (res) {
                        callback && callback(res);
                    }, function (res) {
                        AppUtil.showError({
                            text: util.translate("sever_errors." + res.status)
                        });
                        $state.reload();

                    });
                },
                getProjectMemberByProject: function (project_id, callback) {

                    var objUrl = {
                        method: APIName.GET_USER_PROJECT_BY_PROJECT.method,
                        name: APIName.GET_USER_PROJECT_BY_PROJECT.name + project_id + APIName.GET_USER_PROJECT_BY_PROJECT.suffix
                    };
                    return AppUtil.createRequest(objUrl, {}, function (res) {
                        callback && callback(res);
                    }, function (res) {
                        AppUtil.showError({
                            text: util.translate("sever_errors." + res.status)
                        });
                        $state.reload();

                    });
                },
                // Reset user information
                reset: function () {
                    // Remove cookie
                    $.removeCookie(TOKEN_COOKIE_NAME, {path: '/'});
                    // Set user as null
                    $rootScope.user = currentUser = null;
                },
                // Get user info
                getUserInfo: function (callback, error) {

                    var that = this;
                    // Our interceptor auto add token
                    AppUtil.createRequest(APIName.GET_AUTH_INFO, {}, function (data) {
                        var user = data.data;
                        if (data.data.role_id === userConfig.COMPANY_ADMIN.role) {
                            that.getCurrencyApi();
                        }
                        if (data.data.role_id === userConfig.ADMIN.role || data.data.role_id === userConfig.MANAGER.role
                            || data.data.role_id === userConfig.MEMBER.role || data.data.role_id === userConfig.GUEST.role) {
                            that.getTeamSettingApi(data.data.team_id, function (res) {
                                user.team_settings = res || '';
                                that.setUser(user);
                                callback && callback(user);
                            });
                        } else {
                            that.setUser(user);
                            callback && callback(user);
                        }

                    }, function (data) {
                        that.reset();
                        // Invalid token
                        error && error(data);
                    });
                },
                getPasswordPolicySetting: function (key, cb) {
                    var that = this;
                    var paramsPasswordPolicy = {
                        auth_token: key,
                    };
                    var objUrlPasswordPolicy = {
                        method: APIName.GET_PASSWORD_POLICY_SETTING.method,
                        url: APIName.GET_PASSWORD_POLICY_SETTING.name
                    };
                    AppUtil.createRequest(objUrlPasswordPolicy, paramsPasswordPolicy, function (data) {
                        localStorage.setItem(localStorageKey.PASSWORD_POLICY, JSON.stringify(data.data));
                        cb && cb(key);
                    }, function (error) {
                    });
                },
                // Do login
                login: function (credential, callback, error, isAdmin) {
                    if (!angular.isObject(credential))
                        return;

                    var that = this;

                    var params = credential;

                    // Encrypt password

                    var passwordMD5Hash = credential.password_hash;

                    var emailEncode = credential.email;

                    var passencoded = AppUtil.MD5(passwordMD5Hash);

                    params["email"] = emailEncode;
                    params["password_hash"] = passencoded;
                    return AppUtil.createRequest(isAdmin ? APIName.LOGIN_ADMIN : APIName.LOGIN, params, function (data) {
                        // Store cookie
                        if (data.data.type === app.FACTOR_AUTHEN_TWO_STEP) {
                            that.setOTPToken(data.data.session_id);
                            that.setKeepLogin(params.keep_login);
                        } else if (data.data.type === app.CHANGE_PASSWORD_EXPIRED) {
                            if (data.data.password_expire === true) { // password expire
                                AppUtil.showError({
                                    text: util.translate("errors.password_expire"),
                                    timeout: 10000 // 10s
                                });
                            } else { // check first time login
                                that.setFirstTimeLoginToken(data.data.session_id);
                                AppUtil.showError({
                                    text: util.translate("errors.first_time_login"),
                                    timeout: 10000 // 10s
                                });
                            }
                        } else {
                            if (!configServer.SESSION_COOKIE_ENABLE){
                                that.setToken(data.data.session_id, data.data.expiration_date);
                            }

                        }

                        var roleId = data.data.role_id;
                        var redirectPath = getRedirectPath(roleId);

                        callback && callback(data, redirectPath);

                        //reset redirect url
                        redirectToUrlAfterLogin.url = "/";

                    }, function (err) {
                        error && error(err);
                    });
                },
                loginOTP: function (params, callback, error) {

                    if (params) {

                        var _this = this;

                        var opts = APIName.VERIFY_AUTHEN_CODE_LOGIN;

                        opts.headers = {};
                        opts.headers['otp-token'] = params.auth_token;

                        var body = {
                            'auth_code': params.auth_code,
                            'keep_login': params.keep_login
                        };

                        // Set current authentication token
                        // _this.setToken(params.auth_token);
                        // validate OTP link
                        util.createRequest(
                            opts,
                            body,
                            function (data) {
                                if (data.data.type === 2) {
                                    if (!configServer.SESSION_COOKIE_ENABLE) {
                                        _this.setFirstTimeLoginToken(data.data.session_id);
                                    }
                                    callback && callback(data, "");
                                } else {
                                    if (!configServer.SESSION_COOKIE_ENABLE) {
                                        // update session id
                                        _this.setToken(data.data.session_id, data.data.expiration_date);
                                    }
                                    var roleId = data.data.role_id;
                                    var redirectPath = getRedirectPath(roleId);
                                    $location.search({});
                                    $location.path(redirectPath);
                                    callback && callback(data, redirectPath);
                                }
                            }, function (err) {
                                error && error(err);
                                AppUtil.showError({
                                    text: util.translate("sever_errors." + err.status)
                                });
                            }
                        );
                    }
                },
                // Do logout
                logout: function (callback) {

                    var that = this;

                    AppUtil.createRequest(APIName.LOGOUT, function (data) {

                        var copy = angular.copy(currentUser);

                        that.reset();

                        //reset redirect url
                        redirectToUrlAfterLogin.url = "/";

                        callback && callback(copy, data);
                    });
                },
                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;
                            break;

                        default:
                            return "en"; // default
                            break;
                    }
                },
                getCurrentLanguage: function () {
                    // Get lanage from browser
                    var browserLanguage = this.detectBrowserLang();
                    if (currentUser) {
                        var currentUserLanguage = currentUser.lang;
                        if (currentUserLanguage === 'auto')
                            return browserLanguage;
                        else
                            return currentUser.lang;
                    } else
                        return browserLanguage;
                },
                // check if current user Team Admin
                isAdmin: function () {
                    if (currentUser !== null && currentUser.role_id === 1)
                        return true;
                    else
                        return false;
                },
                isGuest: function () {
                    if (currentUser !== null && currentUser.role_id === 4)
                        return true;
                    else
                        return false;
                },
                //check the language is Japanese or not
                isJapanese: function () {
                    if (currentUser !== null && currentUser.lang === 'ja')
                        return true;
                    else
                        return false;
                },
                getCurrencyApi: function (cb) {
                    if (currentUser) {
                        var api = {
                            method: APIName.GET_COMPANY_INFO.method,
                            name: APIName.GET_COMPANY_INFO.name + currentUser.company_id
                        };
                        AppUtil.createRequest(api, {}, function (data) {
                            currencySetting = data.data.company.currency;
                            localStorage.setItem(localStorageKey.CURRENCY, currencySetting);
                        });

                    } else {
                        cb && cb();
                    }
                },
                getTeamSettingApi: function (teamId, cb) {
                    if (teamId) {
                        var api = {
                            method: APIName.GET_TEAM.method,
                            name: APIName.GET_TEAM.name + teamId
                        };
                        AppUtil.createRequest(api, {}, function (res) {
                            cb && cb(res.data.settings);
                        }, function () {
                            cb && cb();
                        });
                    } else {
                        cb && cb();
                    }
                },
                setCurrency: function (currencyParams) {
                    currencySetting = currencyParams;
                    localStorage.setItem(localStorageKey.CURRENCY, currencySetting);
                },
                getCurrencyValue: function () {
                    return localStorage.getItem(localStorageKey.CURRENCY);
                },
                isEdgeBrowser: function () {
                    var isIE = /*@cc_on!@*/!!document.documentMode;
                    // Edge 20+
                    return !isIE && !!window.StyleMedia;
                },
                isEnableCookieSession: function(){
                    return configServer.SESSION_COOKIE_ENABLE;
                },
            };

            return service;
        }])

    // Authen factory
    // This factory is now deprecated
    .factory('Auth', function ($) {

        var currentUser;

        return {
            getToken: function () {
                return $.cookie('t');
            },
            getUser: function () {

                return currentUser;
            },
            setUser: function (jsonResult) {

                angular.isObject(jsonResult) && (currentUser = jsonResult);
            }
        };
    });
