package com.agilex.healthcare.schedulingmanager.resources;

import com.agilex.healthcare.mobilehealthplatform.domain.DataIdentifier;
import com.agilex.healthcare.mobilehealthplatform.domain.MhpUser;
import com.agilex.healthcare.mobilehealthplatform.domain.PatientIdentifier;
import com.agilex.healthcare.mobilehealthplatform.domain.filter.datefilter.DateFilter;
import com.agilex.healthcare.mobilehealthplatform.domain.filter.datefilter.DateFilterFactory;
import com.agilex.healthcare.mobilehealthplatform.security.MhpUserFactory;
import com.agilex.healthcare.schedulingmanager.enumeration.AppType;
import com.agilex.healthcare.schedulingmanager.notification.appointmentrequest.AppointmentRequestMessageNotificationGateway;
import com.agilex.healthcare.schedulingmanager.notification.appointmentrequest.MessagePublishException;
import com.agilex.healthcare.schedulingmanager.notification.appointmentrequest.MessagingFactory;
import com.agilex.healthcare.schedulingmanager.datalayer.appointment.AppointmentRequestFilter;
import com.agilex.healthcare.schedulingmanager.dataservice.AppointmentMetricsDataService;
import com.agilex.healthcare.schedulingmanager.dataservice.AppointmentRequestDataService;
import com.agilex.healthcare.schedulingmanager.dataservice.AppointmentRequestInProcessDataService;
import com.agilex.healthcare.schedulingmanager.dataservice.DetailCodeDataService;
import com.agilex.healthcare.schedulingmanager.domain.*;
import com.agilex.healthcare.schedulingmanager.enumeration.AppointmentMetrics;
import com.agilex.healthcare.schedulingmanager.linkbuilder.AppointmentRequestLinkBuilder;
import com.agilex.healthcare.schedulingmanager.linkbuilder.AppointmentRequestMessagesLinkBuilder;
import com.agilex.healthcare.schedulingmanager.utils.PilotFacilitiesHelper;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import java.util.StringTokenizer;

@Path("/appointment-service")
@Component
@Scope("request")
public class AppointmentRequestResource extends AbstractUserResource {

    private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory.getLog(AppointmentRequestResource.class);
    private static final String DETAIL_CODE_MAKE_PHONE_CALL = "DETCODE2";
    
    @Resource
    SMAppointmentsMetadata smAppointmentsMetadata;

    @Resource
    PilotFacilitiesHelper pilotFacilitiesHelper;

    @Resource
    String haMode;

    @Resource
    AppointmentRequestDataService appointmentRequestDataService;

    @Resource
    DetailCodeDataService detailCodeDataService;

    @Resource
    AppointmentRequestInProcessDataService appointmentRequestInProcessDataService;

    @POST
    @Path("/metrics/no-icn-or-dfn")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentMetric incrementNoIcnOrDfnMetric(@Context HttpServletRequest request, @Context UriInfo uriInfo) {
        AppointmentMetricsDataService dataService = new AppointmentMetricsDataService();
        return dataService.incrementMetric(AppointmentMetrics.NO_ICN_OR_DFN.getName());
    }

    @POST
    @Path("/metrics/no-dfn-cancel-request")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentMetric incrementNoDfnCancelRequestMetric(@Context HttpServletRequest request, @Context UriInfo uriInfo) {
        AppointmentMetricsDataService dataService = new AppointmentMetricsDataService();
        return dataService.incrementMetric(AppointmentMetrics.NO_DFN_CANCEL_REQUEST.getName());
    }

    @GET
    @Path("/metadata")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentsMetadata getSmAppointmentsMetadata() {
        Set<SMDetailCode> SMDetailCodes = detailCodeDataService.fetchDetailCodes();
        smAppointmentsMetadata.setSMDetailCodes(SMDetailCodes);
        return smAppointmentsMetadata;
    }

