package com.agilex.vamf.missionhealth.domain;

import com.agilex.vamf.utils.DateHelper;
import com.agilex.vamf.utils.DateMarshaller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

/**
 * This object contains all the details needed to keep track of a user's
 *  status while using the mission health application.  This info includes the user's
 *  personal info, rank, total points earned, missions created/attempted/completed, etc.
 *
 *
 */
@XmlRootElement(name = "missionHealthDetail", namespace = Namespace.MissionHealth)
@XmlAccessorType(value = XmlAccessType.NONE)
public class MissionHealthDetail extends PatientData {

	private static final long serialVersionUID = -8448590498065156470L;

	/** Object Identifier */
    @XmlElement
	private String id;

    /** Mission Health Profile object */
	@XmlElement
	private MissionHealthProfile missionHealthProfile;

	/** Last Date when the user logged in */
    @XmlElement
	private Date loginDate;

    /** The exact Date/time when the user last logged in */
    @XmlElement
    private Date lastSessionStart;

    /** The last date at which the user took the SMART info questionnaire */
	@XmlElement
	private Date smartInfoDate;
	
	/** The rank object representing the current rank of the user */
    @XmlElement
	private MissionHealthRank rank;

    /** The rank object representing the user's new rank should he completed the require mission readiness reports */
    @XmlElement
    private MissionHealthRank pendingRank;

    /** The rank object representing the user's last rank */
    @XmlElement
    private MissionHealthRank previousRank;

    /** The date at which the user achieved the current rank */
    @XmlElement
    @XmlJavaTypeAdapter(DateMarshaller.class)
    private Date rankEffectiveDate;

    /** If true, the user earned a promotion during the most recent mission cycle */
    @XmlElement
    private boolean promoted=false;

	/** The number of points that the user received for creating a profile */
    @XmlElement
	private Integer missionProfilePoints = 0;

    /** The total points earned by the user */
	@XmlElement
	private Integer points = 0;

    /** The total troops earned by the user */
	@XmlElement
	private Integer troops = 0;

    /** Missions created by the user during the current annual cycle but prior to the current mission cycle */
	@XmlElement(name = "pastMissions")
	private List<Mission> missions = new ArrayList<Mission>();

    /** Missions created by the user during the current mission cycle */
    @XmlElement
    private List<Mission> currentMissions = new ArrayList<Mission>();

    /** The total number of missions created by the user */
    @XmlElement
    private Integer totalMissions = 0;

    /** The total number of missions completed by the user */
    @XmlElement
    private Integer totalCompletedMissions = 0;

    /** The number of times the user has logged into the app during the current mission cycle */
    @XmlElement
    private Integer totalLoginsForCycle = 0;

    /** The total number of days during the current mission cycle where the user has logged in */
    @XmlElement
    private Integer totalLoginDaysForCycle  = 0;

    /** Counts how many mission cycles have not had a successful mission before this point.
     *  This field is reset to 0 when the user completes a mission successfully */
    @XmlElement
    private Integer failedMissionCounter=0;

    /** Indicates if the user needs to see a message regarding lost troops. */
    @XmlElement
    private boolean lostTroopsShowMessage=false;
    
    /** A collection containing the user's mission readiness reports */
    @XmlElement
	private List<MissionReadinessReport> missionReadinessReports = new ArrayList<MissionReadinessReport>();

    /** The user's position in the overall standings (user's ranked by total points) */
    @XmlElement
    private Integer standing;

    //@XmlElement
    private MissionHealthStanding weeklyStanding;

    /** The date when the user last created a mission */
    @XmlElement
    @XmlJavaTypeAdapter(DateMarshaller.class)
    private Date lastMissionCreateDate;

    /** The total number of users in the system (at the time of the client request) */
    @XmlElement
    private Integer totalUsers;
    
    /** The total number of missions attempted (but not completed) by the user */
    @XmlElement
    private Integer totalAttemptedMissions=0;

    /** The total number of missions completed during the current annual cycle */
    @XmlElement
    private Integer annualTotalCompletedMissions = 0;

    /** The total points earned by the user during the current annual cycle */
    @XmlElement
    private Integer annualTotalPoints = 0;

    /** The total troops earned by the user during the current annual cycle */
    @XmlElement
    private Integer annualTotalTroops = 0;

    /** The number of cycles since the last user activity */
    @XmlElement
    private Integer inactiveCycles = -1;

    @XmlElement
    private String deviceId;
    
    public MissionHealthDetail() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public MissionHealthProfile getMissionHealthProfile() {
        return missionHealthProfile;
    }

    public void setMissionHealthProfile(MissionHealthProfile missionHealthProfile) {
        this.missionHealthProfile = missionHealthProfile;
    }

    public Date getLoginDate() {
        return loginDate;
    }

    public void setLoginDate(Date loginDate) {
        this.loginDate = loginDate;
    }

    public Date getSmartInfoDate() {
        return smartInfoDate;
    }

    public void setSmartInfoDate(Date smartInfoDate) {
        this.smartInfoDate = smartInfoDate;
    }

    public MissionHealthRank getRank() {
        return rank;
    }

    public void setRank(MissionHealthRank rank) {
        this.rank = rank;
    }

    public MissionHealthRank getPendingRank() {
        return pendingRank;
    }

    public void setPendingRank(MissionHealthRank pendingRank) {
        this.pendingRank = pendingRank;
    }

    public MissionHealthRank getPreviousRank() {
        return previousRank;
    }

    public void setPreviousRank(MissionHealthRank previousRank) {
        this.previousRank = previousRank;
    }

