package com.agilex.vamf.missionhealth.resource;

import java.net.URI;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

import com.agilex.vamf.missionhealth.domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.agilex.vamf.missionhealth.datalayer.MissionHealthDataService;
import com.agilex.vamf.missionhealth.uri.ResourceDirectoryBuilder;
import com.agilex.vamf.utils.PropertyHelper;

@Component
@Scope("request")
@Path("patient/{assigning-authority}/{patient-id}/mission-health")
public class MissionHealthResource {

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

	@Resource
	ResourceDirectoryBuilder resourceDirectoryBuilder;

	@Resource
    private PropertyHelper propertyHelper;
	
	@Autowired
    private MissionHealthDataService missionHealthDataService;

    /**
	 * This resource is used to get to the mission health specific resource directory.
	 * 
	 * @param uriInfo
	 * @param headers
	 * @param assigningAuthority Assigning Authority for the patient
	 * @param patientId Patient Identifier
	 * @return Returns a set of links representing mission health specific
	 *         resources.
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	public ResourceDirectory fetchResourceDirectory(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers, 
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
		
		logger.debug("MissionHealthResource.fetchResourceDirectory() called");
		URI mhpUri = UriBuilder.fromUri(propertyHelper.getProperty("mhp.baseUri")).build();
		ResourceDirectory resourceDirectory = resourceDirectoryBuilder.getResourceDirectory(uriInfo.getBaseUri(), uriInfo.getRequestUri(), mhpUri, assigningAuthority, patientId);
		return resourceDirectory;
	}

    /**
     * This resource saves the specified mission health profile
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param missionHealthProfile The profile to be saved
     * @return Returns the saved MissionHealthDetail object
     */
	@PUT
	@Consumes({ "application/xml", "application/json"  })
	@Produces({ "application/xml", "application/json"  })
	@Path("/mission-health-profile")
	public MissionHealthDetail saveMissionHealthProfile(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, MissionHealthProfile missionHealthProfile) {

		logger.debug("MissionHealthResource.updateMissionHealthProfile() @PUT called");

		PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
		missionHealthProfile.setPatientIdentifier(patientIdentifier);
		MissionHealthDetail updatedMissionHealthDetail = missionHealthDataService.updateMissionHealthProfile(missionHealthProfile);
//		updatedMissionHealthProfile.setPatientIdentifier(patientIdentifier);
//		MissionHealthLinkBuilder linkBuilder = new MissionHealthLinkBuilder(uriInfo.getBaseUri());
//		linkBuilder.fillLinks(updatedMissionHealthProfile);
		return updatedMissionHealthDetail;
	}

    /**
     * This resource creates a new mission health profile for a veteran/patient.
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param missionHealthProfile The profile to be created
     * @return Returns MissionHealthProfile
     */
	@POST
    @Consumes({ "application/xml", "application/json"  })
    @Produces({ "application/xml", "application/json"  })
    @Path("/mission-health-profile")
    public MissionHealthProfile createMissionHealthProfile(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
            @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, MissionHealthProfile missionHealthProfile) {

        logger.debug("MissionHealthResource.saveMissionHealthProfile() @POST called");

        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        missionHealthProfile.setPatientIdentifier(patientIdentifier);
        MissionHealthProfile savedMissionHealthProfile = missionHealthDataService.saveMissionHealthProfile(missionHealthProfile);
//        savedMissionHealthProfile.setPatientIdentifier(patientIdentifier);
//        MissionHealthLinkBuilder linkBuilder = new MissionHealthLinkBuilder(uriInfo.getBaseUri());
//        linkBuilder.fillLinks(savedMissionHealthProfile);
        return savedMissionHealthProfile;
    }
	
