package org.xcolab.view.pages.contestmanagement.wrappers;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.xcolab.client.activities.ActivitiesClientUtil;
import org.xcolab.client.contest.ContestTeamMemberClientUtil;
import org.xcolab.client.contest.pojo.team.ContestTeamMember;
import org.xcolab.client.members.MembersClient;
import org.xcolab.util.enums.activity.ActivityEntryType;
import org.xcolab.util.http.exceptions.UncheckedEntityNotFoundException;
import org.xcolab.view.pages.contestmanagement.beans.ContestTeamBean;
import org.xcolab.view.pages.loginregister.SharedColabUtil;
import org.xcolab.view.util.entity.enums.MemberRole;

import java.util.List;

public class ContestTeamWrapper {

    private static final Logger log = LoggerFactory.getLogger(ContestTeamWrapper.class);

    private final ContestTeamBean contestTeamBean;
    private final Long contestId;

    public ContestTeamWrapper(ContestTeamBean contestTeamBean) {
        this.contestTeamBean = contestTeamBean;
        this.contestId = contestTeamBean.getContestId();
    }

    public void updateContestTeamMembers() {
        removeAllContestTeamMembersForContest();
        assignMemberToContest(MemberRole.JUDGE, contestTeamBean.getUserIdsJudges());
        assignMemberToContest(MemberRole.ADVISOR, contestTeamBean.getUserIdsAdvisors());
        assignMemberToContest(MemberRole.FELLOW, contestTeamBean.getUserIdsFellows());
        assignMemberToContest(MemberRole.CONTEST_MANAGER,
                contestTeamBean.getUserIdsContestManagers());
        assignMemberToContest(MemberRole.IMPACT_ASSESSMENT_FELLOW,
                contestTeamBean.getUserIdsIAFellows());
    }

    private void assignMemberToContest(MemberRole memberRole, List<Long> userIds) {
        assignMembersToContestWithRole(userIds, memberRole);
        assignMemberRoleToUser(memberRole, userIds);
        subscribeUsersToContest(userIds);
        crossColabRegisterUsersForSharedContests(userIds);
    }

    private void crossColabRegisterUsersForSharedContests(List<Long> userIds) {

        for (Long id : userIds) {
            SharedColabUtil.checkTriggerForAutoUserCreationInContest(contestId, id);
        }
    }

    private void assignMemberRoleToUser(MemberRole memberRole, List<Long> userIds) {
        Long roleId = memberRole.getRoleId();
        for (Long userId : userIds) {
            MembersClient.assignMemberRole(userId, roleId);
        }
    }

    private void assignMembersToContestWithRole(List<Long> userIds, MemberRole memberRole) {
        for (Long userId : userIds) {
            ContestTeamMember contestTeamMember = new ContestTeamMember();
            contestTeamMember.setContestId(contestId);
            contestTeamMember.setUserId(userId);
            contestTeamMember.setRoleId(memberRole.getRoleId());
            ContestTeamMemberClientUtil.createContestTeamMember(contestTeamMember);
        }
    }

    private void subscribeUsersToContest(List<Long> userIds) {
        for (Long userId : userIds) {
            ActivitiesClientUtil.addSubscription(userId, ActivityEntryType.CONTEST, contestId, "");
        }
    }

    private void removeAllContestTeamMembersForContest() {
        List<ContestTeamMember> contestTeamMembers =
                ContestTeamMemberClientUtil.getTeamMembers(contestId);
        for (ContestTeamMember contestTeamMember : contestTeamMembers) {
            try {
                ContestTeamMemberClientUtil.deleteContestTeamMember(contestTeamMember.getId_());
            } catch (UncheckedEntityNotFoundException e) {
                log.warn("ContestTeamMember {} already deleted", contestTeamMember.getId_());
            }
        }
    }
}

@@ -3153,27 +3153,35 @@
  void remove
-All
+TeamMember(
 ContestTeamM
@@ -3185,28 +3185,34 @@
 amMember
-sForC
+ c
 ontest
-(
+TeamMember
 ) %7B%0A    
@@ -3215,21 +3215,68 @@
         
-List%3C
+try %7B%0A            ContestTeamMemberClientUtil.delete
 ContestT
@@ -3284,18 +3284,17 @@
 amMember
-%3E 
+(
 contestT
@@ -3306,80 +3306,225 @@
 mber
-s =%0A                ContestTeamMemberClientUtil.getTeamMembers(contest
+.getId_());%0A        %7D catch (UncheckedEntityNotFoundException e) %7B%0A            log.warn(%22ContestTeamMember %7B%7D already deleted%22, contestTeamMember.getId_());%0A        %7D%0A        Long userId = contestTeamMember.getUser
 Id
+(
 );%0A 
@@ -3534,14 +3534,23 @@
     
-for (C
+Long roleId = c
 onte
@@ -3565,68 +3565,171 @@
 mber
- contestTeamMember : contestTeamMembers) %7B%0A            try %7B
+.getRoleId();%0A        if (ContestTeamMemberClientUtil.getTeamMembers(userId, null, roleId).isEmpty()) %7B%0A            MembersClient.removeMemberRole(userId, roleId);
 %0A   
@@ -3737,50 +3737,90 @@
     
+%7D%0A%0A
     
+%7D%0A%0A
     
-ContestTeamMemberClientUtil.delete
+private void removeAllContestTeamMembersForContest() %7B%0A        List%3C
 Cont
@@ -3824,33 +3824,34 @@
 ontestTeamMember
-(
+%3E 
 contestTeamMembe
@@ -3847,35 +3847,27 @@
 stTeamMember
-.getId_());
+s =
 %0A           
@@ -3871,119 +3871,129 @@
     
-%7D catch (UncheckedEntityNotFoundException e) %7B%0A                log.warn(%22ContestTeamMember %7B%7D already deleted%22,
+    ContestTeamMemberClientUtil.getTeamMembers(null, contestId, null);%0A        for (ContestTeamMember contestTeamMember :
  con
@@ -4002,35 +4002,28 @@
 stTeamMember
-.getId_());
+s) %7B
 %0A           
@@ -4015,33 +4015,68 @@
 ) %7B%0A            
-%7D
+removeTeamMember(contestTeamMember);
 %0A        %7D%0A    %7D

implement platform-wide role removal