package org.innovateuk.ifs.project.status.populator;

import org.innovateuk.ifs.competition.resource.CompetitionDocumentResource;
import org.innovateuk.ifs.competition.resource.CompetitionResource;
import org.innovateuk.ifs.project.constant.ProjectActivityStates;
import org.innovateuk.ifs.project.document.resource.DocumentStatus;
import org.innovateuk.ifs.project.document.resource.ProjectDocumentResource;
import org.innovateuk.ifs.project.resource.ProjectResource;
import org.innovateuk.ifs.sections.SectionAccess;
import org.innovateuk.ifs.sections.SectionStatus;
import org.springframework.stereotype.Component;

import java.util.List;

import static org.innovateuk.ifs.competition.resource.CompetitionDocumentResource.COLLABORATION_AGREEMENT_TITLE;
import static org.innovateuk.ifs.project.constant.ProjectActivityStates.*;
import static org.innovateuk.ifs.sections.SectionStatus.*;
import static org.innovateuk.ifs.sections.SectionStatus.INCOMPLETE;
import static org.innovateuk.ifs.sections.SectionStatus.MO_ACTION_REQUIRED;

/**
 * This is a helper class for determining the status of a given Project Setup section
 */
@Component
public class SetupSectionStatus {

    public SectionStatus projectDetailsSectionStatus(final boolean projectDetailsProcessCompleted,
                                                     final boolean awaitingProjectDetailsActionFromPartners,
                                                     final boolean isLeadPartner) {
        if (projectDetailsProcessCompleted && !(isLeadPartner && awaitingProjectDetailsActionFromPartners)) {
            return TICK;
        } else {
            return FLAG;
        }
    }

    public SectionStatus projectTeamSectionStatus(final ProjectActivityStates projectTeamStatus) {
        return COMPLETE.equals(projectTeamStatus) ?
                TICK : FLAG;
    }

    public SectionStatus monitoringOfficerSectionStatus(final boolean monitoringOfficerAssigned,
                                                        final boolean requiredProjectDetailsForMonitoringOfficerComplete) {
        if (monitoringOfficerAssigned) {
            return TICK;
        } else {
            return HOURGLASS;
        }

    }

    public SectionStatus bankDetailsSectionStatus(final ProjectActivityStates bankDetails) {
        if (bankDetails == null) {
            return EMPTY;
        } else if (PENDING.equals(bankDetails)) {
            return HOURGLASS;
        } else if (COMPLETE.equals(bankDetails)) {
            return TICK;
        } else {
            return FLAG;
        }
    }

    public SectionStatus financeChecksSectionStatus(final ProjectActivityStates financeCheckState,
                                                    final SectionAccess access) {

        if (access.equals(SectionAccess.NOT_ACCESSIBLE)) {
            return EMPTY;
        } else if (financeCheckState.equals(COMPLETE)) {
            return TICK;
        } else if (financeCheckState.equals(ACTION_REQUIRED)) {
            return FLAG;
        } else {
            return HOURGLASS;
        }
    }

    public SectionStatus spendProfileSectionStatus(final ProjectActivityStates spendProfileState, boolean isProjectMO) {

        if (isProjectMO){
            return spendProfileStatusDisplayForMO(spendProfileState);
        }
        else{
            switch (spendProfileState) {
                case PENDING:
                    return HOURGLASS;
                case ACTION_REQUIRED:
                    return FLAG;
                case LEAD_ACTION_REQUIRED:
                    return LEAD_ACTION_FLAG;
                case COMPLETE:
                    return TICK;
                default:
                    return EMPTY;
            }
        }
    }
    private SectionStatus spendProfileStatusDisplayForMO(ProjectActivityStates spendProfileState) {
        switch (spendProfileState) {
            case NOT_STARTED:
                return INCOMPLETE;
            case PENDING:
                return HOURGLASS;
            case ACTION_REQUIRED:
                return FLAG;
            case LEAD_ACTION_REQUIRED:
                return INCOMPLETE;
            case COMPLETE:
                return TICK;
            default:
                return EMPTY;
        }
    }

    public SectionStatus projectSetupCompleteStatus(final ProjectActivityStates setupSectionState) {
        if (setupSectionState.equals(COMPLETE)) {
            return TICK;
        } else if (setupSectionState.equals(PENDING)) {
            return HOURGLASS;
        } else {
            return EMPTY;
        }
    }

