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

// Java classes
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;

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

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import gov.va.med.fw.conversion.ConversionServiceException;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.validation.ValidationMessage;
import gov.va.med.fw.validation.ValidationMessages;

import gov.va.med.esr.common.model.insurance.InsurancePolicy;
import gov.va.med.esr.common.model.insurance.Medicare;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.ui.common.action.AddressForm;
import gov.va.med.esr.ui.util.SessionManager;

/**
 * @author DNS   RAMACP
 *         <p/>
 *         TODO To change the template for this generated type comment go to Window - Preferences -
 *         Java - Code Style - Code Templates
 */
public class InsuranceEditAction extends InsuranceInfoAction
{

    public InsuranceEditAction()
    {
        super();
    }


    /**
     * Displays a search result page.
     *
     * @param mapping An action mapping
     * @param form A form bean
     * @param request A http request from an search.jsp page
     * @param response A http response to stream data to a next page
     *
     * @return An action forward class encapsulating information about a next page
     * @throws Exception Thrown if failed to process
     */
    public ActionForward display(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception
    {

        InsuranceInfoForm insForm =
            (form instanceof InsuranceInfoForm) ? (InsuranceInfoForm)form : null;

        if (insForm != null) {
	        boolean isAddAPerson = false;
	        isAddAPerson = SessionManager.isAddAPerson(request);
	        insForm.setAddAPerson(isAddAPerson);
	        
	        String insuranceId = insForm.getInsuranceId();
	        if (StringUtils.isNotEmpty(insuranceId))
	        {
	            // Get the Person object from the cache
	            Person person = getSelectedPerson(request);
	
	            InsurancePolicy insPolicy = getInsuranceById(person, insuranceId);
	            if (insPolicy != null)
	            {
	                prepopulateForm(insForm, insPolicy);
	            }
	        }
        }
        return mapping.findForward("success");

    }

    public ActionForward editMedicare(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception
    {

        InsuranceMedicareForm medicareForm = (InsuranceMedicareForm)form;
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        medicareForm.setAddAPerson(isAddAPerson);
        
        Person person = getSelectedPerson(request);
        //get Medicare policies (A & B ) and populate the form
        conversionService.convert(person, medicareForm);
        //Check and Set the defaults
        return mapping.findForward("success");
    }

    public ActionForward copyPartAtoB(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception
    {

        InsuranceMedicareForm medicareForm = (InsuranceMedicareForm)form;
        medicareForm.copyPartAtoB();
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        medicareForm.setAddAPerson(isAddAPerson);
        return mapping.getInputForward();
    }


    public ActionForward update(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
    {
       //Medicare Add and Update
        if (form instanceof InsuranceMedicareForm)
        {
            return updateMedicare(mapping, form, request, response);
        }

        InsuranceInfoForm insForm =
            (form instanceof InsuranceInfoForm) ? (InsuranceInfoForm)form : null;

        ActionForward samePageForward = mapping.findForward(FORWARD_RETURN_TO_SAME_PAGE);
        if (insForm == null) {
        	return samePageForward;
        }
        
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        insForm.setAddAPerson(isAddAPerson);
        
        // Get the Person object from the cache
        Person person = getSelectedPerson(request);

        // Create some action forwards
        ActionForward overviewSuccessForward =
            new ActionForward(mapping.findForward(FORWARD_TO_OVERVIEW_PAGE));
        

        // Perform US extra validation
        if (Country.isUSAddress(insForm.getCountry()))
        {
            // Validate the state
            if (!stateValid(insForm, AddressForm.class, STATE_FIELD, overviewSuccessForward,
                request))
            {
                return samePageForward;
            }

            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(insForm, AddressForm.class, CITY_FIELD, STATE_FIELD,
                ZIPCODE_FIELD, request))
            {
                return samePageForward;
            }
        }

        String insuranceId = insForm.getInsuranceId();
        if (StringUtils.isNotEmpty(insuranceId))
        {
            Person clonePerson = (Person)person.clone();

            InsurancePolicy insPolicy = getInsuranceById(clonePerson, insuranceId);
            if (insPolicy != null)
            {
                conversionService.convert(form, insPolicy);
                // Call service layer here
                
                ValidationMessages messages = new ValidationMessages();
                if (!isAddAPerson)
                	messages = getInsuranceService().updateInsurance(clonePerson); 

                // Store updated person in the cache
                updateSelectedPerson(request, clonePerson);
                
                return getForwardPathFromValidationMessages(mapping, messages,
                        FORWARD_TO_OVERVIEW_PAGE);             
            }
        }

        return overviewSuccessForward;
    }

    public ActionForward delete(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
    {
        Person person = getSelectedPerson(request);
        Person clonePerson = (Person)person.clone();
    	
        if (form instanceof InsuranceMedicareForm)
        {
        	InsuranceMedicareForm insForm = (InsuranceMedicareForm)form;
        	  boolean isAddAPerson = false;
              isAddAPerson = SessionManager.isAddAPerson(request);
              insForm.setAddAPerson(isAddAPerson);
              
            Medicare partA = null;
            Medicare partB = null;

            //TODO code is duplicated move to a function
            //Get Medicare policies
            Iterator iter = clonePerson.getInsurances().iterator();

            while (iter.hasNext())
            {
                InsurancePolicy insPolicy = (InsurancePolicy)iter.next();

                //Ignore the policies from other sites
                if (insPolicy instanceof Medicare &&
                    (insPolicy.getReportSite() == null ||
                        VAFacility.CODE_HEC.getName().equals(
                            insPolicy.getReportSite().getStationNumber())))
                {
                    Medicare medicare = (Medicare)insPolicy;
                    if (medicare.isEnrolledInPartB() != null &&
                        Boolean.TRUE.equals(medicare.isEnrolledInPartB()))
                    {
                        partB = medicare;
                    }
                    else if (medicare.isEnrolledInPartA() != null &&
                        Boolean.TRUE.equals(medicare.isEnrolledInPartA()))
                    {
                        partA = medicare;
                    }
                    else
                    {
                        //Erronious medicare policy
                        throw new ConversionServiceException("Medicare Insurance found without Part A or B indicators");
                    }
                }
            }
            if (partA != null)
            {
            	clonePerson.removeInsurance(partA);
            }
            if (partB != null)
            {
            	clonePerson.removeInsurance(partB);
            }

        } else
        {
	        InsuranceInfoForm insForm =
	            (form instanceof InsuranceInfoForm) ? (InsuranceInfoForm)form : null;
	        if (insForm != null) {
		        boolean isAddAPerson = false;
		        isAddAPerson = SessionManager.isAddAPerson(request);
		        insForm.setAddAPerson(isAddAPerson);
		        String insuranceId = insForm.getInsuranceId();
		        
		        if (StringUtils.isNotEmpty(insuranceId))
		        {
		        	InsurancePolicy insPolicy = getInsuranceById(clonePerson, insuranceId);
		            if (insPolicy != null)
		            {
		            	clonePerson.removeInsurance(insPolicy);
		            }
		        }
	        }
        }
        
        // Call service layer here
        ValidationMessages messages = getInsuranceService().updateInsurance(clonePerson); 
    	
        // Store updated person in the cache
        updateSelectedPerson(request, clonePerson);
   
        return new ActionForward(mapping.findForward(FORWARD_TO_OVERVIEW_PAGE));
    }

    public ActionForward updateMedicare(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
    {
        InsuranceMedicareForm insForm = (InsuranceMedicareForm)form;

        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        insForm.setAddAPerson(isAddAPerson);
        
        // Get the Person object from the cache
        Person person = getSelectedPerson(request);

        // Create some action forwards
        ActionForward overviewSuccessForward =
            new ActionForward(mapping.findForward(FORWARD_TO_OVERVIEW_PAGE));
        ActionForward samePageForward = mapping.findForward(FORWARD_RETURN_TO_SAME_PAGE);

        // Perform US extra validation for Address 1
        if (Country.isUSAddress(insForm.getCountry()))
        {
            // Validate the state
            if (!stateValid(insForm, AddressForm.class, STATE_FIELD, overviewSuccessForward,
                request))
            {
                return samePageForward;
            }

            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(insForm, AddressForm.class, CITY_FIELD, STATE_FIELD,
                ZIPCODE_FIELD, request))
            {
                return samePageForward;
            }
        }

        // Perform US extra validation for Address 2
        if (Country.isUSAddress(insForm.getCountry2()))
        {
            // Validate the state
            if (!stateValid(insForm, InsuranceMedicareForm.class, STATE2_FIELD, overviewSuccessForward,
                request))
            {
                return samePageForward;
            }

            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(insForm, InsuranceMedicareForm.class, CITY2_FIELD, STATE2_FIELD,
                ZIPCODE2_FIELD, request))
            {
                return samePageForward;
            }
        }

        Person clonePerson = (Person)person.clone();

        conversionService.convert(form, clonePerson);

        // Call service layer here
        
        ValidationMessages messages = new ValidationMessages();
        // Call service layer here
        if (!isAddAPerson)
        	messages =  getInsuranceService().updateInsurance(clonePerson); 
        
        //Store updated person in the cache
        updateSelectedPerson(request, clonePerson);

        return getForwardPathFromValidationMessages(mapping, messages,
                FORWARD_TO_OVERVIEW_PAGE);
  
    }


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


    /**
     * Initialize and get the Struts lookup dispatch method map hashmap.
     *
     * @return the method map
     * @see org.apache.struts.actions.LookupDispatchAction#getKeyMethodMap()
     */
    protected Map getKeyMethodMap()
    {
        if (keyMethodMap == null)
        {
            keyMethodMap = new HashMap();
            keyMethodMap.put("button.display", "display");
            keyMethodMap.put("button.update", "update");
            keyMethodMap.put("button.delete", "delete");
            keyMethodMap.put("button.cancel", "cancel");
            keyMethodMap.put("text.editMedicare", "editMedicare");
            keyMethodMap.put("button.addMedicare", "editMedicare");
            keyMethodMap.put("button.copyPartAData", "copyPartAtoB");
        }
        return keyMethodMap;
    }

    private void prepopulateForm(InsuranceInfoForm form, InsurancePolicy insurance)
        throws ConversionServiceException
    {
        if (conversionService != null)
        {
            conversionService.convert(insurance, form);
        }
    }

}


 