package com.agilex.healthcare.schedulingmanager.dataservice;

import com.agilex.healthcare.mobilehealthplatform.domain.*;
import com.agilex.healthcare.mobilehealthplatform.security.MhpUserFactory;
import com.agilex.healthcare.schedulingmanager.datalayer.appointment.AppointmentRequestDataLayer;
import com.agilex.healthcare.schedulingmanager.datalayer.appointment.AppointmentRequestFilter;
import com.agilex.healthcare.schedulingmanager.domain.*;
import com.agilex.healthcare.schedulingmanager.enumeration.AppointmentRequestStatus;
import com.agilex.healthcare.schedulingmanager.exception.InvalidAppointmentRequestException;
import com.agilex.healthcare.schedulingmanager.exception.InvalidAppointmentRequestMessageException;
import com.agilex.healthcare.schedulingmanager.utils.DefaultAssigningAuthorityUpdater;
import com.agilex.healthcare.schedulingmanager.validator.AppointmentRequestMessageValidator;
import com.agilex.healthcare.schedulingmanager.validator.AppointmentRequestMessageValidatorFactory;
import com.agilex.healthcare.schedulingmanager.validator.AppointmentRequestValidator;
import com.agilex.healthcare.schedulingmanager.validator.AppointmentRequestValidatorFactory;
import com.agilex.healthcare.utility.DateHelper;
import com.agilex.healthcare.utility.NullChecker;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Component
public class AppointmentRequestDataService {

    private final static org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory.getLog(AppointmentRequestDataService.class);

    @Resource(name = "appointmentRequestDataLayer")
    AppointmentRequestDataLayer appointmentRequestDataLayer;

    @Resource
    PatientCorrelationService patientCorrelationService;


	private static final int EarliestTimeVeteranCanRequestAppointmentInHours = 96;
	private static final int FarthestTimeVeteranCanRequestAppointmentInDays = 120;
    private static final int messageLimitPerSender = 2;

	private static final String LAST_UPDATED_DATE = "lastUpdatedDate";
//	private static final String PRIMARY_CARE_MAX_LIMIT_ERROR_MSG = "**Number of Request Exceeded**<br/>You can submit one primary care appointment request at a time. "
//			+ "Another request may be submitted after the current primary care request is processed by the VA, or you may return to the previous screen, cancel the pending request, and submit a new one.";
//	private static final String MENTAL_HEALTH_MAX_LIMIT_ERROR_MSG = "**Number of Request Exceeded**<br/>You can only have two pending mental health appointment requests at a time. "
//			+ "Another request may be submitted after one or more existing mental health appointment requests are processed by the VA, or you may return to the previous screen, cancel a pending request, and submit a new one.";
//	private static final String FACILITY_NOT_FOUND_ERROR_MSG = "The requested facility was not found.  Please choose the desired facility using the autocomplete feature.";
	private static final String STATUS_NOT_FOUND_ERROR_MSG = "The appointment request is missing a valid status.";
	private static final String INVALID_STATUS_ERROR_MSG = "The requested appointment request status is invalid.";
    private static final String APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_FOR_CANCELLED_APPOINTMENT = "Appointment request messages are not allowed for cancelled appointment requests.";
    private static final String APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_AFTER_APPOINTMENT_DATE_PASSED = "Appointment request messages are not allowed after appointment date has passed.";
    private static final String APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_UNTIL_REPLY = "New appointment request message not allowed until reply received.";
    private static final String APPOINTMENT_REQUEST_MSG_LIMIT_REACHED = "Maximum allowed number of messages for this appointment request reached.";
    private static final String EDIPI_ASSIGNING_AUTHORITY  = "EDIPI";
    private static final String VAR_DATA_IDENTIFIER = "var";

