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

// Java Classes
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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

// ESR Classes
import gov.va.med.esr.common.model.comms.Document;
import gov.va.med.esr.common.model.comms.DocumentReceipt;
import gov.va.med.esr.common.model.ee.Eligibility;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.financials.IncomeTestStatus;
import gov.va.med.esr.common.model.financials.PatientVisitSummary;
import gov.va.med.esr.common.model.lookup.DocumentType;
import gov.va.med.esr.common.model.lookup.IncomeTestType;
import gov.va.med.esr.common.model.lookup.PhoneType;
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.SignatureImage;
import gov.va.med.esr.common.util.MailingAddressHelper;
import gov.va.med.esr.service.PersonHelperService;
import gov.va.med.esr.service.external.HandBookInfo;
import gov.va.med.esr.ui.common.util.JspUtils;
import gov.va.med.esr.ui.conversion.UIConversionServiceImpl;
import gov.va.med.esr.common.model.ee.HealthBenefitProfile;

/**
 * @author DNS   KATIKM
 * Conversion service for PersonOverviewForm and Person Object
 */
public class PersonOverviewConversionService extends UIConversionServiceImpl {
	
	public static final String EMPTY_STRING = "";
	
	public PersonOverviewConversionService() {
		super();
	}
	
	protected void convertBean(Object source, Object target)
			throws ConversionServiceException {
		
		//convert the objects
		if (source instanceof Person && target instanceof PersonOverviewForm) {
			Person person = (Person) source;
			PersonOverviewForm formBean = (PersonOverviewForm) target;
			PersonHelperService helper = getPersonHelperService ();
			
			try {				
		        //populate data from the Person object       
		        //eligibility
				
				formBean.setEligibilityStatus(helper.getEligibilityStatus(person));
				ServiceConnectionAward svcConnAwd = person.getServiceConnectionAward();				
				formBean.setServiceConnectedPercentage(
						(svcConnAwd == null) ? null: svcConnAwd.getServiceConnectedPercentage());
				EnrollmentDetermination enrollDet = person.getEnrollmentDetermination();
				
				if (enrollDet != null) {
					Eligibility eligibility = enrollDet.getPrimaryEligibility();
					formBean.setPrimaryEligibilityCode(
							(eligibility==null) ? null : eligibility.getType().getDescription());
					
					Set eligibilities = enrollDet.getSecondaryEligibilities();
			        List secondaryEligibilityCodes = new ArrayList ();
			        if (eligibilities != null && eligibilities.size() > 0) {            
						//Display Other Eligibility Codes in order of precedence, 1249[UC5.3.2]

			        	Object a[] = enrollDet.getSecondaryEligibilities().toArray();
						Arrays.sort(a);

			            for (int i=0; i < a.length; i++) {
			                eligibility = (Eligibility)a[i];
			                secondaryEligibilityCodes.add(eligibility.getType().getDescription());
			            }
			        }
			        formBean.setSecondaryEligibilityCodes(secondaryEligibilityCodes);
			        
			        formBean.setEffectiveDateOfChange(enrollDet.getEffectiveDate());
				}
				
				//Health Benefit Plans
				//formBean.setCurrentNumberOfHealthBenefitPlans(currentNumberOfHealthBenefitPlans);
				HealthBenefitProfile hbp = person.getHealthBenefitProfile();
				if (hbp!=null) {
				      Set plans = hbp.getHealthBenefitPlans();
				      formBean.setCurrentNumberOfHealthBenefitPlans(plans.size());
				      //plans.addHealthBenefitPlan(newPlan);
				      //plans.removeHealthBenefitPlan(oldPlan);
				} 
				else 
				{
					formBean.setCurrentNumberOfHealthBenefitPlans(0);
				}

                // Select the current Mailing address
                Address currentAddress = MailingAddressHelper.selectAddressForMailing(person.getAddresses());
                formBean.setCurrentMailingAddress(JspUtils.displayAddress(currentAddress));
                formBean.setBadAddressReason(((currentAddress == null) ||
                    (currentAddress.getBadAddressReason() == null)) ? null : currentAddress.getBadAddressReason().getCode());
				copyEmergencyReponse(person,formBean);

                //Get Home Phone Number
		        Set phones = person.getPhones();
		        if (phones != null) {
			        	for(Iterator iter = phones.iterator(); iter.hasNext();) {
			        		Phone phone = (Phone)iter.next();
			        		if (phone.getType().getCode().equals(PhoneType.CODE_HOME.getName())) {
			        			String phonenumber = phone.getPhoneNumber();
			        			if (phonenumber != null && phonenumber.length()>0)
			        				formBean.setPhoneNumber(phonenumber);
			        			else
			        				formBean.setPhoneNumber(null);
			        	}
			        }
		        }
	            
		        //financials
		        //TODO, add Integer to fix compiling error
		        IncomeTest incomeTest = getPersonHelperService().getCurrentIncomeTest(person);
		        if (incomeTest != null) {
                    //current income test type
                    formBean.setCurrentTestType(incomeTest.getType().getDescription());
                    
                    //primary income test type
		            if (incomeTest.getPrimaryTestType() != null)
		                formBean.setPrimaryTestType(incomeTest.getPrimaryTestType().getDescription());
		            
                    //mt and rx copy statuses
		            Set statuses = incomeTest.getStatuses();
		            if (statuses != null) {
		                for (Iterator iter=statuses.iterator(); iter.hasNext(); ) {
		                    Object statusObj = iter.next ();
		                    if (statusObj != null && statusObj instanceof IncomeTestStatus) {
		                        IncomeTestStatus incomeTestStatus = (IncomeTestStatus) statusObj;
		                        
		                        String statusDesc = null;
		                        if (incomeTestStatus.getStatus() != null){
		                        	statusDesc = incomeTestStatus.getStatus().getDescription();
		                        }
		                        if(incomeTestStatus.getType() != null) {
		                            if (incomeTestStatus.getType().getCode().equals(
		                            		IncomeTestType.CODE_MEANS_TEST.getName())) {
		                                formBean.setMeansTestStatus(statusDesc);
		                            }
		                            else if (incomeTestStatus.getType().getCode().equals(
		                            		IncomeTestType.CODE_CO_PAY_EXEMPTION_TEST.getName())) {
		                            	formBean.setPharmacyCoPayStatus(statusDesc);
		                            }
                                    else if (incomeTestStatus.getType().getCode().equals(
                                            IncomeTestType.CODE_LTC_CO_PAY_TEST.getName())) {
                                        formBean.setLtcCoPayStatus(statusDesc);
                                    }
                                    else if (incomeTestStatus.getType().getCode().equals(
                                            IncomeTestType.CODE_LTC_CO_PAY_EXEMPTION_TEST.getName())) {
                                        formBean.setLtcCoPayExemptionStatus(statusDesc);
                                    }
		                        }
		                    }                        
		                }
		            }
		        }
		        
		        //Signature
		        if (person.getSignatureImages() != null && person.getSignatureImages().size() > 0)
		        {
		        	//sort first
		        	List signatures = new ArrayList(person.getSignatureImages());
		        	Collections.sort(signatures);
		        	
		        	SignatureImage image = (SignatureImage)signatures.get(0);
		        	if (image != null)
		        	{
			        	formBean.setSignatureOnFile(image.getSignatureIndicator());
			        	formBean.setImageId(image.getImageIdNumber());
			        	formBean.setDateIndexed(image.getDateIndex());	
		        	}
		        }
		        else
		        {
		        	formBean.setSignatureOnFile(null);
		        	formBean.setImageId(null);
		        	formBean.setDateIndexed(null);			        	
		        }
		        
		        		       		        
		        //Enrollment
		        formBean.setApplicationDate(
		        		(person.getApplication()==null) ? null: person.getApplication().getApplicationDate());
		        
		        //current status
                DeathRecord deathRecord = person.getDeathRecord();
                if ((deathRecord != null && deathRecord.getDeathDate() != null))
                {

                    formBean.setCurrentStatus("Deceased");	
                }
                else
                {
                  formBean.setCurrentStatus("Alive");
                }
		    		        
		        //Handbook		        
		        List handBookls = getHandBookService().getLatestHandbookInformation(person.getIdentityTraits().getVpid().getVPID());
		        
		        if(handBookls != null && !handBookls.isEmpty()){
		        	
		        	//CCR 11783, from RSD
		        	//The ES Overview Screen will be enhanced to accommodate viewing of the current Handbook, 
		        	//the current Benefits At A Glance, and the last two unique versions of the Handbook and Benefits at a Glance.  
		        	//Also displayed will be the source of the Handbook or Benefits at a Glance (Online, Mailed), and the creation date.
		        	buildHandebookOverview(formBean, handBookls);
		        	
		        	if ((formBean.getBenefitGlanceHistory() != null && formBean.getBenefitGlanceHistory().size() > 0) ||
		        			(formBean.getHandbookHistory() != null && formBean.getHandbookHistory().size() > 0))
			        	formBean.setHandbookInfo(true);		
 
		        }
		        
		        //VHIC Card - get VHIC card number from MVI
		        String vpid = person.getIdentityTraits().getVpid().getVPID();
		        //String vhicId = getPersonHelperService().getVhicIdByVPID(vpid);
		        getVhicCardInfoService().resetVhicCardInfo(vpid);
		        
		        
		        //Before a user click "Query VHIC" on VHIC Status page in Communication tab, vhic card number and status are default values.
		        formBean.setVhicCardNum(getVhicCardInfoService().getVhicCardInfo().getCurrentVHICCardNumber());
		        				        		
		        formBean.setVhicCardStatus(getVhicCardInfoService().getVhicCardInfo().getCurrentVHICCardStatus());
		        
			}
			catch (Exception ex) {
	            throw new ConversionServiceException("Conversion Failed", ex);
	        }
		}
		else
		{
            throw new ConversionServiceException("Type mismatch: Expecting Person, PersonOverviewForm Received " +
            source.getClass().getName() + " and " + target.getClass().getName() );
		}
	}	
	
