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

import java.text.SimpleDateFormat;
// Java Classes
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Collections;


// Library Classes
import org.apache.commons.lang.Validate;


// Framework Classes
import gov.va.med.fw.conversion.ConversionServiceException;

// ESR Classes
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.lookup.AddressType;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.party.Phone;
import gov.va.med.esr.common.model.person.DeathRecord;
import gov.va.med.esr.common.model.person.EmergencyResponseIndicator;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PreferredLanguage;
import gov.va.med.esr.common.util.MailingAddressHelper;
import gov.va.med.esr.ui.common.util.JspUtils;
import gov.va.med.esr.ui.conversion.UIConversionServiceImpl;

/**
 * @author DNS   KATIKM
 */
public class DemographicOverviewConversionService extends UIConversionServiceImpl
{
    // Constants
    private static final String CONST_LIVE = "Alive";
    private static final String CONST_DECEASED = "Deceased";

    /**
     * Converts between a Person object and the DemographicOverviewForm. It only converts Person to Form and not vice
     * versa.
     *
     * @param source the source object
     * @param target the target object
     *
     * @throws gov.va.med.fw.conversion.ConversionServiceException if any errors were encountered during the
     * conversion.
     */
    protected void convertBean(Object source, Object target) throws ConversionServiceException
    {
        Validate.notNull(source, "DemographicOverviewConversionService source is null");
        Validate.notNull(source, "DemographicOverviewConversionService target is null");

        if ((source instanceof Person) && (target instanceof DemographicOverviewForm))
        {
            convertPersontoForm((Person)source, (DemographicOverviewForm)target);
        }
        else
            if ((target instanceof Person) && (source instanceof DemographicOverviewForm))
            {
                // Nothing to do since there is no update on the overview page
            }
            else
            {
                throw new ConversionServiceException("Type mismatch: Can't convert from " +
                    source.getClass().getName() + " to " + target.getClass().getName());
            }
    }

    /**
     * Convert from the person to the form.
     *
     * @param person the person
     * @param form the form
     *
     * @throws ConversionServiceException if any problems were encountered during the conversion.
     */
    private void convertPersontoForm(Person person, DemographicOverviewForm form) throws ConversionServiceException
    {
        try
        {
            // Populate data from the Person object
            copyMailingAddress(person, form);
            copyHomePhoneNumber(person, form);
            copyDODStatus(person, form);
            copyPreferredLanguage(person,form);
            copyEmploymentStatus(person, form);
            copyInsuranceInfo(person, form);
            copyAssociations(person, form);
            copyEmergencyReponse(person, form);
        }
        catch (Exception ex)
        {
        	throw new ConversionServiceException("Conversion Failed", ex);
        }
    }

    /**
     * Copy Date of Death Info
     *
     * @param person the person
     * @param formBean the form
     */
    private void copyDODStatus(Person person, DemographicOverviewForm formBean)
    {
        DeathRecord deathRecord = person.getDeathRecord();
        if ((deathRecord != null && deathRecord.getDeathDate() != null))
        {
        	formBean.setCurrentStatus(CONST_DECEASED);
        	/*
        	if (deathRecord.getDodVerifiedInd() == null || deathRecord.getDodVerifiedInd())
            {
        	  formBean.setCurrentStatus(CONST_DECEASED_VERIFIED);	
            }
            */
        }
        else
        {
        	formBean.setCurrentStatus(CONST_LIVE);	
        }        
    }

    
    /**
     * Copy PreferredLanguage
     *
     * @param person the person
     * @param formBean the form
     */
    private void copyPreferredLanguage(Person person, DemographicOverviewForm formBean)
    {
        PreferredLanguage language = person.getPreferredLanguage();
        formBean.setPreferredLanguage((language == null || language.getLanguage() == null || 
                language.getLanguage().getDescription() == null ) ? "" : language.getLanguage().getDescription() );
    }

    /**
     * Copy Employment status
     *
     * @param person the person
     * @param formBean the form
     */
    private void copyEmploymentStatus(Person person, DemographicOverviewForm formBean)
    {
        if (person.getEmployment() != null) {
           formBean.setEmploymentStatus(person.getEmployment().getEmploymentStatus() == null ?
           "" : person.getEmployment().getEmploymentStatus().getDescription());
        }
    }