	public AppointmentRequestDataService() {
	}

//	public SMAppointmentRequests getPatientAppointmentRequests(PatientIdentifier patientIdentifier, DateFilter dateFilter) {
//		RequestMessage request = PatientDataFetchRequestBuilder.forRetrieveList().forDomain(Domain.SMAppointmentRequest).forPatientIdentifier(patientIdentifier).forScopeFilter(scopeFilter).forDateFilter(dateFilter).excludeDetails().build();
//		ResponseMessage responseMessage = router.execute(request);
//
//		SMAppointmentRequests SMAppointmentRequests = readAppointmentRequestsFromRouterResponseAndSortDescendingByLastUpdatedDate(responseMessage);
//		return SMAppointmentRequests;
//	}

//	public Facilities fetchMostRecentFacilities(PatientIdentifier patientIdentifier, ScopeFilter scopeFilter) {
//		SMAppointmentRequests patientAppointmentRequests = getPatientAppointmentRequests(patientIdentifier, DateFilterFactory.createEmptyFilter(), scopeFilter);
//		patientAppointmentRequests.sortDescending("createdDate");
//
//		Facilities facilities = new Facilities();
//
//		for (SMAppointmentRequest SMAppointmentRequest : patientAppointmentRequests) {
//			Facility facility = SMAppointmentRequest.getFacility();
//
//			if (facilities.size() < 3) {
//				if (!facilities.contains(facility)) {
//					facilities.add(facility);
//				}
//			} else {
//				break;
//			}
//		}
//
//		return facilities;
//	}

	public SMAppointmentRequests getAppointmentRequests(AppointmentRequestFilter filter, boolean freshStart, HashMap<String, Boolean> sortFields, String filterString, int  firstRecord, int  lastRecord) {
		SMAppointmentRequests SMAppointmentRequests = sortAppointmentsRequestsAscendingByLastUpdatedDate(appointmentRequestDataLayer.fetchAppointmentRequests(filter, freshStart, sortFields, filterString, firstRecord, lastRecord));
		SMAppointmentRequests filteredSMAppointmentRequests = excludeAppointmentRequestsCancelledByVeteranBeforeBeingBooked(SMAppointmentRequests);
        fixPatientAndDataIdentifier(SMAppointmentRequests);
		return filteredSMAppointmentRequests;
	}

    public SMAppointmentRequests getAppointmentRequestsNoSort(AppointmentRequestFilter filter, boolean freshStart, HashMap<String, Boolean> sortFields, String filterString, int  firstRecord, int  lastRecord) {
        SMAppointmentRequests smAppointmentRequests = appointmentRequestDataLayer.fetchAppointmentRequests(filter, freshStart, sortFields, filterString, firstRecord, lastRecord);
        fixPatientAndDataIdentifier(smAppointmentRequests);
        return smAppointmentRequests;
    }


	private SMAppointmentRequests excludeAppointmentRequestsCancelledByVeteranBeforeBeingBooked(SMAppointmentRequests SMAppointmentRequests) {
		SMAppointmentRequests filteredSMAppointmentRequests = new SMAppointmentRequests();

		for (SMAppointmentRequest SMAppointmentRequest : SMAppointmentRequests) {
			if (isCancelledAppointmentRequest(SMAppointmentRequest)) {
				if (doesAppointmentRequestContainDetailCode(SMAppointmentRequest)) {
					filteredSMAppointmentRequests.add(SMAppointmentRequest);
				}
			} else {
				filteredSMAppointmentRequests.add(SMAppointmentRequest);
			}
		}

		return filteredSMAppointmentRequests;
	}

	private boolean doesAppointmentRequestContainDetailCode(SMAppointmentRequest SMAppointmentRequest) {
		List<SMAppointmentRequestDetailCode> arDetailCodes = SMAppointmentRequest.getAppointmentRequestDetailCode();
		if (NullChecker.isNotNullish(arDetailCodes)) {
			return true;
		}
		return false;
	}

	private boolean isCancelledAppointmentRequest(SMAppointmentRequest SMAppointmentRequest) {
		if (AppointmentRequestStatus.CANCELLED.getName().equalsIgnoreCase(SMAppointmentRequest.getStatus())) {
			return true;
		}
		return false;
	}

//	private SMAppointmentRequests readAppointmentRequestsFromRouterResponseAndSortDescendingByLastUpdatedDate(ResponseMessage responseMessage) {
//		SMAppointmentRequests SMAppointmentRequests = PatientDataResponseReader.<SMAppointmentRequests, SMAppointmentRequest> fromResponse(responseMessage).getDataListNoNull(SMAppointmentRequests.class);
//		//SMAppointmentRequests.sortDescending(LAST_UPDATED_DATE);
//		return SMAppointmentRequests;
//	}

