/*GROUP ACTIONS*/

        /*
         * Returns List of users groups with modified UserState_ID  == user
         * users - list of usernames which will be modified
         * if exception then returns current list of groups
         * DOESN'T CHECK CURRENT USERS ROLES!!!
         */
        public async Task<IList<Group>> ChangeCourseUserGroupAsync(IEnumerable<String> users, ApplicationDbContext appContext, Course course, CourseUsers user, Boolean addNever = true)
        {
            List<Group> groups = new List<Group>();
            try
            {
                if (users != null && course != null)
                {
                    Int32 userType = (Int32)user;
                    Group currGroup = null;
                    String currUser = null;
                    for (Int32 i = 0; i < users.Count(); i++)
                    {
                        currUser = users.ElementAt(i);
                        currGroup = await appContext.Groups
                            .Where(g => String.Compare(g.User.UserName, currUser, true) == 0 && g.Course_ID == course.ID)
                            .FirstAsync();
                        if (!addNever || currGroup.UserState_ID != userType)
                        {
                            currGroup.UserState_ID = userType;
                            groups.Add(currGroup);
                        }
                    }
                }
                return groups;
            }
            catch (InvalidOperationException)
            {
                return groups;
            }
            catch (NullReferenceException)
            {
                return groups;
            }
        }
        public void Participate(string userId, int courseId)
        {
            CourseUsers courseUsers = repository.CourseUsers
                                      .FirstOrDefault(c => c.AppUserId == userId && c.CourseId == courseId);

            if (courseUsers == null)
            {
                //add user to course
                repository.AddUserToCourse(userId, courseId);

                //notification
                _ = ShowNewUserNotification(userId, courseId);

                _ = HideParticipateBtn(userId, courseId);
            }
        }
        /*
         * returns users with current UserState(user) for mainGroup(group)
         * if checkName then checks if groupName == null (userHasn't any group) || comparesName - user is in current Group 
         */
        public async Task RefreshGroupOfUsersTypeAsync(IEnumerable<String> userNames, Group group, ApplicationDbContext appContext, CourseUsers userType, CourseUsers defaultType)
        {
            if (userNames == null)
            {
                Group[] groups = await appContext.Groups
                .Where(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == (Int32)userType).ToArrayAsync();
                foreach (var gr in groups)
                {
                    gr.UserState_ID = (Int32)defaultType;
                    gr.Name = null;
                    appContext.Entry(gr).State = EntityState.Modified;
                }
            }
            else
            {
                /*updating role for users*/
                Int32 currentRole = (Int32)userType;
                Group[] groups = await appContext.Users
                    .Where(u => userNames.Contains(u.UserName))
                    .Select(u => u.Groups.FirstOrDefault(g => g.Course_ID == group.Course_ID))
                    .ToArrayAsync();
                foreach (var i in groups)
                {
                    i.Name = group.Name;
                    i.UserState_ID = (Int32)userType;
                    appContext.Entry(i).State = EntityState.Modified;
                }

                ApplicationUser[] users = await appContext.Users
                    .Where(u => !userNames.Contains(u.UserName)).ToArrayAsync();
                Group selected = null;
                if (users != null)
                {
                    foreach (var user in users)
                    {
                        if (user.Groups.Any(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == currentRole))
                        {
                            selected = user.Groups.First(g => String.Compare(g.Name, group.Name, false) == 0 && g.UserState_ID == currentRole);
                            selected.Name = null;
                            selected.UserState_ID = (Int32)defaultType;
                            appContext.Entry(selected).State = EntityState.Modified;
                        }
                    }
                }
            }
        }
 /*
  * Checks users role with applied roles
  * and if he has applied role then returns this role
  * else returns default role
  */
 private CourseUsers CheckUserForRoles(IEnumerable<String> roles, IEnumerable<String> userRoles, CourseUsers defaultRole)
 {
     try
     {
         CourseUsers userRole;
         for (Int32 j = 0; j < roles.Count(); j++)
         {
             if (userRoles.Contains(roles.ElementAt(j)))
             {
                 userRole = (CourseUsers)Enum.Parse(typeof(CourseUsers), roles.ElementAt(j));
                 return userRole;
             }
         }
         return defaultRole;
     }
     catch (ArgumentException)
     {
         return defaultRole;
     }
 }
 /*
  * Search users to change their roles
  * for example if someone deleted user from group
  * user status changes to defaultUser status
  * USE DBSAVECHANGES AFTER THIS METHOD
  */
 public async Task<IList<Group>> ClearUsersWithOldRoles(IEnumerable<String> users, Group group, ApplicationDbContext appContext, CourseUsers defaultUser)
 {
     IEnumerable<ApplicationUser> foundUsers = await appContext.Users.Where(u => !users.Contains(u.UserName)).ToArrayAsync();
     List<Group> editableGroups = new List<Group>();
     Course course = await appContext.Courses.FindAsync(group.Course_ID);
     if (foundUsers != null && course != null)
     {
         ApplicationUser foundUser = null;
         for (Int32 i = 0; i < foundUsers.Count(); i++)
         {
             foundUser = foundUsers.ElementAt(i);
             editableGroups.AddRange(await appContext.Groups.Where(g => g.Course_ID == course.ID && g.User.Id == foundUser.Id).ToArrayAsync());
         }
         foreach (var gr in editableGroups)
         {
             gr.UserState_ID = (Int32)defaultUser;
             gr.Name = null;
         }
     }
     return editableGroups;
 }
 /*
  * Gets all users of current group(user) type
  * if exception then returns current list of users
  */
 public async Task<IList<ApplicationUser>> GetUsersFromGroupsAsync(ApplicationDbContext appContext, Course course, CourseUsers userType, Boolean checkGroupName = false)
 {
     List<ApplicationUser> users = new List<ApplicationUser>();
     try
     {
         if (course != null)
         {
             Int32 userState = (Int32)userType;
             /*adds users with groups where names == null which means that user is not in any main group*/
             users.AddRange(await appContext.Users.Where
                 (
                     u => u.Groups
                     .Any(gr => gr.Course_ID == course.ID && gr.UserState_ID == userState && checkGroupName ? gr.Name == null : true)
                 )
                 .ToListAsync());
         }
         return users;
     }
     catch (NullReferenceException)
     {
         return users;
     }
 }
 public async Task<IList<ApplicationUser>> GetUsersFromMainGroupAsync(ApplicationDbContext appContext, Group group, CourseUsers user, Boolean checkName = false)
 {
     List<ApplicationUser> users = new List<ApplicationUser>();
     try
     {
         if (group != null)
         {
             Int32 userState = (Int32)user;
             /*adds users with groups where names == null which means that user is not in any main group*/
             users.AddRange(await appContext.Users.Where
                 (
                     u => u.Groups
                     .Any(gr => gr.Course_ID == group.Course_ID && gr.UserState_ID == userState && (checkName ? String.Compare(group.Name, gr.Name, false) == 0 : gr.Name == null))
                 )
                 .ToListAsync());
         }
         return users;
     }
     catch (NullReferenceException)
     {
         return users;
     }
 }