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

// Java Classes
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.mlw.vlh.ValueListInfo;

// Framework Classes
import gov.va.med.fw.service.pagination.SearchQueryInfo;
import gov.va.med.fw.ui.UIConstants;
import gov.va.med.fw.ui.valuelist.SearchValueListAdapter;
import gov.va.med.fw.ui.valuelist.ValueListException;
import gov.va.med.fw.util.StringUtils;

// ESR Classes
import gov.va.med.esr.common.model.lookup.NameType;
import gov.va.med.esr.common.model.lookup.SSNType;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.person.Name;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.SSN;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.esr.service.PersonSearchQueryInfo;
import gov.va.med.esr.ui.ApplicationConstants;
import gov.va.med.esr.ui.admin.beans.VeteranSearchBean;
import gov.va.med.esr.ui.util.ConvertUtils;
import gov.va.med.esr.ui.util.SessionManager;

/**
 * This value list adapter provides an extension to the default SearchValueListAdapter by implementing a post query data
 * conversion.  The list of person objects are converted to VeteranSearchBean objects.  In addition, all names are
 * filtered out besides legal names.
 *
 * @author Andrew Pach
 * @version 3.0
 */
public class PersonSearchValueListAdapter extends SearchValueListAdapter
{
    private static final long serialVersionUID = -7571419029256398228L;

    /**
     * Converts a list of Person objects into a list of VeteranSearchBean objects.  Also, only the legal name is used
     * for the person's name.
     *
     * @param results The initial query results
     * @param searchQueryInfo The search query information
     *
     * @return The modified search results
     * @throws gov.va.med.fw.ui.valuelist.ValueListException if there are any errors processing the data.
     * @see SearchValueListAdapter#performPostQueryProcessing(java.util.List, gov.va.med.fw.service.pagination.SearchQueryInfo)
     */
    protected List performPostQueryProcessing(List results, SearchQueryInfo searchQueryInfo, ValueListInfo info) throws ValueListException
    {
        // Convert the returned list of Person objects into VeteranSearchBeans
        Vector vetList = new Vector();
        int size = (results != null) ? results.size() : 0;

        // CCR 10471 ADD A PERSON
        boolean isAddPerson = false;
        PersonSearchQueryInfo personSearchQueryInfo = null;
        if (searchQueryInfo != null && searchQueryInfo instanceof PersonSearchQueryInfo) {
        	personSearchQueryInfo = (PersonSearchQueryInfo) searchQueryInfo;
        }
        isAddPerson = (personSearchQueryInfo !=null && personSearchQueryInfo.isAddAPerson() == true ) ? true : false;

        // CCR11593 -- if a single row is returned in search, cache it into HTTP session for later use
        // to avoid redundant Idm 1305 search calls.  Otherwise, clear any previously saved traits from teh session.
        if (size == 1) {
        	saveTraitsToSession((Person)results.get(0), info);
        } else {
        	clearTraitsFromSession(info);
        }

        for (int i = 0; i < size; i++)
        {
            // Get a person
            Person p = ((Person)results.get(i));
            //System.out.println("PersonSearchValueListAdapter::performPostQueryProcessing()-before convert person to VeteranSearchBean= " + p);

            // Create the search bean
            VeteranSearchBean bean = new VeteranSearchBean();

            // Search for a legal name to display
            Name legalName = null;
            Set names = p.getNames();
            if (names != null && names.size() > 0)
            {
                for (Iterator iter = names.iterator(); iter.hasNext();)
                {
                    Name name = (Name)iter.next();
                    NameType type = name.getType();
                    String code = (type != null) ? type.getCode() : null;

                    if (NameType.LEGAL_NAME.getName().equalsIgnoreCase(code))
                    {
                        legalName = name;
                        break;
                    }
                }
            }

            // Find the first, middle, and last names
            String firstName = "";
            String middleName = "";
            String lastName = "";
            if (legalName != null)
            {
                firstName = (StringUtils.isBlank(legalName.getGivenName()) ? "" : legalName.getGivenName());
                middleName = (StringUtils.isBlank(legalName.getMiddleName()) ? "" : legalName.getMiddleName());
                if (StringUtils.isNotBlank(legalName.getFamilyName()))
                {
                    lastName = legalName.getFamilyName();
                    if (StringUtils.isNotBlank(legalName.getSuffix()))
                    {
                        lastName += " " + legalName.getSuffix();
                    }
                }
            }
            bean.setFirstName(firstName);
            bean.setMiddleName(middleName);
            bean.setLastName(lastName);

            // Get the Person ID
            // CCR 10471 For ADD A PERSON, person id is not available
            if (personSearchQueryInfo != null && !personSearchQueryInfo.isAddAPerson())
            	bean.setPersonID(p.getEntityKey().getKeyValueAsString());

            Set ssns = p.getSsns();
            String ssnText = "";
            if (ssns != null)
            {
                for (Iterator iter = ssns.iterator(); iter.hasNext();)
                {
                    SSN ssnObj = (SSN) iter.next();
                    // CCR 10471 ADD A PERSON, set the SSN text directly because IdM does not return type
                    if ( ((PersonSearchQueryInfo) searchQueryInfo).isAddAPerson()) {
                    	ssnText = ssnObj.getSsnText();
                    	break;
                    }
                    else if (SSNType.CODE_ACTIVE.getName().equals(ssnObj.getType().getCode()))
                    {
                        ssnText = ssnObj.getSsnText();
                    }
                }
            }
            if (StringUtils.isBlank(ssnText))
            {
                ssnText = UNKNOWN;
            }
            bean.setSsn(ssnText);

            bean.setDateOfBirth(p.getBirthRecord() != null ? p.getBirthRecord().getBirthDate() : null);
            bean.setSensitiveRecord(p.getSensitiveRecord());
            bean.setPersonLockedReason(p.getPersonLockedReason());

            if (p.getBirthRecord().getMultipleBirth() == null){
            	bean.setMultipleBirth("");
            } else if (p.getBirthRecord().getMultipleBirth().equals(Boolean.TRUE)){
            	bean.setMultipleBirth("Y");
            } else {
            	bean.setMultipleBirth("N");
            }

            bean.setAddAPerson(isAddPerson);
            bean.setIdmMatchType(p.getIdmMatchType());
            bean.setGender(p.getGender());
            //bean.setSigi(p.getSelfIdentifiedGenderIdentity());

            bean.setVpid(p.getVPIDEntityKey().getKeyValueAsString());

            // Add the
            vetList.add(bean);
        }

        // Return the VeteranSearchBean list
        return vetList;
    }