    /**
     * Copy Mailing Address
     *
     * @param person the person
     * @param formBean the form
     */
    private void copyMailingAddress(Person person, DemographicOverviewForm formBean)
    {
        // Select the current Mailing address
        Address currentAddress = MailingAddressHelper.selectAddressForMailing(person.getAddresses());
        if (currentAddress != null)
        formBean.setCurrentMailingAddress(JspUtils.displayAddress(currentAddress));
        
        Address temporaryAddress = person.getTemporaryCorrespondenceAddress();
        if (temporaryAddress != null)
        formBean.setTemporaryAddress(JspUtils.displayAddress(temporaryAddress));
        
        if (currentAddress != null)
        formBean.setActiveAddress(currentAddress.getType().getCode());
      
        Address permanentAddress = person.getPermanentAddress();
        if (permanentAddress != null)
        formBean.setPermanentAddress(JspUtils.displayAddress(permanentAddress));
      
        Address confidentialAddress = person.getConfidentialAddress();

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        if (confidentialAddress != null)
        {
            formBean.setConfidentialAddress(JspUtils.displayAddress(confidentialAddress));
        	if (confidentialAddress.getStartDate() != null)
        	formBean.setConfStartDate(sdf.format(confidentialAddress.getStartDate().getDate()));
        	if (confidentialAddress.getEndDate() != null)
        	formBean.setConfEndDate(sdf.format(confidentialAddress.getEndDate().getDate()));
        }
        
        if (temporaryAddress != null)
        {
        	if (temporaryAddress.getStartDate() != null)
        	formBean.setTempStartDate(sdf.format(temporaryAddress.getStartDate().getDate()));
        	if (temporaryAddress.getEndDate() != null)
        	formBean.setTempEndDate(sdf.format(temporaryAddress.getEndDate().getDate()));
        }
      
        Address residentialAddress = person.getResidentialAddress();
        if (residentialAddress != null)
        formBean.setResidentialAddress(JspUtils.displayAddress(residentialAddress));
      
        formBean.setBadAddressReasonPerm(((permanentAddress == null) ||
            (permanentAddress.getBadAddressReason() == null)) ? null : permanentAddress.getBadAddressReason().getCode());
        formBean.setBadAddressReasonTemp(((temporaryAddress == null) ||
                (temporaryAddress.getBadAddressReason() == null)) ? null : temporaryAddress.getBadAddressReason().getCode());
        formBean.setBadAddressReasonConf(((confidentialAddress == null) ||
                (confidentialAddress.getBadAddressReason() == null)) ? null : confidentialAddress.getBadAddressReason().getCode());
    }

    /**
     * Copy home phone number.
     *
     * @param person the person
     * @param formBean the form
     */
    private void copyHomePhoneNumber(Person person, DemographicOverviewForm formBean)
    {
        //Get Home Phone Number
        Phone phone = person.getHomePhone();
        if (phone != null)
        {
            String phonenumber = phone.getPhoneNumber();
            if (phonenumber != null && phonenumber.length() > 0)
            {
                formBean.setPhoneNumber(phonenumber);
            }
            else
            {
                formBean.setPhoneNumber(null);
            }
        }
    }

    /**
     * Copy insurace company names
     *
     * @param person the person
     * @param form the form
     */
    private void copyInsuranceInfo(Person person, DemographicOverviewForm form)
    {
        // Sort the insurances to a predictable order.  Medicare records Part A and Part B will be next to each other.
        List insurances = new ArrayList(person.getInsurances());
        Collections.sort(insurances);

        // Variable to hold onto the HEC Medicare record to add to the form and whether we added it already or not.
        Medicare medicareRecordToAdd = null;
        boolean medicareAdded = false;

        // Iterate through each insurance record
        Iterator iter = insurances.iterator();
        while (iter.hasNext())
        {
            InsurancePolicy insPolicy = (InsurancePolicy)iter.next();

            if (insPolicy.isSiteRecord())
            {
                form.addSiteInsurance(insPolicy);
            }
            else
            {
                if (insPolicy instanceof Medicare)
                {
                    Medicare medicareRecord = (Medicare)insPolicy;

                    // If we don't have a Medicare record to add to the form or if the newest one contains
                    // a Part B, use it so we see the Part A & B on the overview screen.
                    if ((medicareRecordToAdd == null) || (Boolean.TRUE.equals(medicareRecord.isEnrolledInPartB())))
                    {
                        // Use the first medicare record we come across (the default one)
                        // as the one to insert onto the form.
                        medicareRecordToAdd = medicareRecord;
                    }
                }
                else
                {
                    // Add any previously "held on to" medicare record when we have moved passed them and
                    // onto a Private Insurance record.
                    if ((medicareRecordToAdd != null) && (!medicareAdded))
                    {
                        form.addHecInsurance(medicareRecordToAdd);
                        medicareAdded = true;
                    }

                    // Private Insurance
                    form.addHecInsurance(insPolicy);
                }
            }
        }

        // Add any previously "held on to" medicare record when we have moved passed them and
        // onto a Private Insurance record.
        if ((medicareRecordToAdd != null) && (!medicareAdded))
        {
            form.addHecInsurance(medicareRecordToAdd);
            medicareAdded = true;
        }
    }

    /**
     * Copy associations.
     *
     * @param person the person
     * @param form the form
     */
    private void copyAssociations(Person person, DemographicOverviewForm form)
    {
        List associations = new ArrayList(person.getAssociations());
        Collections.sort(associations);
        form.setAssociations(associations);
    }

    private void copyEmergencyReponse(Person person, DemographicOverviewForm form)
    {
        Set existingEResponseIndicator = person.getEmergencyResponseIndicators();
        Set existingEResponseIndicatorDesc = new HashSet();

        if (existingEResponseIndicator != null && !existingEResponseIndicator.isEmpty())
        {
            EmergencyResponseIndicator eResponseIndicator = null;
            for (Iterator iter = existingEResponseIndicator.iterator(); iter.hasNext();)
            {
                eResponseIndicator = (EmergencyResponseIndicator)iter.next();
                if (eResponseIndicator != null)
                {
                    existingEResponseIndicatorDesc.add(eResponseIndicator.getEmergencyResponse().getDescription());
                }
            }
            form.setEmergencyResponse(JspUtils.displayValues(existingEResponseIndicatorDesc, "", null));
        }
    }
}