	private SMAppointmentRequests sortAppointmentsRequestsAscendingByLastUpdatedDate(SMAppointmentRequests SMAppointmentRequests) {
		SMAppointmentRequests.sortAscending(LAST_UPDATED_DATE);
		return SMAppointmentRequests;
	}

	public SMAppointmentRequest getPatientAppointmentRequest(PatientIdentifier patientIdentifier, DataIdentifier dataIdentifier) {
		SMAppointmentRequest SMAppointmentRequest =  appointmentRequestDataLayer.fetchAppointmentRequest(patientIdentifier.getUniqueId(), dataIdentifier.getUniqueId());
        SMAppointmentRequest.setPatientIdentifier(patientIdentifier);
        SMAppointmentRequest.getDataIdentifier().setSystemId(VAR_DATA_IDENTIFIER);
		return SMAppointmentRequest;
	}

	public SMAppointmentRequestMessages fetchAppointmentRequestMessages(PatientIdentifier patientIdentifier, DataIdentifier dataIdentifier) {
		SMAppointmentRequestMessages smAppointmentRequestMessages =  appointmentRequestDataLayer.fetchAppointmentRequestMessages(patientIdentifier.getUniqueId(), dataIdentifier.getUniqueId());
        fixPatientAndDataIdentifier(smAppointmentRequestMessages,patientIdentifier,dataIdentifier.getUniqueId());
        SMAppointmentRequestMessages messages = sortMessagesDescendingByMessageDateTime(smAppointmentRequestMessages);
		return messages;
	}

	private SMAppointmentRequestMessages sortMessagesDescendingByMessageDateTime(SMAppointmentRequestMessages smAppointmentRequestMessages) {
        smAppointmentRequestMessages.sortDescending("messageDateTime");
		return smAppointmentRequestMessages;
	}

	public SMAppointmentRequest saveAppointmentRequest(List<String> pilotSites, SMAppointmentRequest smAppointmentRequest, String haMode, boolean fullValidation) {
		Patient patient = null;
//		if (haMode.equalsIgnoreCase(RunningMode.VETERAN.getName())) {
//			patient = MhpUserFactory.createFromSecurityContext().getPatient();
//		} else {
			patient = smAppointmentRequest.getPatient();
//		}

		if (NullChecker.isNullish(patient.getPatientIdentifier().getUniqueId())) {
			patient.setPatientIdentifier(smAppointmentRequest.getPatientIdentifier());
		}

		patient.setTextMessagingAllowed(smAppointmentRequest.isTextMessagingAllowed());
		patient.setTextMessagingPhoneNumber(smAppointmentRequest.getTextMessagingPhoneNumber());

		smAppointmentRequest.setPatient(patient);
		if (smAppointmentRequest.getParentRequest() != null) {
			smAppointmentRequest.getParentRequest().setPatient(patient);
		}

		validateAppointmentRequest(pilotSites, smAppointmentRequest, fullValidation);

        addSurrogate(smAppointmentRequest);
        SMAppointmentRequest result = appointmentRequestDataLayer.saveAppointmentRequest(smAppointmentRequest);
        result.setPatientIdentifier(smAppointmentRequest.getPatientIdentifier());
        result.setDataIdentifier(smAppointmentRequest.getDataIdentifier());
		return result;
	}

	public SMAppointmentRequestMessage saveAppointmentRequestMessage(SMAppointmentRequestMessage SMAppointmentRequestMessage) {
        SMAppointmentRequest associatedSMAppointmentRequest = getPatientAppointmentRequest(SMAppointmentRequestMessage.getPatientIdentifier(), SMAppointmentRequestMessage.getDataIdentifier());
        validateAppointmentRequestMessage(SMAppointmentRequestMessage, associatedSMAppointmentRequest);
        addSurrogate(SMAppointmentRequestMessage);
        SMAppointmentRequestMessage message = appointmentRequestDataLayer.saveAppointmentRequestMessage(SMAppointmentRequestMessage.getPatientIdentifier().getUniqueId(), SMAppointmentRequestMessage, MhpUserFactory.doesUserHasStaffRole());
		return message;
	}

