/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
'use strict';

angular.module('invite', [])

    // Invite utilities
    .factory("invite", ["session", "AppUtil", "APIName", "$q", "_", "util", "$state",
        function (session, AppUtil, APIName, $q, _, util, $state) {

            return {
                // @param {Array} changedList
                // @param {function} callback
                doChangeRole: function (project_id, changedList, folder_id, callback) {
                    // Find all members has been kicked
                    var lKicked = _.filter(changedList, {status: 2});

                    var reqs = [], dfd = $q.defer();
                    folderId = (folder_id) ? folder_id : "0";

                    var group_user_ids = _.compact(_.pluck(lKicked, 'group_id').join(',').split(','));
                    var user_ids = _.compact(_.pluck(lKicked, 'user_id').join(',').split(','));

                    if (user_ids != null) {
                        var objUrl = {
                            name: APIName.KICK_USER_PROJECT.name + folderId + APIName.KICK_USER_PROJECT.surfix,
                            method: APIName.KICK_USER_PROJECT.method
                        };
                        angular.forEach(user_ids, function (user_id) {
                            var params = {
                                user_id: user_id,
                                project_id: project_id
                            };

                            if (lKicked.length > 0) {
                                // Do kick
                                reqs.push(AppUtil.createRequest(objUrl, params, function (data) {


                                }, function (error) {

                                }));
                            }
                        });
                    }

                    if (group_user_ids != null) {
                        angular.forEach(group_user_ids, function (group_user_id) {
                            var objUrlKickGroupCollaborator = {
                                name: APIName.KICK_USER_PROJECT_GROUP.name + folderId + APIName.KICK_USER_PROJECT_GROUP.surfix + group_user_id,
                                method: APIName.KICK_USER_PROJECT_GROUP.method
                            };
                            var params = {
                                project_id: project_id
                            };

                            if (lKicked.length > 0) {
                                // Do kick
                                reqs.push(AppUtil.createRequest(objUrlKickGroupCollaborator, params, function (data) {


                                }, function (error) {

                                }));
                            }
                        });
                    }
                    // Find all members has been changed their role

                    if (changedList.length > 0) {

                        var userRole = [];
                        var groupRole = [];
                        angular.forEach(changedList, function (mem) {
                            // Check not in kicked list
                            if (mem.status === 1) {
                                if (mem && mem.user_id != null) {
                                    var updateUser = {
                                        "user_id": mem.user_id,
                                        "role_id": mem.project_role_id
                                    };
                                    userRole.push(updateUser);
                                } else {
                                    groupRole.push(mem);
                                }
                            }
                        });
                        var folderId = (folder_id) ? folder_id : "0";

                        if (userRole.length > 0) {
                            var objUrlChange = {
                                method: APIName.UPDATE_USER_PROJECT.method,
                                name: APIName.UPDATE_USER_PROJECT.name + folderId + APIName.UPDATE_USER_PROJECT.surfix
                            };

                            reqs.push(AppUtil.createRequest(objUrlChange, {
                                users: userRole,
                                project_id: project_id
                            }, function (res) {
                                // AppUtil.showSuccess({text: util.translate('default_toast.update_success')});
                            }, function (error) {

                            }));
                        }
                        if (groupRole.length > 0) {
                            var objUrlChangeGroup = {
                                method: APIName.UPDATE_USER_PROJECT_GROUP.method,
                                name: APIName.UPDATE_USER_PROJECT_GROUP.name + folderId + APIName.UPDATE_USER_PROJECT_GROUP.surfix
                            };
                            angular.forEach(groupRole, function (value) {
                                reqs.push(AppUtil.createRequest(objUrlChangeGroup, {
                                    group_id: value.group_id,
                                    folder_group_role_id: value.project_role_id,
                                    project_id: project_id
                                }, function (res) {
                                    // AppUtil.showSuccess({text: util.translate('default_toast.update_success')});
                                }, function (error) {

                                }));
                            });

                        }
                    }

                    if (reqs.length > 0) {

                        // Post all reqs
                        $q.all(reqs).then(function (data) {
                            dfd.resolve(data);
                            var success = true;
                            // Get result
                            angular.forEach(data, function (d) {
                                if (d.data) {
                                    if (d.data.status !== 200) {
                                        success = false;
                                    }
                                }
                            });
                            if (success) {
                                AppUtil.showSuccess({text: util.translate('default_toast.save_success')});
                            } else {
                                AppUtil.showError({text: util.translate("sever_errors." + 403)});
                                $state.reload();
                            }

                            callback && callback(data);
                        });
                    }

                    return dfd;
                },
                // @param {Array} users Must contain "user_id" key
                doInvite: function (project_id, folder_id, users, role, message, isOverwrite, callback, errorCb) {

                    var user = session.getUser();
                    var ids = _.map(users, 'user_id');
                    // ids = _.pluck( $scope.invite.users , 'user_id');
                    var userRole = [];
                    var updateUser;
                    angular.forEach(ids, function (id) {

                        updateUser = {
                            "user_id": id,
                            "role_id": role
                        };
                        userRole.push(updateUser);
                    });
                    var params = {
                        team_id: user.team_id,
                        users: userRole,
                        message: message,
                        project_id: project_id,
                        overwrite: isOverwrite
                    };

                    var folderId = (folder_id) ? folder_id : "0";
                    var objUrl = {
                        name: APIName.INVITE_USER_PROJECT.name + folderId + APIName.INVITE_USER_PROJECT.surfix,
                        method: APIName.INVITE_USER_PROJECT.method
                    };
                    // Request
                    return AppUtil.createRequest(objUrl, params, function (data) {

                        callback && callback(data);

                        if (data.data.error_users.length > 0) {
                            angular.forEach(data.data.error_users, function (email) {
                                if (email.type_error !== 5) {
                                    AppUtil.showError({text: util.translate("invite_error_users." + email.type_error) + " " + email.email});
                                } else {
                                    angular.forEach(users, function (user) {
                                        if (user.user_id === email.user_id) {
                                            AppUtil.showError({text: util.translate("invite_error_users." + email.type_error) + " " + user.value});
                                        }
                                    });
                                }
                            });
                        } else {
                            AppUtil.createToast({
                                text: util.translate("default_toast.invite_success"),
                                type: 'success'
                            });


                        }

                    }, function (error) {
                        errorCb && errorCb(error);
                        // apply invited successful user
                        callback && callback();
                    });
                }

            };
        }])

    // Invite controller
    // In project detail
    .controller('InviteModal', [
        "$scope", "$uibModalInstance", "project", "_", "session", "invite", "util", "AppUtil",
        "app", "ProjectService", '$uibModal', 'projectRole', 'userConfig', 'APIName', '$q',
        function ($scope, $uibModalInstance, project, _, session, invite, util, AppUtil,
                  app, ProjectService, $uibModal, projectRole, userConfig, APIName, $q) {
            // Get current user
            $scope.user = session.getUser();
            $scope.isAdmin = session.isAdmin();
            $scope.userRole = ProjectService.getUserPermission();
            $scope.isGuestUser = function () {
                return $scope.user.role_id === userConfig.GUEST.role;
            };
            //check show button remove member
            $scope.isRemoved = function (mem) {
                return !(mem.project_role_id === projectRole.OWNER.id || mem.project_role_id === $scope.userRole
                    || $scope.userRole === projectRole.VIEWER.id || $scope.userRole === projectRole.PREVIEWER.id
                    || $scope.userRole === projectRole.VIEWER_UPLOADER.id || $scope.userRole === projectRole.PREVIEWER_UPLOADER.id
                    || $scope.userRole === projectRole.UPLOADER.id);
            };

            // Cache member
            var origin = [],
                // Changed member
                changes = [];

            // Create license model
            $scope.members = [];
            $scope.groups = [];

            // List role
            // Should move this list to config file
            $scope.roles = [];
            $scope.roles2 = [3, 4, 5, 6, 7];
            if ($scope.userRole === projectRole.OWNER.id) {
                $scope.roles = [2, 3, 4, 5, 6, 7];
            } else if ($scope.userRole === projectRole.EDITOR.id) {
                $scope.roles = [3, 4, 5, 6, 7];
            }

            var listRole = [
                {id: 2, name: util.translate("label.user.project_role.editor")},
                {id: 3, name: util.translate("label.user.project_role.viewer")},
                {id: 4, name: util.translate("label.user.project_role.previewer")},
                {id: 5, name: util.translate("label.user.project_role.viewer_uploader")},
                {id: 6, name: util.translate("label.user.project_role.previewer_uploader")},
                {id: 7, name: util.translate("label.user.project_role.uploader")}
            ];
            // reset combobox select role when undefined
            $scope.$watch("invite", function () {
                if (!$scope.invite.role) {
                    $scope.invite.role = 3
                }
                if (!$scope.invite.role_group) {
                    $scope.invite.role_group = 3;
                }
            }, true);

            // Get role name
            $scope.getRoleName = function (id) {

                var obj = _.find(listRole, {id: id});

                if (!angular.isDefined(obj))
                    return;
                return obj.name;
            };

            $scope.isChange = false;

            // For tags
            $scope.tags = [];
            $scope.group_tags = [];


            var lastPressTime, mgs, toutId, errNoti;
            var isValidEmail = false;
            $scope.tagTransform = function (newTag) {
                isValidEmail = false;
                lastPressTime = new Date().getTime();

                // validate email address
                // Team Admin and Manager can invite user non-existent in team
                if (AppUtil.isValidEmail(newTag) && (session.getUser().role_id === userConfig.ADMIN.role || session.getUser().role_id === userConfig.MANAGER.role)) {

                    // validate email length (max 65 chars)
                    if (newTag.length > app.MAX_LENGTH_EMAIL) {

                        mgs = util.translate('errors.email_too_long').replace('%d', app.MAX_LENGTH_EMAIL);

                    } else {

                        var obj = _.find($scope.tags, {value: newTag});
                        if (!angular.isDefined(obj)) {

                            if (!_.include($scope.member_emails, newTag)) {
                                isValidEmail = true;
                                var item = {
                                    value: newTag,
                                    user_id: newTag
                                };
                                return item;
                            }
                        }
                    }
                } else {
                    mgs = util.translate('validation.user.invalid_email');
                }

            };


            function setSchedule(callback) {
                return setTimeout(function () {

                    if (new Date().getTime() - lastPressTime >= 3000) {
                        callback && callback();
                    } else {
                        setSchedule(callback);
                    }
                }, 1000);
            }

            $scope.getTags = function (search) {
                return $scope.tags;
            };

            // For tags
            $scope.tagGroupTransform = function (newTag) {
                // Team Admin and Manager can invite group non-existent in team
                if (!AppUtil.isContainSpecialChar(newTag, app.XSS_CHARS + ",/")
                    && (session.getUser().role_id === userConfig.ADMIN.role || session.getUser().role_id === userConfig.MANAGER.role)) {
                    // validate group name length (max 64 chars)
                    if (newTag.length > app.MAX_LENGTH_GROUP_NAME) {
                        $scope.mgs = util.translate('errors.name_too_long').replace('%d', app.MAX_LENGTH_GROUP_NAME);
                    } else {

                        if (newTag) {
                            var isDuplicate = false;
                            var index;
                            for (index in $scope.group_tags) {
                                if (newTag.toLowerCase() === $scope.group_tags[index].value.toLowerCase()) {
                                    isDuplicate = true;
                                    break;
                                }
                            }

                            if (!isDuplicate) {
                                angular.forEach($scope.invite.groups, function (value) {
                                    if (newTag.toLowerCase() === value.value.toLowerCase()) {
                                        isDuplicate = true;
                                    }
                                });
                            }
                            if (!isDuplicate) {
                                return {
                                    value: newTag,
                                    name: newTag
                                };
                            }

                            // var obj = _.find($scope.group_tags, {value: newTag});
                            // if (!angular.isDefined(obj)) {
                            //     if (!_.include($scope.invite.groups, newTag)) {
                            //         var item = {
                            //             value: newTag,
                            //             name: newTag
                            //         };
                            //         return item;
                            //     }
                            // }
                        }
                    }
                }
            };
            $scope.getTagsGroup = function (search) {
                return $scope.group_tags;
            };


            // Not allow external user. Using for tokenfield
            $scope.isAllow = false;

            // Get license info
            // @param {Object} f File object
            function getProjectMembers() {
                session.getProjectMember(project.project_id, project.folder_id, function (res) {
                    $scope.members = res.data.member_projects;
                    $scope.membersGroup = res.data.member_group_projects;
                    if (res.data.group_projects) {
                        for (var i = 0; i < res.data.group_projects.length; i++) {
                            res.data.group_projects[i].status = 1;
                            $scope.members.push(res.data.group_projects[i]);
                        }
                    }
                    var temp = _.filter($scope.members, function (member) {
                        return member.project_role_id === 1
                    });
                    if (temp.length > 0) {

                        for (var i = 0; i < $scope.members.length; i++) {
                            if ($scope.members[i].project_role_id === 1) {
                                $scope.members.splice(i, 1);
                                i--;
                            }
                        }

                        $scope.members = _.sortBy($scope.members, 'first_name');

                        $scope.members.unshift(temp[0]);
                    }
                    origin = angular.copy($scope.members);
                    // Get members
                    getTeamMember();
                    getGroupMember();
                });
            }

            // Get Group member of a team
            function getGroupMember() {
                $scope.group_tags = [];
                var objUrl = {
                    method: APIName.GROUP_USER_LIST_ALL.method,
                    name: APIName.GROUP_USER_LIST_ALL.name
                };

                AppUtil.createRequest(objUrl, {}, function (res) {
                    angular.forEach(res.data, function (value) {
                        $scope.group_tags.push({
                            value: value.name,
                            name: value.name
                        });
                    });
                })
            }

            // Get member of a team
            function getTeamMember() {

                session.getTeamMember(function (res) {
                    // Reset first
                    $scope.tags = [];
                    $scope.member_emails = $scope.members.map(function (item) {
                        return item['email_address'];
                    });
                    $scope.membersGroup.map(function (item) {
                        $scope.member_emails.push(item.email_address);
                    });

                    var language = session.getCurrentLanguage();
                    angular.forEach(res.data, function (d) {
                        var name = d.first_name + ' ' + d.last_name;
                        if (language === 'ja')
                            name = d.last_name + d.first_name;
                        if (_.findIndex($scope.members, {user_id: d.user_id}) === -1
                            && _.findIndex($scope.membersGroup, {user_id: d.user_id}) === -1) {
                            $scope.tags.push({
                                value: d.mail_address,
                                label: name + ' - ' + d.mail_address,
                                user_id: d.user_id,
                                name: name
                            });
                        }
                    });
                });
            }

            // Do get members
            getProjectMembers();

            // Now we have to watch collection
            $scope.$watch('members', function (n) {
                var lChanged = _.filter(n, function (m) {
                    var item = _.find(origin, function (m1) {
                        // Find member changed role
                        if (m.group_id && m1.group_id) {
                            return (m.group_id === m1.group_id && m.project_role_id !== m1.project_role_id) || m.status === 2;
                        } else {
                            return (m.user_id === m1.user_id && m.project_role_id !== m1.project_role_id) || m.status === 2;
                        }

                    });
                    // change role = Viewer when delete combobox
                    if (!m.project_role_id) {
                        m.project_role_id = 3;
                    }
                    // return (item) ? true : false;
                    return !!(item);
                });
                $scope.isChange = lChanged.length > 0;

                // Set changed value
                changes = lChanged;
            }, true);

            // Do remove user
            $scope.doRemove = function (item) {
                // Save change
                $scope.isChange = true;
                var m;
                if (angular.isUndefined(item.user_id)) {
                    m = _.find($scope.members, {group_id: item.group_id});
                } else {
                    m = _.find($scope.members, {user_id: item.user_id});
                }
                // As deleted item
                m.status = 2;
            };

            // Do save change
            var folderId = (project.folder_id) ? project.folder_id : "0";
            $scope.doSaveChange = function () {
                invite.doChangeRole(project.project_id, changes, folderId, function (data) {

                    $scope.isChange = false;

                    getProjectMembers();

                    getTeamMember();
                });
            };

            // Do invite people to project
            $scope.inviting = false;

            $scope.doInvite = function () {

                $scope.isError = false;
                //Do invite people
                if (angular.isUndefined($scope.invite.users) && angular.isUndefined($scope.invite.groups))
                    return;

                $scope.invite.inviting = true;
                var folderId = (project.folder_id) ? project.folder_id : "0";

                var reqs = [];

                if ($scope.invite.users != null && $scope.invite.users.length > 0) {

                    reqs.push(invite.doInvite(project.project_id, folderId, $scope.invite.users,
                        $scope.invite.role, $scope.invite.message, $scope.invite.overwrite_collaborator, function () {
                            // $scope.invite.users = [];
                            // getProjectMembers();
                            // $scope.invite.inviting = false;
                        }, function () {
                            // $scope.invite.inviting = false;
                        })
                    );
                }

                if ($scope.invite.groups != null && $scope.invite.groups.length > 0) {
                    reqs.push($scope.doInviteGroup(project.project_id, folderId, $scope.invite.groups,
                        $scope.invite.role_group, $scope.invite.message, $scope.invite.overwrite, function () {

                            // $scope.invite.groups = [];
                            // getProjectMembers();
                            // $scope.invite.inviting = false;

                        }, function () {
                            // $scope.invite.inviting = false;
                        })
                    );
                }
                if (reqs.length > 0) {
                    // Post all reqs
                    $q.all(reqs).then(function () {
                        $scope.invite.users = [];
                        $scope.invite.groups = [];
                        getProjectMembers();
                        $scope.invite.inviting = false;

                    });
                }


            };

            // Cancel change
            $scope.cancelChange = function () {

                $scope.isChange = false;

                // Revert
                $scope.members = angular.copy(origin);
            };

            // Close modal
            $scope.close = function () {

                $uibModalInstance.close();
            };

            $scope.$on('$destroy', function () {

                $uibModalInstance.close();
            });

            //Get name order
            $scope.getNameOrder = function (first, last) {
                var name = first + " " + last;
                if (session.getCurrentLanguage() !== 'en')
                    name = last + " " + first;
                return name;
            };

            // Show select group address modal
            $scope.showGroupUserModal = function (event) {
                var modalInstance = $uibModal.open({
                    windowClass: 'bootstrap-dialog type-primary',
                    // backdrop: false,
                    templateUrl: 'js/components/invite/select_group_user_modal.html',
                    controller: 'SelectGroupUserModal',
                    resolve: {
                        type: function () {
                            return '';
                        },
                    }
                });
                return modalInstance;
            };
            // Show select group user modal project
            $scope.showGroupUserModal2 = function () {
                return $uibModal.open({
                    windowClass: 'bootstrap-dialog type-primary',
                    // backdrop: false,
                    templateUrl: 'js/components/invite/select_group_user_modal.html',
                    controller: 'SelectGroupUserModal',
                    resolve: {
                        type: function () {
                            return 'name';
                        },
                    }
                });
            };

            var handleSelectGroupUserName = function (event, value) {
                if (!$scope.invite.groups) {
                    $scope.invite.groups = [];
                }
                _.each(value, function (group) {
                    if (!_.find($scope.invite.groups, {value: group.name})) {
                        if (!_.include($scope.groupName, group.name)) {
                            var tag = {
                                value: group.name,
                                name: group.name
                            };
                            $scope.invite.groups.push(tag);
                        }
                    }
                })
            };
            $scope.$on("select_group_user_name", handleSelectGroupUserName);


            var handleSelectGroupUserEmail = function (event, value) {

                if (!$scope.invite.users) {
                    $scope.invite.users = [];
                }
                var currentUser = session.getUser();
                _.each(value, function (user) {
                    if (!_.find($scope.invite.users, {value: user.mail_address})) {
                        if (currentUser.mail_address !== user.mail_address) {

                            if (!_.include($scope.member_emails, user.mail_address)) {
                                var language = session.getCurrentLanguage();
                                var name = user.first_name + ' ' + user.last_name;
                                if (language === 'ja')
                                    name = user.last_name + user.first_name;
                                var tag = {
                                    value: user.mail_address,
                                    label: name + ' - ' + user.mail_address,
                                    user_id: user.user_id,
                                    name: name
                                };
                                $scope.invite.users.push(tag);
                            }
                        }
                    }
                })
            };
            $scope.$on("select_group_user_email", handleSelectGroupUserEmail);


            //open modal
            $scope.openUserProjectInGroupUserModal = function (group_id) {
                return $uibModal.open({
                    windowClass: 'bootstrap-dialog type-primary',
                    backdrop: false,
                    // templateUrl: 'js/components/invite/select_group_user_modal.html',
                    // controller: 'SelectGroupUserModal',
                    templateUrl: 'js/components/invite/show_group_user_collaborator_modal.html',
                    controller: 'ShowGroupUserCollaboratorModal',
                    resolve: {
                        groupId: function () {
                            return group_id;
                        },
                        projectId: function () {
                            return project.project_id;
                        },
                        folderId: function () {
                            return (!project.folder_id) ? "0" : project.folder_id;
                        },
                    }
                });
            };

            // @param {Array} groups Must contain "group_name" key
            $scope.doInviteGroup = function (project_id, folder_id, groups, role, message, overwrite, callback, errorCb) {
                var names = _.map(groups, 'value');
                var params = {
                    overwrite: overwrite,
                    role_id: role,
                    group_names: names.join(),
                    message: message,
                    project_id: project_id
                };

                var folderId = (folder_id) ? folder_id : "0";
                var objUrl = {
                    name: APIName.INVITE_GROUP_USER_PROJECT.name + folderId + APIName.INVITE_GROUP_USER_PROJECT.surfix,
                    method: APIName.INVITE_GROUP_USER_PROJECT.method
                };
                // Request
                return AppUtil.createRequest(objUrl, params, function (data) {
                    AppUtil.createToast({
                        text: util.translate("default_toast.invite_success"),
                        type: 'success'
                    });
                    callback && callback(data);


                }, function (error) {
                    errorCb && errorCb(error);
                    // apply invited successful user
                    callback && callback();
                });
            }
        }]);