    /**
     * A resource that returns all {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequests} that have been
     * created by this user.
     *
     * @return Returns {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequests} associated with the user
     *         calling the request
     */
    @GET
    @Path("/appointment-requests")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentRequests getAppointmentRequestsByCriteria(@QueryParam("parentSiteCode") String parentSiteCode,
                                                                  @QueryParam("noSort") Boolean noSort,
                                                                  @QueryParam("refresh") String refresh,
                                                                  @QueryParam("max-per-page") String maxPerPageStr,
                                                                  @QueryParam("go-to-page") String goToPageStr,
                                                                  @QueryParam("sort-on") String sortOnString,
                                                                  @QueryParam("filter") String filter,
                                                                  @Context UriInfo uriInfo) {
        SMAppointmentRequests smAppointmentRequests;
        int                         gotoPage;
        int                         maxPerPage;
        HashMap<String, Boolean>    sortFields = null;
        StringTokenizer             strtok;
        StringTokenizer             strtok2;

        if(refresh == null) {
            refresh = "true";
        }
        if(maxPerPageStr == null) {
            maxPerPageStr = "20";
        }
        if(goToPageStr == null) {
            goToPageStr = "1";
        }

        maxPerPage = Integer.parseInt(maxPerPageStr);
        gotoPage = Integer.parseInt(goToPageStr);

        gotoPage -= 1;
        if(gotoPage < 0) {
            gotoPage = 0;
        }

        if(sortOnString != null) {
            if(!(sortOnString.equals("defaultVAACSort") || sortOnString.equals("defaultVAACSort;"))){
                sortFields = new HashMap<String, Boolean>();

                strtok = new StringTokenizer(sortOnString, ";");
                while(strtok.hasMoreTokens()) {
                    String      sortData = strtok.nextToken();

                    strtok2 = new StringTokenizer(sortData, ",");

                    sortFields.put(strtok2.nextToken(), new Boolean(strtok2.nextToken()));
                }
            }
        }

        AppointmentRequestFilter appointmentRequestFilter = getAppointmentRequestCriteria(parentSiteCode, uriInfo);

        if (noSort != null && noSort) {
            smAppointmentRequests = appointmentRequestDataService.getAppointmentRequestsNoSort(appointmentRequestFilter, Boolean.parseBoolean(refresh),
                                                                                                sortFields, filter, gotoPage * maxPerPage,
                                                                                                (gotoPage * maxPerPage) + maxPerPage);

        } else {
            smAppointmentRequests = appointmentRequestDataService.getAppointmentRequests(appointmentRequestFilter, Boolean.parseBoolean(refresh),
                                                                                                sortFields, filter, gotoPage * maxPerPage,
                                                                                                (gotoPage * maxPerPage) + maxPerPage);

        }

        gotoPage += 1;
        int pgCount = (int) smAppointmentRequests.getRecordCount()/maxPerPage;
        if((int)smAppointmentRequests.getRecordCount() % maxPerPage != 0){
            pgCount++;
        }
        smAppointmentRequests.setPageCount(pgCount);
        if(gotoPage > smAppointmentRequests.getPageCount()){
            smAppointmentRequests.setCurrentPage(smAppointmentRequests.getPageCount());
        }
        else {
            smAppointmentRequests.setCurrentPage(gotoPage);
        }
        smAppointmentRequests.setStartRecord((maxPerPage * (gotoPage - 1)) + 1);
        smAppointmentRequests.setStopRecord(maxPerPage * gotoPage);
        if(smAppointmentRequests.getStopRecord() > smAppointmentRequests.getRecordCount()){
            smAppointmentRequests.setStopRecord(smAppointmentRequests.getRecordCount());
        }

        updateAtomLinks(uriInfo, smAppointmentRequests);

        return smAppointmentRequests;
    }

    private AppointmentRequestFilter getAppointmentRequestCriteria(String parentSiteCode, UriInfo uriInfo) {
        DateFilter dateFilter = DateFilterFactory.createFilterFromUri(uriInfo);

        AppointmentRequestFilter appointmentRequestFilter = new AppointmentRequestFilter();
        appointmentRequestFilter.setParentSiteCode(parentSiteCode);
        appointmentRequestFilter.setStartDate(dateFilter.getStartDate());
        appointmentRequestFilter.setEndDate(dateFilter.getEndDate());

        return appointmentRequestFilter;
    }

//    /**
//     * A resource that returns all {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequests} that have been
//     * created by this user.
//     *
//     * @return Returns {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequests} associated with the user
//     *         calling the request
//     */
//    @GET
//    @Path("/patient/{assigning-authority}/{patient-id}/appointments")
//    @Produces({"application/xml", "application/json"})
//    public SMAppointmentRequests getAppointmentRequests(@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @Context UriInfo uriInfo) {
//        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
//        DateFilter dateFilter = DateFilterFactory.createFilterFromUri(uriInfo);
//        SMAppointmentRequests SMAppointmentRequests;
//
//        AppointmentRequestDataService appointmentRequestDataService = new AppointmentRequestDataService();
//        SMAppointmentRequests = appointmentRequestDataService.getPatientAppointmentRequests(patientIdentifier, dateFilter, ScopeFilter.getInstanceForLongitudinalScope());
//
//        PatientMetadataDataService patientMetadataDataService = new PatientMetadataDataService();
//        SMAppointmentRequests.setLastAccessDate(patientMetadataDataService.fetchAndUpdateLastAccessDate(patientIdentifier, ScopeFilter.getInstanceForLongitudinalScope()));
//
//        updateAtomLinks(uriInfo, SMAppointmentRequests);
//
//        return SMAppointmentRequests;
//    }

