package eu.dnetlib.goldoa.service.eligibility;

import eu.dnetlib.goldoa.domain.Eligibility;
import eu.dnetlib.goldoa.domain.Project;
import eu.dnetlib.goldoa.domain.Request;
import eu.dnetlib.goldoa.service.EligibilityManager;
import eu.dnetlib.goldoa.service.ProjectManager;
import eu.dnetlib.goldoa.service.RequestManager;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by antleb on 3/9/15.
 */
public class ProjectEligibiliyManager implements EligibilityManager {

	@Autowired
	private ProjectManager projectManager;
	@Autowired
	private RequestManager requestManager;

	private long expirationOk;
	private float expirationThreshold;
	private String expirationIffy;
	private String expirationNono;
	private String stillRunningNono;

	private int maxRequests;
	private String maxRequestsNono;

	@Override
	public Eligibility validate(Request request) {
		Eligibility eligibility = new Eligibility();

		if (request.getProject() != null) {
			Project project = projectManager.getById(request.getProject()).getProject();

			eligibility.merge(validateExpirationDate(project));
			eligibility.merge(validateNumberOfRequests(project));
		}
		return eligibility;
	}

	private Eligibility validateNumberOfRequests(Project project) {
		List<Request> requests = requestManager.getForProject(project.getId());
		int completed = 0;

		for (Request request : requests) {
			switch (Request.RequestStatus.forStatus(request.getStatus())) {
				case CONDITIONALLY_APPROVED:
				case APPROVED:
				case ACCOUNTING_PROCESSING:
				case ACCOUNTING_ON_HOLD:
				case ACCOUNTING_PAID:
					completed++;
					break;
			}
		}

		if (completed >= maxRequests)
			return new Eligibility(Eligibility.Status.NONO, maxRequestsNono);

		return Eligibility.OK;
	}

	private Eligibility validateExpirationDate(Project project) {

		if (!project.getEndDate().before(new Date())) {
			return new Eligibility(Eligibility.Status.NONO, stillRunningNono);
		} else if (project.getEndDate().after(new Date(System.currentTimeMillis() - expirationOk))) {
			return Eligibility.OK;
		} else if (project.getEndDate().after(new Date((long) (System.currentTimeMillis() - (1.0f + expirationThreshold) * expirationOk)))) {
			return new Eligibility(Eligibility.Status.IFFY, expirationIffy);
		} else {
			return new Eligibility(Eligibility.Status.NONO, expirationNono);
		}

//		try {
//			Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2013");
//
//			if (project.getEndDate().after(date)) {
//				if (project.getEndDate().before(new Date()))
//					return new Eligibility(Eligibility.Status.OK);
//				else
//					return new Eligibility(Eligibility.Status.NONO, stillRunningNono);
//			} else
//				return new Eligibility(Eligibility.Status.NONO, expirationNono);
//		} catch (ParseException e) {
//			e.printStackTrace();
//
//			return Eligibility.OK;
//		}
	}

	public ProjectManager getProjectManager() {
		return projectManager;
	}

	public void setProjectManager(ProjectManager projectManager) {
		this.projectManager = projectManager;
	}

	public RequestManager getRequestManager() {
		return requestManager;
	}

	public void setRequestManager(RequestManager requestManager) {
		this.requestManager = requestManager;
	}

	public long getExpirationOk() {
		return expirationOk;
	}

	public void setExpirationOk(long expirationOk) {
		this.expirationOk = expirationOk * 1000L * 60 * 60 * 24 * 30;
	}

	public float getExpirationThreshold() {
		return expirationThreshold;
	}

	public void setExpirationThreshold(float expirationThreshold) {
		this.expirationThreshold = expirationThreshold;
	}

	public String getExpirationIffy() {
		return expirationIffy;
	}

	public void setExpirationIffy(String expirationIffy) {
		this.expirationIffy = expirationIffy;
	}

	public String getExpirationNono() {
		return expirationNono;
	}

	public void setExpirationNono(String expirationNono) {
		this.expirationNono = expirationNono;
	}

	public int getMaxRequests() {
		return maxRequests;
	}

	public void setMaxRequests(int maxRequests) {
		this.maxRequests = maxRequests;
	}

	public String getMaxRequestsNono() {
		return maxRequestsNono;
	}

	public void setMaxRequestsNono(String maxRequestsNono) {
		this.maxRequestsNono = maxRequestsNono;
	}

	public String getStillRunningNono() {
		return stillRunningNono;
	}

	public void setStillRunningNono(String stillRunningNono) {
		this.stillRunningNono = stillRunningNono;
	}
}
