package com.agilex.vamf.missionhealth.service;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import com.agilex.vamf.missionhealth.domain.Mission;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.stereotype.Service;

import com.agilex.vamf.missionhealth.domain.MissionHealthDetail;

@Service
public class PointService {

	private static final int LOGGING_POINTS = 10;
	private static final int SMARTINFO_POINTS = 5;
    //Profile points is 40 but user don't get profile points and login points until they complete the profile. So when profile completed login+profile point=40
    //This is done to keep logic change for points minimal
    private static final int PROFILE_POINTS = 30;
    private static final int EMAILFACEBOOK_POINTS=10;
    private static final int CRITICAL_MISSION_POINTS = 200;
    private static final int CRITICAL_MISSION_PERCENTAGE = 90;
    private static final int MISSION_READINESS_POINTS=50;
    private static final int MISSION_READINESS_POINTS_CRITERIA=5;
	
	public boolean updatePointsForLogging(MissionHealthDetail missionHealthDetail) {
		
		boolean updated = false;
		if (missionHealthDetail.getLoginDate() == null || !((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) > 0) ||  !DateUtils.isSameDay(missionHealthDetail.getLoginDate(), new Date())) {
			missionHealthDetail.setLoginDate(new Date());
			missionHealthDetail.setPoints((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) + LOGGING_POINTS);
			missionHealthDetail.setAnnualTotalPoints((missionHealthDetail.getAnnualTotalPoints()==null?0:missionHealthDetail.getAnnualTotalPoints()) + LOGGING_POINTS);
            missionHealthDetail.setTotalLoginDaysForCycle(missionHealthDetail.getTotalLoginsForCycle()+1);
            updated = true;
		}
		return updated;
		
	}

	public boolean updatePointsForCompletingMissionProfile(MissionHealthDetail missionHealthDetail) {
		
		boolean updated = false;
		if (missionHealthDetail.getMissionHealthProfile() != null) {
			missionHealthDetail.setMissionProfilePoints(PROFILE_POINTS);
			missionHealthDetail.setPoints((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) + PROFILE_POINTS);
			missionHealthDetail.setAnnualTotalPoints((missionHealthDetail.getAnnualTotalPoints()==null?0:missionHealthDetail.getAnnualTotalPoints()) + PROFILE_POINTS);
			updated = true;
		}
		return updated;
		
	}
	
	public boolean updatePointsForSmartInfo(MissionHealthDetail missionHealthDetail) {

		boolean updated = false;

		if (missionHealthDetail.getSmartInfoDate() == null || !DateUtils.isSameDay(missionHealthDetail.getSmartInfoDate(), new Date())) {
			missionHealthDetail.setSmartInfoDate(new Date());
			missionHealthDetail.setPoints((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) + SMARTINFO_POINTS);
			missionHealthDetail.setAnnualTotalPoints((missionHealthDetail.getAnnualTotalPoints()==null?0:missionHealthDetail.getAnnualTotalPoints()) + SMARTINFO_POINTS);
			updated = true;
		}
		return updated;

	}

    public boolean updatePointsForEmailOrFacebook(MissionHealthDetail missionHealthDetail) {

        boolean updated = true;

        missionHealthDetail.setPoints((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) + EMAILFACEBOOK_POINTS);
        missionHealthDetail.setAnnualTotalPoints((missionHealthDetail.getAnnualTotalPoints()==null?0:missionHealthDetail.getAnnualTotalPoints()) + EMAILFACEBOOK_POINTS);
        updated = true;

        return updated;

    }

    public Mission setPointsForNewMission(PointsRule pointsRule, Mission mission, boolean isCritical){
        if(isCritical){
            mission.setThresholdPercentage(Integer.toString(CRITICAL_MISSION_PERCENTAGE)+"%");
            mission.setTotalPoints(CRITICAL_MISSION_POINTS);
        } else {
            mission.setThresholdPercentage(Integer.toString(getRandomNumberForRange(pointsRule.getMissionThresholds().getLower(), pointsRule.getMissionThresholds().getUpper(), pointsRule.getMissionThresholds().getInterval()))+"%");
            mission.setTotalPoints(getRandomNumberForRange(pointsRule.getPointThresholds().getLower(), pointsRule.getPointThresholds().getUpper(), pointsRule.getPointThresholds().getInterval()));
            mission.setPointsRange(getRange(pointsRule.getPointThresholds().getLower(), pointsRule.getPointThresholds().getUpper(), pointsRule.getPointThresholds().getInterval()));
        }
        return mission;
    }

    private int getRandomNumberForRange(int lowerBound, int upperBound, int interval){
        SecureRandom random = new SecureRandom();
        int convertedLowerBound = lowerBound/interval;
        int convertedUpperBound = upperBound/interval;

        int randInt = random.nextInt(convertedUpperBound-convertedLowerBound)+convertedLowerBound;
        return randInt*interval;
    }

    private List<Integer> getRange(int lowerBound, int upperBound, int interval){
        List<Integer> range = new ArrayList<Integer>();
        Integer value = Integer.valueOf(lowerBound);
        while(value <= upperBound){
            range.add(value);
            value+=interval;
        }
        return range;
    }
    
    public boolean updatePointsForMissionReadinessReport(MissionHealthDetail missionHealthDetail) {

		boolean updated = false;

		if (missionHealthDetail.getMissionReadinessReports()!=null && !(missionHealthDetail.getMissionReadinessReports().isEmpty()) && missionHealthDetail.getMissionReadinessReports().size()%MISSION_READINESS_POINTS_CRITERIA==0) {
			missionHealthDetail.setPoints((missionHealthDetail.getPoints()==null?0:missionHealthDetail.getPoints()) + MISSION_READINESS_POINTS);
			missionHealthDetail.setAnnualTotalPoints((missionHealthDetail.getAnnualTotalPoints()==null?0:missionHealthDetail.getAnnualTotalPoints()) + MISSION_READINESS_POINTS);
			updated = true;
		}
		return updated;

	}
}