    /**
     * A resource that returns all {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequestMessages} that have
     * been created by this user.
     *
     * @return Returns {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequestMessages} associated with the
     *         user calling the request
     */
    @GET
    @Path("/patient/{assigning-authority}/{patient-id}/appointment-requests/system/{system-id}/id/{appointment-request-id}/messages")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentRequestMessages getAppointmentRequestMessages(@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @PathParam("system-id") String systemId,
                                                                    @PathParam("appointment-request-id") String appointmentRequestId, @Context UriInfo uriInfo) {
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        DataIdentifier dataIdentifier = new DataIdentifier(systemId, appointmentRequestId);

        SMAppointmentRequestMessages messages = appointmentRequestDataService.fetchAppointmentRequestMessages(patientIdentifier, dataIdentifier);

        updateAtomLinks(uriInfo, messages);

        return messages;
    }

    /**
     * This request is used to create/save new text message created by user for a given appointment.
     * @param assigningAuthority
     * @param patientId
     * @param appointmentRequestId
     * @param systemId
     * @param SMAppointmentRequestMessage
     * @return
     */
    @POST
    @Path("/patient/{assigning-authority}/{patient-id}/appointment-requests/system/{system-id}/id/{appointment-request-id}/messages")
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public SMAppointmentRequestMessage createAppointmentRequestMessage(@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @PathParam("appointment-request-id") String appointmentRequestId, @PathParam("system-id") String systemId ,SMAppointmentRequestMessage SMAppointmentRequestMessage) {


        if (appointmentRequestId.equals(SMAppointmentRequestMessage.getAppointmentRequestId())) {
            SMAppointmentRequestMessage.setMessageDateTime(new Date());
            SMAppointmentRequestMessage.setPatientIdentifier(new PatientIdentifier(assigningAuthority, patientId));
            SMAppointmentRequestMessage.setDataIdentifier(new DataIdentifier(systemId, appointmentRequestId));

            SMAppointmentRequestMessage result = appointmentRequestDataService.saveAppointmentRequestMessage(SMAppointmentRequestMessage);

            //temp fix for save not returning patientIdentifier
            if ((result.getPatientIdentifier() == null) || (result.getPatientIdentifier().getUniqueId() == null) || (result.getPatientIdentifier().getAssigningAuthority() == null)) {
                result.setPatientIdentifier(new PatientIdentifier(assigningAuthority, patientId));
            }

            //Only send notification if message is staff generated (don't notify veteran of action they just did themselves)
            if (MhpUserFactory.doesUserHasStaffRole()) {
                sendNotificationMessage(result);
            }

            return result;
        } else {
            return null;
        }
    }

    /**
     * This resource is used to update flag that indicates that user has read text message(s).
     * @param assigningAuthority
     * @param patientId
     * @param systemId
     * @param appointmentRequestId
     * @return
     */
    @POST
    @Path("/patient/{assigning-authority}/{patient-id}/appointment-requests/system/{system-id}/id/{appointment-request-id}/messages/read")
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public Response markMessagesAsRead(@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @PathParam("system-id") String systemId, @PathParam("appointment-request-id") String appointmentRequestId) {

        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        DataIdentifier dataIdentifier = new DataIdentifier(systemId, appointmentRequestId);

        SMAppointmentRequest SMAppointmentRequest = appointmentRequestDataService.updateAppointmentMessageFlag(appointmentRequestId,patientIdentifier,dataIdentifier);
        SMAppointmentRequest.setPatientIdentifier(patientIdentifier);
        SMAppointmentRequest.setDataIdentifier(dataIdentifier);
        if (SMAppointmentRequest.getAppointmentRequestId().equals(appointmentRequestId)) {
            return Response.ok().build();
        } else {
            return Response.serverError().build();
        }
    }

