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

// Java Classes
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.SiteYear;
import gov.va.med.esr.common.model.financials.DependentFinancials;
import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.SpouseFinancials;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.rule.service.impl.RuleValidationMessage;
import gov.va.med.esr.common.ui.form.FinancialDetailsForm;
import gov.va.med.esr.service.FinancialsService;
import gov.va.med.esr.ui.common.action.PersonAbstractAction;
import gov.va.med.esr.ui.common.action.AddressValidationAction;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.esr.ui.util.SessionManager;
import gov.va.med.fw.service.ServiceConfigurationException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.validation.ValidationServiceException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Calendar;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionForm;

/**
 * Base Struts action class that will support various Financials screens.
 *
 * @author Priya Ramachandran
 * @author Andrew Pach
 * @version: 3.0
 */
// public class FinancialsAction extends PersonAbstractAction implements FinancialsConstants
public class FinancialsAction extends AddressValidationAction implements FinancialsConstants
{
    private FinancialsService financialsService;

    // Struts forwards
    public static final String FORWARD_FINANCIALS_OVERVIEW = "financialsOverview";
    public static final String FORWARD_FINANCIALS_SUMMARY = "financialSummary";
    public static final String FORWARD_FINANCIAL_REVIEW_IMPACT = "finacialReviewImpact";
    public static final String FORWARD_FINANCIAL_REVIEW_IMPACT_DISPLAY = "finacialReviewImpactDisplay";
    public static final String FORWARD_FINANCIAL_DETAILS_EDIT = "financialDetailsEdit";
    public static final String FORWARD_RETURN_TO_FINANCIAL_DETAILS_EDIT = "returnToFinancialDetailsEdit";
    public static final String FORWARD_ADJUDICATION = "adjudication";
    public static final String FORWARD_CANCEL = "cancel";
    // public final static String Y  = "y";
    // public final static String N  = "n";
    // public final static String ND    = "nd";

    public FinancialsAction()
    {
        super();
    }

    /**
     * Sets the currently selected income year in the session.
     *
     * @param request The HttpServletRequest
     * @param incomeYear The currently selected income year
     */
    protected void setSelectedIncomeYear(HttpServletRequest request, Integer incomeYear)
    {
        SessionManager.setSelectedFinancialIncomeYear(request, incomeYear);
    }

    /**
     * Gets the currently selected income year from the session.
     *
     * @param request The HttpServletRequest
     * @return The currently selected income year or null if one hasn't been set.
     */
    protected Integer getSelectedIncomeYear(HttpServletRequest request)
    {
        return SessionManager.getSelectedFinancialIncomeYear(request);
    }

    /**
     * Removes the currently selected income year from the session.
     *
     * @param request The HttpServletRequest
     */
    protected void removeSelectedIncomeYear(HttpServletRequest request)
    {
        SessionManager.removeSelectedFinancialIncomeYear(request);
    }

    /**
     * Determines the valid years a veteran can view/add/edit an income test
     * @param person The person to determine the valid years for
     * @return The list of valid years - sorted.
     */
    protected List determineValidIncomeYears(Person person)
    {
        // Get a list of all income tests for this Person
        Map incomeTestMap = person.getIncomeTests();

        // Create the set of valid income years by starting with every year an income test is defined
        // for the veteran
        Set validIncomeYears = new HashSet(incomeTestMap.keySet());
        
        //Add the income years related Beneficiary travel
        Map beneficiaryTravels = person.getBeneficiaryTravels();
        if (beneficiaryTravels != null && beneficiaryTravels.size() > 0) {
            Set keySet = beneficiaryTravels.keySet();
            for (Iterator i=keySet.iterator(); i.hasNext();) {
                SiteYear siteYear = (SiteYear) i.next();
                validIncomeYears.add(siteYear.getYear());
            }
        }

  // Code change to reflect the requirement to select the current income year minus one for the first ninety (90) days of the current calendar year.        
        //Find the day of the year
        Calendar calendar = Calendar.getInstance();
        int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);  
        int year = calendar.get(Calendar.YEAR);
        

        /*/ Previous code commented to meet the requirement to display the previous income year for first 90 days of current calendar year 
         Add the current year and the following year
        int prevYear = DateUtils.getCurrentYear() -1;
        validIncomeYears.add(new Integer(prevYear));   */
        
        //get 90th day from begining of the year
        Calendar cal = Calendar.getInstance();
        cal.setTime(gov.va.med.fw.util.DateUtils.getYearStartDate(year));
        cal.add(Calendar.DATE, 90);
        Date temp90 = cal.getTime();
     
                       
        if(gov.va.med.fw.util.DateUtils.isAfter(calendar.getTime(), temp90)){
            int prevYear = DateUtils.getCurrentYear() -1;
            validIncomeYears.add(new Integer(prevYear));
        }
        else{
            int prevYear1 = DateUtils.getCurrentYear() -1;
            validIncomeYears.add(new Integer(prevYear1));
            int prevYear2 = DateUtils.getCurrentYear() -2;
            validIncomeYears.add(new Integer(prevYear2));
        }

       

        // Convert the set to a list and sort it
        ArrayList yearList = new ArrayList(validIncomeYears);
        Collections.sort(yearList);

