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

import gov.va.med.esr.common.model.person.Association;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.lookup.AssociationType;
import gov.va.med.esr.common.model.lookup.Country;
import gov.va.med.esr.ui.ApplicationConstants.MessageKeys;
import gov.va.med.esr.ui.admin.action.SearchActionForm;
import gov.va.med.esr.ui.common.action.AddressForm;
import gov.va.med.esr.ui.util.SessionManager;
import gov.va.med.fw.ui.UIConstants;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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 org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**
 * Action handler for adding a new Associate.
 * 
 * @author Muddaiah Ranga
 * @version 3.0
 */
public class PersonAssociationAddAction extends PersonAssociationAction
{
    /**
     * Displays form to add a new Associate.
     *
     * @param mapping Struts action mapping for this action
     * @param actionForm 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 actionForm,
								 HttpServletRequest request, 
								 HttpServletResponse response) 
	throws Exception 
	{
		PersonAssociationInfoForm form = (PersonAssociationInfoForm)actionForm;
        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        form.setAddAPerson(isAddAPerson);
		return mapping.findForward(DISPLAY);
	}
	
	
	public ActionForward clear(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
	throws Exception
	{
		PersonAssociationInfoForm form = (PersonAssociationInfoForm)actionForm;
		form.clearForm();
		boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        form.setAddAPerson(isAddAPerson);
		return mapping.findForward(DISPLAY);     
	}


    /**
     * Adds a new Associate.
     *
     * @param mapping Struts action mapping for this action
     * @param actionForm 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 addAssociate(ActionMapping mapping, 
										ActionForm actionForm,
										HttpServletRequest request, 
										HttpServletResponse response) 
	throws Exception 
	{
        PersonAssociationInfoForm form = (PersonAssociationInfoForm)actionForm;
        Person person = getSelectedPerson(request);

        boolean isAddAPerson = false;
        isAddAPerson = SessionManager.isAddAPerson(request);
        form.setAddAPerson(isAddAPerson);

        String errText = "{0} required for this role";
       
        // Create some action forwards
        ActionForward overviewSuccessForward =
            new ActionForward(mapping.findForward(OVERVIEW_WITH_MESSAGE));
        ActionForward displayForward = mapping.findForward(DISPLAY);

        // Perform validation based on the role.
        if (!performRoleValidation(form, request, errText)) {
        	return displayForward;
        }
        
        // Perform US extra validation
        if (Country.isUSAddress(form.getCountry()))
        {
            boolean addressValid = true;
            // Validate the state
            if (!stateValid(form, AddressForm.class, STATE_FIELD, overviewSuccessForward, request))
            {
            	addressValid = false;
            }

            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(form, AddressForm.class, CITY_FIELD, STATE_FIELD, ZIPCODE_FIELD, request))
            {
            	addressValid = false;
             }
            
            if (addressValid) {
            	// make sure there is an address1
            	
            	if (form.getAddressLine1().length() == 0) {
            		addressValid = false;
            	}
            }
            if (!validateAddressPhone(form, request)) {
            	return displayForward;
            }
            
        }

        Association association = new Association();
        conversionService.convert(form,association);
        Person updatedPerson = (Person)person.clone();
        updatedPerson.addAssociation(association);

        if (isAddAPerson){
        	if (association!=null){
        		updatedPerson =  association.getPerson();
        	}
        	// CCR11349 -- Add A Person: Last Update Date for contacts not popoulated in ZCT 10
            association.setLastUpdateDate(new Date());
        	updateSelectedPerson(request, updatedPerson);
        }
        else{
        	updatedPerson = this.getAssociationService().updateAssociation( updatedPerson,association );
        	updateSelectedPerson(request,updatedPerson);
        }

		return overviewSuccessForward;
	}
	
	/** Validate a role.  This checks the roles and makes sure the necessary values
	 * for the role have been entered.
	 */
	private boolean performRoleValidation(
			PersonAssociationInfoForm form, 
	        HttpServletRequest request,
	        String errText) 
	throws Exception {
		String role = form.getRole();
		String str;
        ActionMessages errors = form.getActionMessages(request);
        boolean valid = true;
        if (role.equals(AssociationType.CODE_POWER_OF_ATTORNEY.getCode()) ||
				role.equals(AssociationType.CODE_GUARDIAN_VA.getCode()) ||
				role.equals(AssociationType.CODE_GUARDIAN_CIVIL.getCode())) {

        	// the Organization/Name is required
			str = form.getOrganizationName();
			if (str.length() == 0) {
				valid = false;
				errors.add("orginazationName", new ActionMessage(MessageKeys.ERRORS_REQUIRED, "Organization"));
			}
			
		} else if (role.equals(AssociationType.CODE_DESIGNEE.getCode())) {
			boolean validName, validAddress;
	    	validName = validateNames(errors, form);
	    	validAddress = validateAddressPhone(form, request);
	    	valid = validName && validAddress;
			
		} else if (role.equals(AssociationType.CODE_EMERGENCY_CONTACT.getCode()) ||
				role.equals(AssociationType.CODE_OTHER_EMERGENCY_CONTACT.getCode()) || 
				role.equals(AssociationType.CODE_PRIMARY_NEXT_OF_KIN.getCode()) || 
				role.equals(AssociationType.CODE_OTHER_NEXT_OF_KIN.getCode())) {

				boolean validName, validAddress, validRelationship = true;
		    	validName = validateNames(errors, form);
		    	validAddress = validateAddressPhone(form, request);
				if (form.getRelationship().length() == 0) {
					validRelationship = false;
					errors.add("relationship", new ActionMessage(MessageKeys.ERRORS_REQUIRED, "Relationship"));
				}
				valid = validName && validAddress && validRelationship;
		} else {
			// should not happen because role is from a pulldown menu.
		}

		return valid;
	}
	