    public Date getRankEffectiveDate() {
        return rankEffectiveDate;
    }

    public void setRankEffectiveDate(Date rankEffectiveDate) {
        this.rankEffectiveDate = rankEffectiveDate;
    }

    public boolean isPromoted() {
        return promoted;
    }

    public void setPromoted(boolean promoted) {
        this.promoted = promoted;
    }

    public Integer getMissionProfilePoints() {
        return missionProfilePoints;
    }

    public void setMissionProfilePoints(Integer missionProfilePoints) {
        this.missionProfilePoints = missionProfilePoints;
    }

    public Integer getPoints() {
        return points;
    }

    public void setPoints(Integer points) {
        this.points = points;
    }

    public Integer getTroops() {
        return troops;
    }

    public void setTroops(Integer troops) {
        this.troops = troops;
    }

    public List<Mission> getMissions() {
        return missions;
    }

    public void setMissions(List<Mission> missions) {
        this.missions = missions;
    }

    public List<Mission> getCurrentMissions() {
        return currentMissions;
    }

    public void setCurrentMissions(List<Mission> currentMissions) {
        this.currentMissions = currentMissions;
    }

    public Integer getTotalMissions() {
        return totalMissions;
    }

    public void setTotalMissions(Integer totalMissions) {
        this.totalMissions = totalMissions;
    }

    public Integer getTotalCompletedMissions() {
        return totalCompletedMissions;
    }

    public void setTotalCompletedMissions(Integer totalCompletedMissions) {
        this.totalCompletedMissions = totalCompletedMissions;
    }

    public void addMission(Mission mission){
        this.setTotalMissions(getTotalMissions()+1);
        this.getCurrentMissions().add(mission);
        this.setLastMissionCreateDate(new Date());
    }
    
    public List<MissionReadinessReport> getMissionReadinessReports() {
		return missionReadinessReports;
	}

	public void setMissionReadinessReports(
			List<MissionReadinessReport> missionReadinessReports) {
		this.missionReadinessReports = missionReadinessReports;
	}
	
	public void addMissionReadinessReport(MissionReadinessReport missionReadinessReport){
        this.getMissionReadinessReports().add(missionReadinessReport);
    }

    public Integer getTotalLoginsForCycle() {
        return totalLoginsForCycle;
    }

    public void setTotalLoginsForCycle(Integer totalLoginsForCycle) {
        this.totalLoginsForCycle = totalLoginsForCycle;
    }

    public Integer getTotalLoginDaysForCycle() {
        return totalLoginDaysForCycle;
    }

    public void setTotalLoginDaysForCycle(Integer totalLoginDaysForCycle) {
        this.totalLoginDaysForCycle = totalLoginDaysForCycle;
    }

    public Date getLastSessionStart() {
        return lastSessionStart;
    }

    public void setLastSessionStart(Date lastSessionStart) {
        this.lastSessionStart = lastSessionStart;
    }

    public Integer getFailedMissionCounter() {
		return failedMissionCounter;
	}

	public void setFailedMissionCounter(Integer failedMissionCounter) {
		this.failedMissionCounter = failedMissionCounter;
	}

    public boolean isLostTroopsShowMessage() {
        return lostTroopsShowMessage;
    }

    public void setLostTroopsShowMessage(boolean lostTroopsShowMessage) {
        this.lostTroopsShowMessage = lostTroopsShowMessage;
    }

    public Date getLastMissionCreateDate() {
        return lastMissionCreateDate;
    }

    public void setLastMissionCreateDate(Date lastMissionCreateDate) {
        this.lastMissionCreateDate = lastMissionCreateDate;
    }

    public Integer getStanding() {
        return standing;
    }

    public void setStanding(Integer standing) {
        this.standing = standing;
    }

    public MissionHealthStanding getWeeklyStanding() {
        return weeklyStanding;
    }

    public void setWeeklyStanding(MissionHealthStanding weeklyStanding) {
        this.weeklyStanding = weeklyStanding;
    }

    public Integer getTotalUsers() {
        return totalUsers;
    }

    public void setTotalUsers(Integer totalUsers) {
        this.totalUsers = totalUsers;
    }
    
    public Integer getAnnualTotalCompletedMissions() {
		return annualTotalCompletedMissions;
	}

	public void setAnnualTotalCompletedMissions(Integer annualTotalCompletedMissions) {
		this.annualTotalCompletedMissions = annualTotalCompletedMissions;
	}

	public Integer getAnnualTotalPoints() {
		return annualTotalPoints;
	}

	public void setAnnualTotalPoints(Integer annualTotalPoints) {
		this.annualTotalPoints = annualTotalPoints;
	}

    public Integer getAnnualTotalTroops() {
		return annualTotalTroops;
	}

	public void setAnnualTotalTroops(Integer annualTotalTroops) {
		this.annualTotalTroops = annualTotalTroops;
	}

	public boolean hasRecentMissions(){
        return getTotalMissions()>0 && getInactiveCycles()>=0 && getInactiveCycles()<4;
    }

    public Integer getTotalAttemptedMissions() {
		return totalAttemptedMissions;
	}

	public void setTotalAttemptedMissions(Integer totalAttemptedMissions) {
		this.totalAttemptedMissions = totalAttemptedMissions;
	}

    public Integer getInactiveCycles() {
        return inactiveCycles;
    }

    public void setInactiveCycles(Integer inactiveCycles) {
        this.inactiveCycles = inactiveCycles;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    @Override
	@XmlElement(name = "object-type")
	public String getObjectType() {
		return this.getClass().getSimpleName();
	}


}