    private void clearTraitsFromSession(ValueListInfo info) {
        // Get the filter map
        Map filterMap = info.getFilters();

        // Get a handle to the request and session
        HttpServletRequest request = (HttpServletRequest)filterMap.get(HTTP_REQUEST_KEY);
        removeSelectedTraits(request);
	}

	private void saveTraitsToSession(Person p, ValueListInfo info) {
    	PersonIdentityTraits traits = p.getIdentityTraits();

        // Get the filter map
        Map filterMap = info.getFilters();

        // Get a handle to the request and session
        HttpServletRequest request = (HttpServletRequest)filterMap.get(HTTP_REQUEST_KEY);

        setSelectedTraits(request, traits);
    }

    protected void setSelectedTraits(HttpServletRequest request, PersonIdentityTraits traits)
    {
        putSandboxEntry(request, ApplicationConstants.SessionData.SELECTED_TRAITS, traits);
    }

    protected void removeSelectedTraits(HttpServletRequest request)
    {
        removeSandboxEntry(request, ApplicationConstants.SessionData.SELECTED_TRAITS);
    }

	protected Map getApplicationData(final HttpServletRequest request) {

		// Get the appData out of the session
		HttpSession session = request.getSession();
		Map appData = (Map) session.getAttribute(UIConstants.APP_DATA);
		if (appData == null) {
			appData = new HashMap();
			session.setAttribute(UIConstants.APP_DATA, appData);
		}
		return appData;
	}
	protected Map getSandbox(HttpServletRequest request) {
		return getApplicationData(request);
	}

	protected void putSandboxEntry(HttpServletRequest request, Object key,
			Object value) {
		if (key != null && value != null)
			getSandbox(request).put(key, value);
	}

	protected Object removeSandboxEntry(HttpServletRequest request, Object key) {
		return (key != null) ? getSandbox(request).remove(key) : null;
	}

}