    public SectionStatus documentsSectionStatus(final boolean isProjectManager,
                                                ProjectResource project,
                                                CompetitionResource competition,
                                                final boolean isProjectMO) {
        List<CompetitionDocumentResource> competitionDocuments = competition.getCompetitionDocuments();
        List<ProjectDocumentResource> projectDocuments = project.getProjectDocuments();

        if (!project.isCollaborativeProject()) {
            competitionDocuments.removeIf(
                    document -> document.getTitle().equals(COLLABORATION_AGREEMENT_TITLE));
            projectDocuments.removeIf(
                    document -> document.getCompetitionDocument().getTitle().equals(COLLABORATION_AGREEMENT_TITLE));
        }

        int actualNumberOfDocuments = projectDocuments.size();
        int expectedNumberOfDocuments = competitionDocuments.size();

        boolean allDocumentsAreSubmitted = actualNumberOfDocuments == expectedNumberOfDocuments;
        boolean allDocumentsAreApproved = allDocumentsAreSubmitted && projectDocuments.stream()
                .allMatch(projectDocumentResource -> DocumentStatus.APPROVED.equals(projectDocumentResource.getStatus()));
        boolean hasDocumentForApproval = projectDocuments.stream().anyMatch(projectDocumentResource -> DocumentStatus.SUBMITTED.equals(projectDocumentResource.getStatus()));
        boolean hasAnyDocumentUploadedOrRejected = projectDocuments.stream().anyMatch(projectDocumentResource -> DocumentStatus.UPLOADED.equals(projectDocumentResource.getStatus())
                || DocumentStatus.REJECTED.equals(projectDocumentResource.getStatus())
                || DocumentStatus.REJECTED_DUE_TO_TEAM_CHANGE.equals(projectDocumentResource.getStatus()));

        if (allDocumentsAreApproved) {
            return TICK;
        }

        if (isProjectMO) {
            if (hasDocumentForApproval) {
                return MO_ACTION_REQUIRED;
            }
            else {
                return INCOMPLETE;
            }
        }
            if (!allDocumentsAreSubmitted || hasAnyDocumentUploadedOrRejected) {
                return isProjectManager ? FLAG : EMPTY;
            }

            return HOURGLASS;
    }

            public SectionStatus grantOfferLetterSectionStatus(final ProjectActivityStates grantOfferLetterState,
                                                       final boolean isLeadPartner) {
        if (grantOfferLetterState == null || NOT_REQUIRED.equals(grantOfferLetterState)) {
            return EMPTY;
        } else if (COMPLETE.equals(grantOfferLetterState)) {
            return TICK;
        } else if (isLeadPartner && ACTION_REQUIRED.equals(grantOfferLetterState)) {
            return FLAG;
        } else {
            return HOURGLASS;
        }
    }

}
@@ -3188,129 +3188,8 @@
 O) %7B
-%0A%0A        if (isProjectMO)%7B%0A            return spendProfileStatusDisplayForMO(spendProfileState);%0A        %7D%0A        else%7B
 %0A   
@@ -3239,39 +3239,43 @@
            case 
-PENDING
+NOT_STARTED
 :%0A              
@@ -3283,36 +3283,36 @@
      return 
-HOURGLASS
+INCOMPLETE
 ;%0A
- 
             
@@ -3315,39 +3315,31 @@
        case 
-ACTION_REQUIRED
+PENDING
 :%0A          
@@ -3359,534 +3359,178 @@
 urn 
-FLAG;%0A                case LEAD_ACTION_REQUIRED:%0A                    return LEAD_ACTION_FLAG;%0A                case COMPLETE:%0A                    return TICK;%0A                default:%0A                    return EMPTY;%0A            %7D%0A        %7D%0A    %7D%0A    private SectionStatus spendProfileStatusDisplayForMO(ProjectActivityStates spendProfileState) %7B%0A        switch (spendProfileState) %7B%0A            case NOT_STARTED:%0A                return INCOMPLETE;%0A            case PENDING:%0A                return HOURGLASS;%0A            case 
+isProjectMO ? MO_ACTION_REQUIRED : HOURGLASS;%0A                case ACTION_REQUIRED:%0A                    return isProjectMO ? INCOMPLETE : FLAG;%0A                case LEAD_
 ACTI
@@ -3562,37 +3562,45 @@
     
+    
 return 
-FLAG;%0A            case
+isProjectMO ? INCOMPLETE :
  LEA
@@ -3612,53 +3612,18 @@
 ION_
-REQUIRED:
+FLAG;
 %0A    
-            return INCOMPLETE;%0A
     
@@ -3645,16 +3645,20 @@
 MPLETE:%0A
+    
         
@@ -3690,16 +3690,20 @@
         
+    
 default:
@@ -3711,32 +3711,36 @@
                 
+ 
+   
 return EMPTY;%0A  
@@ -3737,34 +3737,42 @@
  EMPTY;%0A        
-%7D%0A
+    %7D%0A    
     %7D%0A%0A    publi

test issues fixed