    private void sendNotificationMessage(SMAppointmentRequestMessage result) {
        AppointmentRequestMessageNotificationGateway messageGateway = MessagingFactory.getAppointmentRequestMessageNotificationGateway();

        try {
            messageGateway.sendMessageToPatient(result);
        } catch (MessagePublishException e) {
            logger.error("Error publishing message " + e.getMessage());
        }
    }

    private void updateAtomLinks(UriInfo uriInfo, SMAppointmentRequestMessages messages) {
        if (uriInfo != null) {
            AppointmentRequestMessagesLinkBuilder linkBuilder = new AppointmentRequestMessagesLinkBuilder(uriInfo.getBaseUri());
            linkBuilder.fillLinks(messages, uriInfo.getRequestUri());
        }
    }

    private void updateAtomLinks(UriInfo uriInfo, SMAppointmentRequests SMAppointmentRequests) {
        if (uriInfo != null) {
            AppointmentRequestLinkBuilder linkBuilder = new AppointmentRequestLinkBuilder(uriInfo.getBaseUri());
            linkBuilder.fillLinks(SMAppointmentRequests, uriInfo.getRequestUri());
        }
    }

    /**
     * A resource that returns a single {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequest} by user and
     * id
     *
     * @return Returns {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequest} associated with the id and
     *         user calling the request
     */
    @GET
    @Path("/patient/{assigning-authority}/{patient-id}/appointments/system/{system-id}/id/{appointment-request-id}")
    @Produces({"application/xml", "application/json"})
    public SMAppointmentRequest getAppointmentRequest(@PathParam("assigning-authority") String assigningAuthority, @PathParam("system-id") String systemId, @PathParam("patient-id") String patientId,
                                                    @PathParam("appointment-request-id") String appointmentRequestId, @Context UriInfo uriInfo) {
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        DataIdentifier dataIdentifier = new DataIdentifier(systemId, appointmentRequestId);
        SMAppointmentRequest SMAppointmentRequest = null;

        SMAppointmentRequest = appointmentRequestDataService.getPatientAppointmentRequest(patientIdentifier, dataIdentifier);
        SMAppointmentRequestInProcess beingProcessedBy = retrieveAppointmentRequestInProcess(SMAppointmentRequest.getUniqueId());
        SMAppointmentRequest.setBeingProcessedBy(beingProcessedBy);

        updateAtomLinks(SMAppointmentRequest, uriInfo);

        return SMAppointmentRequest;
    }

    private SMAppointmentRequestInProcess retrieveAppointmentRequestInProcess(String appointmentRequestId) {
        return appointmentRequestInProcessDataService.fetchAppointmentRequestInProcessById(appointmentRequestId);
    }

    /**
     * A resource that saves a single {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequest} by user and id
     *
     * @return Returns {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequest} associated with the id and
     *         user calling the request
     */
    @PUT
    @Path("/patient/{assigning-authority}/{patient-id}/appointments/system/{system-id}/id/{appointment-request-id}")
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public SMAppointmentRequest updateAppointmentRequest(@Context HttpServletRequest request, @PathParam("assigning-authority") String assigningAuthority, @PathParam("system-id") String systemId, @PathParam("patient-id") String patientId,
                                                       @PathParam("appointment-request-id") String appointmentRequestId, SMAppointmentRequest SMAppointmentRequest, @Context UriInfo uriInfo) {
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        DataIdentifier dataIdentifier = new DataIdentifier(systemId, appointmentRequestId);
        SMAppointmentRequest.setPatientIdentifier(patientIdentifier);
        SMAppointmentRequest.setDataIdentifier(dataIdentifier);
        SMAppointmentRequest.setLastUpdatedDate(new Date());

        for (SMAppointmentRequestDetailCode ardc : SMAppointmentRequest.getAppointmentRequestDetailCode()) {
            if (ardc.getCreatedDate() == null) {
                ardc.setCreatedDate(new Date());
            }
        }


        performStatusChangeProcessing(SMAppointmentRequest);


        boolean fullValidation = false;
        SMAppointmentRequest = saveAppointmentRequest(SMAppointmentRequest, fullValidation, uriInfo);

        return SMAppointmentRequest;
    }