	//CCR11783
	private void buildHandebookOverview(PersonOverviewForm formBean, List handBookls) throws Exception {
		
		DocumentReceipt docReceipt = null;
		Set docs = null;
		Document doc = null;
		List hbDocList = new ArrayList();
		List bpDocList = new ArrayList();
		
		for (int i=0; i< handBookls.size(); i++)
		{
			docReceipt = (DocumentReceipt) handBookls.get(i);
			docs = docReceipt.getDocuments();
			
			for (Iterator iter = docs.iterator(); iter.hasNext();) {
				doc = (Document) iter.next();
				if (DocumentType.isHandBook(doc.getDocumentType())) {
					//add to handbook history list
					hbDocList.add(doc);
					
				} else if (DocumentType.isBenefitsProfile(doc.getDocumentType()))
				{
					//add to benefits profile history list
					bpDocList.add(doc);
				}
			}
		}
		
		//get the latest 3 history (current + 2 history)
		hbDocList = getLastestThreeDocHistory(hbDocList);
		bpDocList = getLastestThreeDocHistory(bpDocList);
		
		formBean.setHandbookHistory(buildDocumentList(hbDocList));
		formBean.setBenefitGlanceHistory(buildDocumentList(bpDocList));
	}
	
	private List buildDocumentList(List docList) throws Exception
	{
		if (docList == null)
			return null;
		
		List ls = new ArrayList();
		Document doc = null;
		DocumentReceipt dr = null;
		
		for (int i=0; i< docList.size(); i++)
		{
			ls.add(buildDocument(((Document)docList.get(i)).getDocumentReceipt(), (Document)docList.get(i)));
		}
		
		return ls;
	}
	