    private void validateAppointmentRequestMessage(SMAppointmentRequestMessage SMAppointmentRequestMessage, SMAppointmentRequest associatedSMAppointmentRequest) {

        AppointmentRequestMessageValidator validator = AppointmentRequestMessageValidatorFactory.createAppointmentRequestMessageValidator();

        if (validator != null) {
            ValidationResult<SMAppointmentRequestMessage> validationResult = validator.validate(SMAppointmentRequestMessage);
            if (!validationResult.isValid()) {
                throw new InvalidAppointmentRequestMessageException(validationResult.getErrors());
            }
        }

        throwAnErrorIfAppointmentRequestIsCancelled(associatedSMAppointmentRequest, SMAppointmentRequestMessage);
        throwAnErrorIfAppointmentRequestDateHasPassed(associatedSMAppointmentRequest, SMAppointmentRequestMessage);
        throwAnErrorIfNewMessageHasNotReceivedReply(associatedSMAppointmentRequest, SMAppointmentRequestMessage);
        throwAnErrorIfMessageLimitReached(associatedSMAppointmentRequest, SMAppointmentRequestMessage);
    }

    public SMAppointmentRequest updateAppointmentMessageFlag(String appointmentRequestId, PatientIdentifier patientIdentifier, DataIdentifier dataIdentifier){
		SMAppointmentRequest SMAppointmentRequest = appointmentRequestDataLayer.updateMessageFlag(patientIdentifier.getUniqueId(), appointmentRequestId, MhpUserFactory.doesUserHasStaffRole());
        MhpUserFactory.addSurrogateToPatientData(SMAppointmentRequest);
        return SMAppointmentRequest;
	}
	
//	public SMAppointmentRequest deleteAppointmentRequest(SMAppointmentRequest SMAppointmentRequest, ScopeFilter scopeFilter) {
//        addSurrogate(SMAppointmentRequest);
//		RequestMessage request = PatientDataEditRequestBuilder.forDelete().forDomain(Domain.SMAppointmentRequest).forScope(scopeFilter).forData(SMAppointmentRequest).build();
//		ResponseMessage responseMessage = router.execute(request);
//		return PatientDataResponseReader.<SMAppointmentRequests, SMAppointmentRequest> fromResponse(responseMessage).getDataItem();
//	}

	private void validateAppointmentRequest(List<String> pilotSites, SMAppointmentRequest SMAppointmentRequest, boolean fullValidation) {
		if (fullValidation) {
			if (AppointmentRequestStatus.SUBMITTED.getName().equalsIgnoreCase(SMAppointmentRequest.getStatus()) && !SMAppointmentRequest.isSecondRequest()) {
//				validateMaximumNumberOfAppointmentRequests(SMAppointmentRequest);
			}
		}

		AppointmentRequestValidator validator = AppointmentRequestValidatorFactory.createAppointmentRequestValidator(EarliestTimeVeteranCanRequestAppointmentInHours, FarthestTimeVeteranCanRequestAppointmentInDays);

		if (validator != null) {
			ValidationResult<SMAppointmentRequest> validationResult = validator.validate(SMAppointmentRequest, fullValidation);
			if (!validationResult.isValid()) {
				throw new InvalidAppointmentRequestException(validationResult.getErrors());
			}
		}

//		validateFacilityCode(pilotSites, SMAppointmentRequest);
		validateStatus(SMAppointmentRequest);
	}