    private void performStatusChangeProcessing(SMAppointmentRequest SMAppointmentRequest) {

        if (!MhpUserFactory.doesUserHasStaffRole()) {
            return;  //no need to send Notification if veteran is performing the action
        }

        //retrieve existing AR
        SMAppointmentRequest existing = appointmentRequestDataService.getPatientAppointmentRequest(SMAppointmentRequest.getPatientIdentifier(), SMAppointmentRequest.getDataIdentifier());

        //if status has changed
        if (!existing.getStatus().equals(SMAppointmentRequest.getStatus())) {
            //generate notification message
            AppointmentRequestMessageNotificationGateway messageGateway = MessagingFactory.getAppointmentRequestMessageNotificationGateway();

            try {
                String detailCode = null;
                for(SMAppointmentRequestDetailCode smAppointmentRequestDetailCode : SMAppointmentRequest.getAppointmentRequestDetailCode()) {
                    if(smAppointmentRequestDetailCode.getDetailCode() != null
                            && smAppointmentRequestDetailCode.getDetailCode().getCode() != null
                            && smAppointmentRequestDetailCode.getDetailCode().getCode().equals(DETAIL_CODE_MAKE_PHONE_CALL)) {
                        detailCode = DETAIL_CODE_MAKE_PHONE_CALL;
                    }
                }
                messageGateway.sendMessageToPatient(SMAppointmentRequest.getPatientIdentifier(), detailCode);
            } catch (MessagePublishException e) {
                logger.error("Error publishing message " + e.getMessage());
            }
        }
    }

//    private void setCreateDateInDetailCodesOfParentAppointmentRequest(SMAppointmentRequest SMAppointmentRequest) {
//        SMAppointmentRequest parentAppointmentRequest = SMAppointmentRequest.getParentRequest();
//
//        if (parentAppointmentRequest != null) {
//            for (SMAppointmentRequestDetailCode ardc : parentAppointmentRequest.getSMAppointmentRequestDetailCode()) {
//                if (ardc.getCreatedDate() == null) {
//                    ardc.setCreatedDate(new Date());
//                }
//            }
//        }
//    }

//    /**
//     * A resource that allows a client to save an {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequest}.
//     * See {@link com.agilex.healthcare.mobilehealthplatform.validator.appointment.AppointmentRequestValidator} for val idation logic.
//     *
//     * @param SMAppointmentRequest
//     * @return The {@link com.agilex.healthcare.mobilehealthplatform.domain.SMAppointmentRequest} that was saved.
//     */
//    @POST
//    @Path("/patient/{assigning-authority}/{patient-id}/appointments")
//    @Consumes({"application/xml", "application/json"})
//    @Produces({"application/xml", "application/json"})
//    public SMAppointmentRequest submitAppointmentRequest(@Context HttpServletRequest request, @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, SMAppointmentRequest SMAppointmentRequest,
//                                                       @Context UriInfo uriInfo) {
//        prepareAppointmentRequestForSubmission(request.getSession(), SMAppointmentRequest, assigningAuthority, patientId);
//
//        boolean fullValidation = true;
//        setCreateDateInDetailCodesOfParentAppointmentRequest(SMAppointmentRequest);
//        SMAppointmentRequest = saveAppointmentRequest(SMAppointmentRequest, fullValidation, uriInfo);
//
//        return SMAppointmentRequest;
//    }

    /**
     * @return The {@link com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequestInProcess} that was saved.
     */
    @POST
    @Path("/patient/{assigning-authority}/{patient-id}/appointments/system/{system-id}/id/{appointment-request-id}/inprocess")
    @Produces({"application/xml", "application/json"})
    public Response saveAppointmentRequestInProcess(@PathParam("patient-id") String patientId, @PathParam("system-id") String systemId, @PathParam("appointment-request-id") String appointmentRequestId) {
        Response response = null;
        SMAppointmentRequestInProcess beingProcessedBy = null;
        beingProcessedBy = retrieveAppointmentRequestInProcess(appointmentRequestId);

        if (beingProcessedBy == null) {
            MhpUser mhpUser = MhpUserFactory.createFromSecurityContext();
            beingProcessedBy = new SMAppointmentRequestInProcess();
            beingProcessedBy.setAppointmentRequestId(appointmentRequestId);
            beingProcessedBy.setUserId(mhpUser.getId());
            beingProcessedBy.setFirstName(mhpUser.getFirstName());
            beingProcessedBy.setLastName(mhpUser.getLastName());

            beingProcessedBy = appointmentRequestInProcessDataService.saveAppointmentRequestInProcess(beingProcessedBy);

            response = Response.ok(beingProcessedBy).build();
        } else if (beingProcessedBy.getUserId().equals(getCurrentUserId())) {
            response = Response.ok(beingProcessedBy).build();
        } else {
            response = Response.status(400).entity(beingProcessedBy).build();
        }

        return response;
    }