        // Return the final list
        return yearList;
    }
    /**
     * Checks to ensure the passed in ActionForm is not null and of the correct type.
     *
     * @param form The struts form to check
     *
     * @return The passed in form type-casted to a FinancialsForm
     * @throws gov.va.med.fw.service.ServiceConfigurationException if the form is null or of an incorrect type.
     */
    protected FinancialsForm getFinancialsForm(ActionForm form) throws ServiceConfigurationException
    {
        FinancialsForm personalForm =
            (form instanceof FinancialsForm) ? (FinancialsForm)form : null;
        if (personalForm == null)
        {
            throw new ServiceConfigurationException("FinancialsForm not properly configured.");
        }
        return personalForm;
    }

    /**
     * Checks to ensure the passed in ActionForm is not null and of the correct type.
     *
     * @param form The struts form to check
     *
     * @return The passed in form type-casted to a FinancialDetailsForm
     * @throws gov.va.med.fw.service.ServiceConfigurationException if the form is null or of an incorrect type.
     */
    protected FinancialDetailsForm getFinancialDetailsForm(ActionForm form) throws ServiceConfigurationException
    {
        FinancialDetailsForm personalForm =
            (form instanceof FinancialDetailsForm) ? (FinancialDetailsForm)form : null;
        if (personalForm == null)
        {
            throw new ServiceConfigurationException("FinancialDetailsForm not properly configured.");
        }
        return personalForm;
    }

    /**
     * Checks to ensure the passed in ActionForm is not null and of the correct type.
     *
     * @param form The struts form to check
     * @return The passed in form type-casted to a FinancialsDependentForm
     * @throws gov.va.med.fw.service.ServiceConfigurationException if the form is null or of an incorrect type.
     */
    protected FinancialsDependentForm getFinancialsDependentForm(ActionForm form) throws ServiceConfigurationException
    {
        FinancialsDependentForm personalForm =
            (form instanceof FinancialsDependentForm) ? (FinancialsDependentForm)form : null;
        if (personalForm == null)
        {
            throw new ServiceConfigurationException("FinancialsDependentForm not properly configured.");
        }
        return personalForm;
    }

    public void afterPropertiesSet()
    {
        // Check for required fields
    }

    /**
     * @return Returns the financialsService.
     */
    public FinancialsService getFinancialsService()
    {
        return financialsService;
    }

    /**
     * @param financialsService The financialsService to set.
     */
    public void setFinancialsService(FinancialsService financialsService)
    {
        this.financialsService = financialsService;
    }
    
    protected SpouseFinancials getSpouseFinancialsById(Person person, String financialsId, Integer incomeYear) {
        
        if(incomeYear != null && StringUtils.isNotEmpty(financialsId)) {
            FinancialStatement ftmt = person.getFinancialStatement(incomeYear);
            return ftmt.getSpouseFinancialsByEntityKey(CommonEntityKeyFactory.createSpouseFinancialsEntityKey(financialsId));  
        }
        return null;
    }
    
    protected DependentFinancials getDependentFinancialsById(Person person, String financialsId, Integer incomeYear) {
        
        if(incomeYear != null && StringUtils.isNotEmpty(financialsId)) {
            FinancialStatement ftmt = person.getFinancialStatement(incomeYear);
            return ftmt.getDependentFinancialsByEntityKey(CommonEntityKeyFactory.createDependentFinancialsEntityKey(financialsId));  
        }
        return null;
    }

    /**
     * @param detailsForm
     * @param incomeYear
     * @param clonePerson
     * @return
     * @throws ServiceException
     * @throws ValidationServiceException
     */
    protected Person invokeAssessReviewImpact(FinancialDetailsForm detailsForm, Integer incomeYear, Person clonePerson) throws ServiceException {
        // Call service layer here
        try {
            return getFinancialsService().assessFinancialImpact(incomeYear,clonePerson);
        } catch (ValidationServiceException ex) {
            setAdjudicationProperty(ex, detailsForm);
            throw ex;
        }
    }

    /**
     * @param detailsForm
     * @param incomeYear
     * @param person
     * @return
     * @throws ServiceException
     * @throws ValidationServiceException
     */
    protected Person invokeUpdateFinancialAssessment(FinancialDetailsForm detailsForm, Integer incomeYear, Person person) throws ServiceException {
        // Call service layer here
        try {
            return getFinancialsService().updateFinancialAssessment(incomeYear,person);
        } catch (ValidationServiceException ex) {
            setAdjudicationProperty(ex, detailsForm);
            throw ex;
        }
    }

    /**
     * @param ex
     * @param detailsForm
     */
    private void setAdjudicationProperty(ValidationServiceException ex, FinancialDetailsForm detailsForm) {
        if (ex.getValidationMessages() != null
                && ex.getValidationMessages().contains(RuleValidationMessage.SEND_TO_ADJUDICATION_REQUIRED.getCode())) {
            detailsForm.setAskAdjudicationQuestion(true);
            // VFA-SP1
            // detailsForm.setSendForAdjudication(getYesNoNoData(Boolean.FALSE));
        }
    }
    /*
    private String getYesNoNoData(Boolean flag) {
            if(flag == null) return ND;
            return (flag.booleanValue() == true) ? Y : N;
    }
    */
}