	private void validateStatus(SMAppointmentRequest SMAppointmentRequest) {
		String status = SMAppointmentRequest.getStatus();

		if (NullChecker.isNotNullish(status)) {
			boolean found = false;
			AppointmentRequestStatus[] statuses = AppointmentRequestStatus.values();
			for (AppointmentRequestStatus statusEnum : statuses) {
				if (status.equals(statusEnum.getName())) {
					found = true;
					break;
				}
			}

			if (!found) {
				ValidationResult<SMAppointmentRequest> validationResult = createOpenAppointmentRequestValidationError(SMAppointmentRequest, INVALID_STATUS_ERROR_MSG);
				throw new InvalidAppointmentRequestException(validationResult.getErrors());
			}
		} else {
			ValidationResult<SMAppointmentRequest> validationResult = createOpenAppointmentRequestValidationError(SMAppointmentRequest, STATUS_NOT_FOUND_ERROR_MSG);
			throw new InvalidAppointmentRequestException(validationResult.getErrors());
		}
	}

//	private void validateFacilityCode(List<String> pilotSites, SMAppointmentRequest SMAppointmentRequest) {
//		boolean notFound = false;
//		try {
//            //TODO
//
//			String facilityCode = SMAppointmentRequest.getFacility().getFacilityCode();
//			FacilityDataService facilityDataService = new FacilityDataService();
//			Facility facility = facilityDataService.fetchFacilityByCode(pilotSites, facilityCode);
//
//			if (facility == null) {
//				notFound = true;
//			}
//		} catch (WebApplicationException e) {
//			notFound = true;
//		}
//
//		if (notFound) {
//			ValidationResult<SMAppointmentRequest> validationResult = createValidationError(SMAppointmentRequest, "facilityName", FACILITY_NOT_FOUND_ERROR_MSG);
//			throw new InvalidAppointmentRequestException(validationResult.getErrors());
//		}
//	}

//	private void validateMaximumNumberOfAppointmentRequests(SMAppointmentRequest SMAppointmentRequest) {
//		if (AppointmentRequestType.PRIMARY_CARE.getName().equals(SMAppointmentRequest.getAppointmentType())) {
//			throwAnErrorIfPrimaryCareAppointmentRequestsExist(SMAppointmentRequest);
//		} else if (AppointmentRequestType.MENTAL_HEALTH.getName().equals(SMAppointmentRequest.getAppointmentType())) {
//			throwAnErrorIfMentalHealthAppointmentRequestsExist(SMAppointmentRequest);
//		}
//	}

//	private void throwAnErrorIfMentalHealthAppointmentRequestsExist(SMAppointmentRequest SMAppointmentRequest) {
//		if (areThereMoreThanOneSubmittedMentalHealthAppointmentRequests(SMAppointmentRequest)) {
//			ValidationResult<SMAppointmentRequest> validationResult = createOpenAppointmentRequestValidationError(SMAppointmentRequest, MENTAL_HEALTH_MAX_LIMIT_ERROR_MSG);
//			throw new InvalidAppointmentRequestException(validationResult.getErrors());
//		}
//	}

//	private boolean areThereMoreThanOneSubmittedMentalHealthAppointmentRequests(SMAppointmentRequest submittedAppointmentRequest) {
//		DateFilter defaultDateFilter = createDateFilterWithDefaultDateRange();
//
//		SMAppointmentRequests patientAppointmentRequests = getPatientAppointmentRequests(submittedAppointmentRequest.getPatientIdentifier(), defaultDateFilter);
//
//		int recordCount = 0;
//		for (SMAppointmentRequest SMAppointmentRequest : patientAppointmentRequests) {
//			if (SMAppointmentRequest.getAppointmentType().equals(AppointmentRequestType.MENTAL_HEALTH.getName()) && SMAppointmentRequest.getStatus().equals(AppointmentRequestStatus.SUBMITTED.getName())) {
//				if (++recordCount > 1) {
//					return true;
//				}
//			}
//		}
//
//		return false;
//	}

//	private void throwAnErrorIfPrimaryCareAppointmentRequestsExist(SMAppointmentRequest SMAppointmentRequest) {
//		if (areThereAnySubmittedPrimaryCareAppointmentRequests(SMAppointmentRequest)) {
//			ValidationResult<SMAppointmentRequest> validationResult = createOpenAppointmentRequestValidationError(SMAppointmentRequest, PRIMARY_CARE_MAX_LIMIT_ERROR_MSG);
//			throw new InvalidAppointmentRequestException(validationResult.getErrors());
//		}
//	}

	private ValidationResult<SMAppointmentRequest> createOpenAppointmentRequestValidationError(SMAppointmentRequest SMAppointmentRequest, String errorMessage) {
		return createValidationError(SMAppointmentRequest, "error", errorMessage);
	}

