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

// Java Classes
import java.util.Map;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Libraries Classes
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;

// Framework Classes

// ESR Classes
import gov.va.med.esr.ui.common.action.AddressForm;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.lookup.Country;

/**
 * This is a struts action class used for Handle Undeliverable Mail Edit Permanent Address pages.
 *
 * @author Andrew Pach
 * @version 3.0
 */
public class UndeliverableMailEditPermAddressAction extends UndeliverableMailAction
{
    /**
     * The session key for the person whose permanent address is being edited.
     */
    public static final String UNDELIVERABLE_MAIL_PERM_ADDR_PERSON_SESSION_KEY =
        "undeliverableMailPermAddrPerson";

    /**
     * Default constructor.
     */
    public UndeliverableMailEditPermAddressAction()
    {
        super();
    }

    /**
     * Displays the main 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
    {
        // Ensure we have a valid form
        UndeliverableMailEditPermAddressForm addressForm =
            getUndeliverableMailEditPermAddressForm(form);

        // Retrieve the person based on the selected Person Id
        Person person = retrievePerson(addressForm.getSelectedPersonId(), request);

        // Convert all the address data to the form
        conversionService.convert(person, addressForm);

        // Add a message informing the user when a country is null
        validateCountryNull(person.getPermanentAddress(), request);

        // Return to the results display
        return mapping.findForward(FORWARD_DISPLAY);
    }

    /**
     * Cancels this page and returns to the search 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 cancel(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // Remove the person from the session
        removePersonFromSession(request);

        // Return to the results display
        return mapping.findForward(FORWARD_RETURN_TO_PREV_SCREEN);
    }

    /**
     * Updates the status of the selected entries as "returned from post office".
     *
     * @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
    {
        // Ensure we have a valid form
        UndeliverableMailEditPermAddressForm addressForm =
            getUndeliverableMailEditPermAddressForm(form);

        // Create some action forwards
        ActionForward successForward =
            new ActionForward(mapping.findForward(FORWARD_RETURN_TO_PREV_SCREEN_SUCCESSFUL_UPDATE));
        ActionForward errorForward = mapping.findForward(FORWARD_DISPLAY);

        // Perform US extra validation
        if (Country.isUSAddress(addressForm.getCountry()))
        {
            // Validate the state
            if (!stateValid(addressForm, AddressForm.class, STATE_FIELD, successForward, request))
            {
                return errorForward;
            }
            
            // Validate the zip code matches the city/state
            if (!zipCodeMatchesCityAndState(
                addressForm, AddressForm.class, CITY_FIELD, STATE_FIELD, ZIPCODE_FIELD, request))
            {
                return errorForward;
            }
        }

        // Get the Person from session
        Person person = getPersonFromSession(request);

        // Clone the person for the update
        Person updatedPerson = (Person)person.clone();

        // Convert the address form data onto the Person's permanent address
        conversionService.convert(addressForm, updatedPerson);

        // Call the demographic service to update the permanent address
        updatedPerson = getDemographicService().updateContactInformation(updatedPerson);

        // Remove the person from session since we are done with the update
        removePersonFromSession(request);

        // Return to the previous screen
        return successForward;
    }

    /**
     * Retrieve the person from the database and store in the session.
     *
     * @param personIdString The person Id (as a string) to retrieve
     * @param request A http request from an search.jsp page
     */
    protected Person retrievePerson(String personIdString, HttpServletRequest request)
        throws Exception
    {
        // Retrieve the person from the database
        PersonEntityKey entityKey = CommonEntityKeyFactory.createPersonIdEntityKey(personIdString);
        Person person = getPersonService().getPerson(entityKey);

        // Set the newly retrieved person in session
        request.getSession().setAttribute(UNDELIVERABLE_MAIL_PERM_ADDR_PERSON_SESSION_KEY, person);

        // Return the retrieved person
        return person;
    }

    /**
     * Gets the Person from session.
     *
     * @param request The HttpServletRequest
     */
    protected Person getPersonFromSession(HttpServletRequest request)
    {
        return (Person)request.getSession()
            .getAttribute(UNDELIVERABLE_MAIL_PERM_ADDR_PERSON_SESSION_KEY);
    }

    /**
     * Removes the person retrieved via the retrievePerson method from session.
     *
     * @param request The HttpServletRequest
     */
    protected void removePersonFromSession(HttpServletRequest request)
    {
        request.getSession().setAttribute(UNDELIVERABLE_MAIL_PERM_ADDR_PERSON_SESSION_KEY, null);
    }

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