    /**
     * @return The {@link com.agilex.healthcare.schedulingmanager.domain.SMAppointmentRequestInProcess} that was saved.
     */
    @DELETE
    @Path("/patient/{assigning-authority}/{patient-id}/appointments/system/{system-id}/id/{appointment-request-id}/inprocess")
    @Produces({"application/xml", "application/json"})
    public Response deleteAppointmentRequestInProcess(@PathParam("system-id") String systemId, @PathParam("appointment-request-id") String appointmentRequestId) {

        appointmentRequestInProcessDataService.deleteAppointmentRequestInProcessById(appointmentRequestId);

        return Response.ok().build();
    }

    /**
     * This resource is used to reset flag to indicate that Staff has seen and appointment request.
     * @param assigningAuthority
     * @param patientId
     * @param systemId
     * @param appointmentRequestId
     * @return
     */
    @PUT
    @Path("/patient/{assigning-authority}/{patient-id}/appointment-requests/system/{system-id}/id/{appointment-request-id}/appointment/provider-read")
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public Response markAppointmentRequestIsSeenByStaff(@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @PathParam("system-id") String systemId, @PathParam("appointment-request-id") String appointmentRequestId) {

        if (MhpUserFactory.doesUserHasStaffRole() && appointmentRequestId != null) {
            PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
            DataIdentifier dataIdentifier = new DataIdentifier(systemId, appointmentRequestId);
            SMAppointmentRequest updatedSMAppointmentRequest = appointmentRequestDataService.updateProviderSeeAppointmentRequestFlag(appointmentRequestId, patientIdentifier, dataIdentifier);
            if(appointmentRequestId.equals(updatedSMAppointmentRequest.getAppointmentRequestId())){
            	return Response.ok().build();
            }
            return Response.serverError().build();
        } else {
            return Response.status(401).build();
        }
    }

    /**
     * This Resource is used to find Vista Identifier using corresponding EPIDP identifier.
     * @param parentSiteCode
     * @param assigningAuthority
     * @param patientId
     * @param uriInfo
     * @return
     */
    @GET
    @Consumes({ "application/xml", "application/json" })
    @Produces({ "application/xml", "application/json" })
    @Path("/patient/{assigning-authority}/{patient-id}")
    public PatientIdentifier convertPatientIdentifier(@QueryParam("parentSiteCode") String parentSiteCode, @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, @Context UriInfo uriInfo){
        if(assigningAuthority.equals("EDIPI")){
            return appointmentRequestDataService.getVistaPatientIdentifier(new PatientIdentifier(assigningAuthority, patientId), parentSiteCode);
        }
        return new PatientIdentifier();
    }


    private SMAppointmentRequest saveAppointmentRequest(SMAppointmentRequest SMAppointmentRequest, boolean fullValidation, UriInfo uriInfo) {
        SMAppointmentRequest = appointmentRequestDataService.saveAppointmentRequest(pilotFacilitiesHelper.getPilotSites(AppType.VARCAR.getName()), SMAppointmentRequest, haMode, fullValidation);
        updateAtomLinks(SMAppointmentRequest, uriInfo);
        return SMAppointmentRequest;
    }

    private void updateAtomLinks(SMAppointmentRequest SMAppointmentRequest, UriInfo uriInfo) {
        AppointmentRequestLinkBuilder linkBuilder = new AppointmentRequestLinkBuilder(uriInfo.getBaseUri());
        linkBuilder.fillLinks(SMAppointmentRequest, uriInfo.getRequestUri());
    }

//    private void prepareAppointmentRequestForSubmission(HttpSession session, SMAppointmentRequest SMAppointmentRequest, String assigningAuthority, String patientId) {
//        Date now = new Date();
//
//        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
//        SMAppointmentRequest.setPatientIdentifier(patientIdentifier);
//        SMAppointmentRequest.setStatus(AppointmentRequestStatus.SUBMITTED.getName());
//        SMAppointmentRequest.setCreatedDate(now);
//        SMAppointmentRequest.setLastUpdatedDate(now);
//        SMAppointmentRequest.setDeletedDate(null);
//
//        if (!SMAppointmentRequest.isTextMessagingAllowed()) {
//            SMAppointmentRequest.setTextMessagingPhoneNumber("");
//        }
//    }

}