	private ValidationResult<SMAppointmentRequest> createValidationError(SMAppointmentRequest SMAppointmentRequest, String fieldName, String errorMessage) {
		ValidationResult<SMAppointmentRequest> validationResult = new ValidationResult<SMAppointmentRequest>();
		validationResult.setRequestObject(SMAppointmentRequest);

		ValidationError error = new ValidationError();
		error.setErrorMessage(errorMessage);
		error.setFieldName(fieldName);

		validationResult.addIfNotNull(error);
		return validationResult;
	}

    private void throwAnErrorIfAppointmentRequestDateHasPassed(SMAppointmentRequest SMAppointmentRequest, SMAppointmentRequestMessage SMAppointmentRequestMessage) {
        if (!hasAppointmentDatePassed(SMAppointmentRequest.getAppointmentDate())){
            ValidationResult<SMAppointmentRequestMessage> validationResult = createOpenAppointmentRequestMessageValidationError(SMAppointmentRequestMessage, APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_AFTER_APPOINTMENT_DATE_PASSED);
            throw new InvalidAppointmentRequestMessageException(validationResult.getErrors());
        }
    }
    private boolean hasAppointmentDatePassed(String appointmentRequestDate){

        if(NullChecker.isNotNullish(appointmentRequestDate)){
            Date today = DateHelper.beginOfDate(DateHelper.getToday());
            Date appointmentDate = DateHelper.beginOfDate(DateHelper.parseDate(appointmentRequestDate));
            if(today.after(appointmentDate))
                return false;
        }

        return true;
    }

    private void throwAnErrorIfAppointmentRequestIsCancelled(SMAppointmentRequest SMAppointmentRequest, SMAppointmentRequestMessage SMAppointmentRequestMessage) {
        if (SMAppointmentRequest.getStatus().equals("Cancelled")){
            ValidationResult<SMAppointmentRequestMessage> validationResult = createOpenAppointmentRequestMessageValidationError(SMAppointmentRequestMessage, APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_FOR_CANCELLED_APPOINTMENT);
            throw new InvalidAppointmentRequestMessageException(validationResult.getErrors());
        }
    }

    private ValidationResult<SMAppointmentRequestMessage> createOpenAppointmentRequestMessageValidationError(SMAppointmentRequestMessage SMAppointmentRequestMessage, String errorMessage) {
        ValidationResult<SMAppointmentRequestMessage> validationResult = new ValidationResult<SMAppointmentRequestMessage>();
        validationResult.setRequestObject(SMAppointmentRequestMessage);

        ValidationError error = new ValidationError();
        error.setErrorMessage(errorMessage);
        error.setFieldName("error");

        validationResult.addIfNotNull(error);
        return validationResult;
    }


    private void throwAnErrorIfNewMessageHasNotReceivedReply(SMAppointmentRequest SMAppointmentRequest, SMAppointmentRequestMessage SMAppointmentRequestMessage){

       SMAppointmentRequestMessages currentMessagesForAppointment =  fetchAppointmentRequestMessages(SMAppointmentRequest.getPatientIdentifier(), SMAppointmentRequest.getDataIdentifier());

       if(!currentMessagesForAppointment.isEmpty()){
           SMAppointmentRequestMessage latestMessage = currentMessagesForAppointment.get(0);
           if(latestMessage.getSenderId().equals(SMAppointmentRequestMessage.getSenderId())){
               ValidationResult<SMAppointmentRequestMessage> validationResult = createOpenAppointmentRequestMessageValidationError(SMAppointmentRequestMessage, APPOINTMENT_REQUEST_MSG_NOT_ALLOWED_UNTIL_REPLY);
               throw new InvalidAppointmentRequestMessageException(validationResult.getErrors());
           }
       }


    }