	private boolean validateAddressPhone(
			PersonAssociationInfoForm form, 
	        HttpServletRequest request) 
	throws Exception {
		String role = form.getRole();
        ActionMessages errors = form.getActionMessages(request);
        boolean valid = true;
        if (role.equals(AssociationType.CODE_DESIGNEE.getCode()) ||
        		role.equals(AssociationType.CODE_EMERGENCY_CONTACT.getCode()) ||
				role.equals(AssociationType.CODE_OTHER_EMERGENCY_CONTACT.getCode()) || 
				role.equals(AssociationType.CODE_PRIMARY_NEXT_OF_KIN.getCode()) || 
				role.equals(AssociationType.CODE_OTHER_NEXT_OF_KIN.getCode())) {

        		boolean addressComplete = isAddressComplete(form, request);
        		if (!addressComplete && form.getPhone().length() == 0) {
        			valid = false;
        			errors.add("phone", new ActionMessage(MessageKeys.ERRORS_DETAIL, "Address or phone number is required"));
        			errors.add("addressLine1", new ActionMessage(MessageKeys.ERRORS_DETAIL, "Full Address or phone number is required"));
        		}
		}

		return valid;
	}
	
	private boolean isAddressComplete(
			PersonAssociationInfoForm form, 
	        HttpServletRequest request) {
		boolean isComplete = true;
		if (form.getAddressLine1().length()== 0 ||
				form.getCity().length() == 0 ||
				form.getState().length() == 0 ||
				form.getZipCode().length() == 0) {

			isComplete = false;
		}
		
		return isComplete;
	}

	
	private boolean validateNames(ActionMessages errors, PersonAssociationInfoForm form) {
		boolean valid = true;
		String errText = "{0} required for this role";
		if (form.getFirstName().length() == 0) {
			valid = false;
			errors.add("firstName", new ActionMessage(MessageKeys.ERRORS_REQUIRED, "First Name"));
		}

		if (form.getLastName().length() == 0) {
			valid = false;
			errors.add("lastName", new ActionMessage(MessageKeys.ERRORS_DETAIL, "Last Name is required"));
		}		
		return valid;
	}
	
    private void validateVAGuardian(HttpServletRequest request) {
        
    }
    
	protected ActionForward handleOptimisticLockException(
			ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		form.reset(mapping,request);
		return display(mapping,form,request,response);
	}
	
	protected Map getKeyMethodMap() 
	{
		if(keyMethodMap == null)
		{
			keyMethodMap = new HashMap();
			keyMethodMap.put("button.addAssociate","display");
			keyMethodMap.put("button.add","addAssociate");
			keyMethodMap.put("button.clear","clear");
			keyMethodMap.put("button.cancel", "cancel");
		}
        return keyMethodMap;
    }
}