	//CCR11783
	private HandBookInfo buildDocument(DocumentReceipt docReceipt, Document doc)  throws Exception{

		HandBookInfo hbi = new HandBookInfo();
		hbi.setDocType(doc.getDocumentType().getName());
		hbi.setGeneratedDate(doc.getCreationDate());
		hbi.setName(doc.getFileInfo().getName());

		hbi.setPhysicalLocation(
		getHandBookService().getVBRFileLocation(doc.getFileInfo().getDirectory()));
		
		hbi.setReleaseControlNumber(docReceipt.getReleaseControlNumber());
		hbi.setVersion(docReceipt.getVersionNumber());
		
		hbi.setFileId(doc.getFileInfo().getEntityKey().getKeyValueAsString());

		return hbi;
	}
	
    public List getLastestThreeDocHistory(Collection docs) {
        List sortedList = new ArrayList();
        if (docs != null && !docs.isEmpty()) {
        	sortedList.addAll(docs);
            Comparator comparator = new Comparator() {
                public int compare(Object pObject1, Object pObject2) {
                    Date date1 = (pObject1 instanceof Document) ? ((Document) pObject1).getCreationDate(): null;
                    Date date2 = (pObject2 instanceof Document) ? ((Document) pObject2).getCreationDate(): null;
                    return (date1 != null && date2 != null) ? (-date1
                            .compareTo(date2)) : 0;
                }
            };
            Collections.sort(sortedList, comparator);
        }
        if (sortedList.size() <4)
        	return sortedList;
        
        return sortedList.subList(0, 3);
    }
    
    private void copyEmergencyReponse(Person person, PersonOverviewForm 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));
        }
	}
}