    /**
	 * This resource is used to retrieve the mission health details for a veteran/patient.
	 * 
	 * @param uriInfo
	 * @param headers
	 * @param assigningAuthority Assigning Authority for the patient
	 * @param patientId Patient Identifier
	 * @return Returns MissionHealthDetail.
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	@Path("/mission-health-detail")
	public MissionHealthDetail fetchMissionHealthDetail(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers, 
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
		
		logger.debug("MissionHealthResource.fetchMissionHealthDetail() called");
		PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
		MissionHealthDetail missionHealthDetail = missionHealthDataService.getMissionHealthDetail(patientIdentifier, new Date(request.getSession().getCreationTime()));

        return missionHealthDetail;
	}	
		
	/**
	 * This resource is used to save points for SMART info in MissionHealthDetail Collection for a veteran/patient.
	 * 
	 * @param uriInfo
	 * @param headers
	 * @param assigningAuthority Assigning Authority for the patient
	 * @param patientId Patient Identifier
	 * @return Returns MissionHealthDetail.
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	@Path("/smartinfo-points")
	public MissionHealthPartialDetail fetchSmartInfoPoints(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers, 
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
		
		logger.debug("MissionHealthResource.fetchSmartInfoPoints() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.updateSmartInfoPoints(patientIdentifier);
		}
	
	/**
	 * This resource is used to save points for Email or Facebook sharing in MissionHealthDetail Collection for a veteran/patient.
	 * 
	 * @param uriInfo
	 * @param headers
	 * @param assigningAuthority Assigning Authority for the patient
	 * @param patientId Patient Identifier
	 * @return Returns MissionHealthDetail.
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	@Path("/emailfacebook-points")
	public MissionHealthPartialDetail fetchEmailFacebookPoints(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers, 
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
		
		logger.debug("MissionHealthResource.fetchEmailFacebookPoints() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.updateEmailFacebookPoints(patientIdentifier);
    }

    /**
     * This resource is used to create a new mission for the specified veteran/patient. </ br>
     *      The mission receives a range of possible point values and is added to the MissionHealthDetail.currentMissions collection for the veteran/patient
     *      The new mission is returned to the client.
     *
     * @param uriInfo
     * @param request                                                        1
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param mission
     * @return Returns a new Mission
     */
    @POST
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @Path("/mission")
    public Mission createNewMission(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                    @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, Mission mission) {

        logger.debug("MissionHealthResource.createNewMission() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.createNewMission(patientIdentifier, mission);
    }

    /**
     * This resource is used to update an existing mission for the specified veteran/patient
     *      If the mission exists in the MissionHealthDetail.currentMissions collection or the MissionHealthDetail.missions collection,
     *          it will be replaced by the mission passed by the client
     *      If the mission doesn't exist, a 204 error will be returned (No Content)
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param mission
     * @return Returns the updated Mission
     */
    @PUT
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @Path("/mission")
    public Mission updateMission(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                    @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, Mission mission) {

        logger.debug("MissionHealthResource.updateCurrentMission() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.updateMission(patientIdentifier, mission);
    }
    
    /**
     * This resource is used to insert mission readiness report for the specified veteran/patient.
     *      The updated partial/required MissionHealthDetail is returned to the client. </ br>
     *      <h3>MissionHealthDetail Fields updated and returned by this service:</h3>
     *      <ul>
     *          <li>missionReadinessReports</li>
     *          <li>rank</li>
     *          <li>rankEffectiveDate</li>
     *          <li>points</li>
     *          <li>promoted</li>
     *          <li>previousRank</li>
     *          <li>pendingRank</li>
     *      </ul>
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param missionReadinessReport
     * @return Returns partial MissionHealthDetail.
     */
    @POST
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @Path("/mission-readiness-report")
    public MissionHealthDetail insertMissionReadinessReport(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                    @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId, MissionReadinessReport missionReadinessReport) {

        logger.debug("MissionHealthResource.insertMissionReadinessReport() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.insertMissionReadinessReport(patientIdentifier, missionReadinessReport);
    }
    
    /**
     * This resource is used to update promoted status to false for the specified veteran/patient.</ br>
     *      <h3>MissionHealthDetail Fields updated and returned by this service:</h3>
     *      <ul>
     *          <li>promoted</li>
     *      </ul>
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @return
     */
    @PUT
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @Path("/promoted")
    public MissionHealthPartialDetail savePromotedStatus(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                    @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
        logger.debug("MissionHealthResource.savePromotedStatus() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.savePromotedStatus(patientIdentifier);
    }
    
    /**
     * This resource is used to update LostTroopsShowMessage to false after the pop-up is acknowledged by veteran/patient.
     *      <h3>MissionHealthDetail Fields updated and returned by this service:</h3>
     *      <ul>
     *          <li>lostTroopsShowMessage</li>
     *      </ul>
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @return
     */
    @PUT
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @Path("/lost-troops")
    public MissionHealthPartialDetail saveLostTroopsShowMessage(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                    @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
        logger.debug("MissionHealthResource.saveLostTroopsShowMessage() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.saveLostTroopsShowMessage(patientIdentifier);
    }

    /**
     * This resource gets the current standing of a veteran/patient.
     *
     * @param uriInfo
     * @param request
     * @param headers
     * @param assigningAuthority Assigning Authority for the patient
     * @param patientId Patient Identifier
     * @param standingType Standing type (vs All(ALL), vs Service(SERVICE), or vs Level(LEVEL))
     * @return
     */
    @GET
    @Produces({ "application/xml", "application/json" })
    @Path("/standings")
    public MissionHealthStandings getStandings(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers,
                                               @PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId,
                                               @QueryParam("type") String standingType) {
        logger.debug("MissionHealthResource.getStandings() called");
        PatientIdentifier patientIdentifier = new PatientIdentifier(assigningAuthority, patientId);
        return missionHealthDataService.getMissionHealthStandings(patientIdentifier, standingType);
    }
    
    /**
	 * This resource is used to get annual service comparison roll up metrics for scoreboard.
	 * 
	 * @param uriInfo
	 * @param headers
	 * @param assigningAuthority Assigning Authority for the patient
	 * @param patientId Patient Identifier
	 * @return Returns AnnualServiceRollUp.
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	@Path("/annual-rollup")
	public AnnualServiceRollUp fetchAnnualServiceComparisonRollUp(@Context UriInfo uriInfo, @Context HttpServletRequest request, @Context HttpHeaders headers, 
			@PathParam("assigning-authority") String assigningAuthority, @PathParam("patient-id") String patientId) {
		
		logger.debug("MissionHealthResource.fetchAnnualServiceComparisonRollUp() called");
		AnnualServiceRollUp a=missionHealthDataService.getAnnualServiceComparisonRollUp();
		return a;
    }
}
