/*******************************************************************************
 * Copyright © 2010 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.ui.financials.action;

import gov.va.med.esr.common.model.financials.RelaxationPercentage;
import gov.va.med.esr.common.model.lookup.Capability;
import gov.va.med.esr.service.RelaxationPercentageService;
import gov.va.med.esr.ui.common.action.AbstractAction;
import gov.va.med.fw.batchprocess.BatchProcessDetail;
import gov.va.med.fw.validation.ValidationServiceException;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.Validate;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * This struts action is used to support the relaxation percentage add page.
 * 
 * @author DNS   barryc
 */
public class RelaxationPercentageEditAction extends AbstractAction {

	/* GET result */
	public static final String FORWARD_RELAXATION_PERCENTAGE_EDIT = "relaxationPercentage";

	/* POST result */
	public static final String FORWARD_RELAXATION_PERCENTAGE_EDIT_ERROR = "relaxationPercentageEditError";

	/* POST result */
	public static final String FORWARD_RELAXATION_PERCENTAGE_EDIT_CONFIRMATION = "relaxationPercentageEditConfirmation";

	private static final Map METHOD_NAME_OVERRIDES = new HashMap();

	static {
		METHOD_NAME_OVERRIDES.put("ADD", "add");
		METHOD_NAME_OVERRIDES.put("UPDATE", "update");
		METHOD_NAME_OVERRIDES.put("RESET", "reset");
		METHOD_NAME_OVERRIDES.put("CANCEL", "cancel");
	}

	private RelaxationPercentageService service;

	/**
	 * Displays the Relaxation Percentage page.
	 * 
	 * @param mapping
	 *            Struts action mapping for this action
	 * @param form
	 *            Struts form bean for this action
	 * @param request
	 *            The Http Request
	 * @param response
	 *            The Http Response
	 * 
	 * @return A struts action forward for where we will go next.
	 * @throws Exception
	 *             If there are any errors during processing.
	 */
	public ActionForward display(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		RelaxationPercentageUpdateForm rpForm = (RelaxationPercentageUpdateForm) form;

		int currentIncomeYear = getCurrentIncomeYear();
		RelaxationPercentage rp = service
				.getRelaxationPercentageByIncomeYear(currentIncomeYear);
		if (rp == null)
			throw new Exception(
					"No Relaxation Percentage data defined for the current year ("
							+ currentIncomeYear + ")");

		rpForm.setIncomeYear(rp.getIncomeYear());
		rpForm.setValue(rp.getValue().toString());
		rpForm.setRetroactiveProcess(true);

		populateReferenceData(rpForm);

		if (request.getParameter("updateSuccess") != null) {
			ActionMessages actionMessages = new ActionMessages();
			actionMessages.add(ActionMessages.GLOBAL_MESSAGE,
					new ActionMessage(
							"message.relaxationPercentage.changesWereSaved"));
			saveMessages(request, actionMessages);
		}

		request.setAttribute("editCapability",
				Capability.EDIT_RELAXATION_PERCENTAGE.getCode());

		return mapping.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT);
	}

	/** GET request for adding a new relaxation percentage */
	public ActionForward displayAdd(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		RelaxationPercentageAddForm rpForm = (RelaxationPercentageAddForm) form;
		int currentIncomeYear = getCurrentIncomeYear();
		RelaxationPercentage rp = service
				.getRelaxationPercentageByIncomeYear(currentIncomeYear);
		if (rp != null)
			rpForm.setValue(rp.getValue().toString());
		populateReferenceData(rpForm);
		return mapping.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT);
	}

	/**
	 * POST request handler for adding a new relaxation percentage.
	 */
	public ActionForward add(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		RelaxationPercentageAddForm rpForm = (RelaxationPercentageAddForm) form;

		try {
			service.addRelaxationPercentage(new BigDecimal(rpForm.getValue()));
		} catch (ValidationServiceException valEx) {
			setValidationMessages(request, valEx.getValidationMessages());
			populateReferenceData(rpForm);
			return mapping
					.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT_ERROR);
		}

		return mapping
				.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT_CONFIRMATION);
	}

	private void populateReferenceData(ActionForm form) {
		if (form instanceof RelaxationPercentageUpdateForm) {
			RelaxationPercentageUpdateForm rpForm = (RelaxationPercentageUpdateForm) form;
			List allRelaxationPercentages = service
					.getAllRelaxationPercentages();
			rpForm.setAllRelaxationPercentages(allRelaxationPercentages);
		} else if (form instanceof RelaxationPercentageAddForm) {
			RelaxationPercentageAddForm rpForm = (RelaxationPercentageAddForm) form;
			// ...
		}
	}

	public void failedValidationCallback(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) {
		populateReferenceData(form);
	}

	/**
	 * Updates the relaxation percentage information.
	 * 
	 * @param mapping
	 *            Struts action mapping for this action
	 * @param form
	 *            Struts form bean for this action
	 * @param request
	 *            The Http Request
	 * @param response
	 *            The Http Response
	 * 
	 * @return A struts action forward for where we will go next.
	 * @throws Exception
	 *             If there are any errors during processing.
	 */
	public ActionForward update(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		RelaxationPercentageUpdateForm rpForm = (RelaxationPercentageUpdateForm) form;
		BatchProcessDetail batchProcessDetail = 
			(BatchProcessDetail) getLookupCacheService().getByCodeFromCache(BatchProcessDetail.class.getName(), "scheduledJob.relaxationPercentageRetroactiveProcess");

		
		try {
			service.updateRelaxationPercentage(rpForm.getIncomeYear(),
					new BigDecimal(rpForm.getValue()),
					rpForm.isRetroactiveProcess(),batchProcessDetail);
		} catch (ValidationServiceException valEx) {
			setValidationMessages(request, valEx.getValidationMessages());
			populateReferenceData(rpForm);
			return mapping
					.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT_ERROR);
		}

		return mapping
				.findForward(FORWARD_RELAXATION_PERCENTAGE_EDIT_CONFIRMATION);
	}

	public ActionForward cancel(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.findForward(FWD_CANCEL);
	}

	public ActionForward reset(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return display(mapping, form, request, response);
	}

	private int getCurrentIncomeYear() {
		return Calendar.getInstance().get(Calendar.YEAR) - 1;
	}

	protected String getMethodName(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			String parameter) throws Exception {
		String keyName = request.getParameter(parameter);
		String key = (String) METHOD_NAME_OVERRIDES.get(keyName);
		return (key != null) ? key : keyName;
	}

	public void afterPropertiesSet() throws Exception {
		Validate.notNull(service,
				"The " + RelaxationPercentageService.class.getName()
						+ " field must be set in " + getClass().getName());
	}

	/**
	 * Handles an optimistic lock exception by resetting the form and
	 * redisplaying the page.
	 * 
	 * @param mapping
	 *            Struts action mapping for this action
	 * @param form
	 *            Struts form bean for this action
	 * @param request
	 *            The Http Request
	 * @param response
	 *            The Http Response
	 * 
	 * @return A struts action forward for where we will go next.
	 * @throws Exception
	 *             If there are any errors during processing.
	 */
	protected ActionForward handleOptimisticLockException(
			ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		form.reset(mapping, request);
		return display(mapping, form, request, response);
	}

	public void setService(RelaxationPercentageService service) {
		this.service = service;
	}

}