    private void throwAnErrorIfMessageLimitReached(SMAppointmentRequest SMAppointmentRequest, SMAppointmentRequestMessage SMAppointmentRequestMessage){

        SMAppointmentRequestMessages currentMessagesForAppointment =  fetchAppointmentRequestMessages(SMAppointmentRequest.getPatientIdentifier(), SMAppointmentRequest.getDataIdentifier());
        int numberOfMessagesAlreadySentBySender = 0;
        for(SMAppointmentRequestMessage aptReqMsg : currentMessagesForAppointment){
            if(SMAppointmentRequestMessage.getSenderId().equals(aptReqMsg.getSenderId())){
                numberOfMessagesAlreadySentBySender ++;
            }
        }

        if(numberOfMessagesAlreadySentBySender >= messageLimitPerSender){
            ValidationResult<SMAppointmentRequestMessage> validationResult = createOpenAppointmentRequestMessageValidationError(SMAppointmentRequestMessage, APPOINTMENT_REQUEST_MSG_LIMIT_REACHED);
            throw new InvalidAppointmentRequestMessageException(validationResult.getErrors());
        }

    }


//    private boolean areThereAnySubmittedPrimaryCareAppointmentRequests(SMAppointmentRequest submittedAppointmentRequest) {
//		DateFilter defaultDateFilter = createDateFilterWithDefaultDateRange();
//
//		SMAppointmentRequests patientAppointmentRequests = getPatientAppointmentRequests(submittedAppointmentRequest.getPatientIdentifier(), defaultDateFilter, ScopeFilter.getInstanceForLongitudinalScope());
//
//		for (SMAppointmentRequest SMAppointmentRequest : patientAppointmentRequests) {
//			if (SMAppointmentRequest.getAppointmentType().equals(AppointmentRequestType.PRIMARY_CARE.getName()) && SMAppointmentRequest.getStatus().equals(AppointmentRequestStatus.SUBMITTED.getName())) {
//				return true;
//			}
//		}
//
//		return false;
//	}

//	private DateFilter createDateFilterWithDefaultDateRange() {
//		Date endDate = DateHelper.getToday();
//		Date startDate = DateHelper.beginOfDate(DateHelper.minusDays(endDate, FarthestTimeVeteranCanRequestAppointmentInDays));
//		return DateFilterFactory.createFilterFromDate(startDate, endDate);
//	}
	
	public SMAppointmentRequest updateProviderSeeAppointmentRequestFlag(String appointmentRequestId, PatientIdentifier patientIdentifier, DataIdentifier dataIdentifier){
        SMAppointmentRequest SMAppointmentRequest = appointmentRequestDataLayer.markAppointmentRequestIsSeenByProvider(patientIdentifier.getUniqueId(),appointmentRequestId);
		return SMAppointmentRequest;
	}
	
	private void addSurrogate(PatientData patientData) {
        MhpUserFactory.addSurrogateToPatientData(patientData);
	}

    private void fixPatientAndDataIdentifier(SMAppointmentRequests SMAppointmentRequests) {
        logger.debug(String.format("fixing the assiging authority for patients [assigningAuthority=%s] ", EDIPI_ASSIGNING_AUTHORITY));

        for (SMAppointmentRequest SMAppointmentRequest : SMAppointmentRequests) {
            DefaultAssigningAuthorityUpdater.fillDefaultAssigningAuthority(SMAppointmentRequest, EDIPI_ASSIGNING_AUTHORITY);
            SMAppointmentRequest.getDataIdentifier().setSystemId(VAR_DATA_IDENTIFIER);
        }
    }

    private void fixPatientAndDataIdentifier(SMAppointmentRequestMessages messages, PatientIdentifier patientIdentifier, String systemId) {
        for (SMAppointmentRequestMessage message : messages) {
            message.setPatientIdentifier(patientIdentifier);
            message.getDataIdentifier().setSystemId(systemId);
        }
    }

    public PatientIdentifier getVistaPatientIdentifier(PatientIdentifier edipiPatientIdentifier, String siteCode){
        logger.debug("Convert EDIPI Patient Identifier : " + edipiPatientIdentifier.getAssigningAuthority() +"#"+ edipiPatientIdentifier.getUniqueId() + " to Vista Identifier");
        PatientIdentifier vistaPatientIdentifier = null;
        if(edipiPatientIdentifier.getAssigningAuthority().equals("EDIPI")){
            vistaPatientIdentifier = patientCorrelationService.translateIDFromEDIPIToVistA(edipiPatientIdentifier, siteCode);
        }
        if(vistaPatientIdentifier != null){
            return vistaPatientIdentifier;
        }
        return edipiPatientIdentifier;
    }
}
