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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import gov.va.med.fw.conversion.ConversionServiceException;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.model.EntityKeyFactory;
import gov.va.med.fw.util.StringUtils;

import gov.va.med.esr.common.model.ee.PurpleHeart;
import gov.va.med.esr.common.model.ee.PurpleHeartDocument;
import gov.va.med.esr.common.model.lookup.DecorationStatus;
import gov.va.med.esr.common.model.lookup.PHDataSource;
import gov.va.med.esr.common.model.lookup.PHDocumentType;
import gov.va.med.esr.common.model.lookup.RejectionRemark;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.Person;

import gov.va.med.esr.ui.common.service.LookupCacheService;
import gov.va.med.esr.ui.common.util.DateUtils;
import gov.va.med.esr.ui.conversion.UIConversionServiceImpl;

public class PurpleHeartConversionService extends UIConversionServiceImpl {

    public PurpleHeartConversionService() {
        super();
    }

    protected void convertBean(Object source, Object target) throws ConversionServiceException {
        if (source instanceof Person && target instanceof PurpleHeartForm) {
            convertPersonToForm((Person)source,(PurpleHeartForm)target);
        }
        else if (target instanceof Person && source instanceof PurpleHeartForm) {
            convertFormToPerson((PurpleHeartForm)source,(Person)target);
        }
        else
        {
            throw new ConversionServiceException("Can not conver from " +
                    source.getClass().getName() + " to " + target.getClass().getName());
        }
    }

    private void convertPersonToForm(Person person, PurpleHeartForm form) throws ConversionServiceException {
        //convert common fields
        LookupCacheService lookupCacheService = getLookupCacheService();

        PurpleHeart ph = person.getPurpleHeart();
        if (ph != null) {
            //get and convert current document read only fields
            form.setPurpleHeartStatus(ph.getStatus() == null ? null : ph.getStatus().getCode());
            form.setStatusUpdateDate(DateUtils.format(ph.getStatusLastEditDate(),null));
            form.setFacility(ph.getFacility() == null ? null : ph.getFacility().getCode());
            form.setAssignedContactUser(ph.getAssignedContactUser());
            form.setRejectionRemark(ph.getRejectionRemark() == null ? null : ph.getRejectionRemark().getCode());
            form.setLastUpdateUserId(ph.getModifiedBy() == null ? null : ph.getModifiedBy().getName());
            form.setLastUpdateDate(ph.getModifiedOn() == null ? null :
            	DateUtils.formatWithTime(ph.getModifiedOn(),DateUtils.MMDDYYYYHHMMSS));
            List documents = new ArrayList(ph.getDocuments ());
            //new document is not available
            PurpleHeartDocument phDocument = null;
            
            if (documents.size() > 0) {
                //current document (oldest acceptable document
                Collections.sort(documents);
                PurpleHeartDocument document = null;
                //get the earliet acceptable document
                for (Iterator i= documents.iterator(); i.hasNext();) {
                    document = (PurpleHeartDocument)i.next();
                    if (Boolean.TRUE.equals(document.getAcceptable())) {
                    	phDocument = document;
                        break; //found the first acceptable document
                    }
                }

                //If we didn't find acceptable document get the latest document
                if (phDocument == null) {
                    phDocument = (PurpleHeartDocument)documents.get(documents.size()-1);
                }
                //convert cuurent document
                form.setCurrentDocId(phDocument.getEntityKey() == null ? null : phDocument.getEntityKey().getKeyValueAsString());
                form.setCurrentDocAcceptable(phDocument.getAcceptable() == null ? null : String.valueOf(phDocument.getAcceptable()));
                form.setCurrentDocUnacceptableRemarks(phDocument.getUnacceptableRemarks());
                form.setCurrentDocReceivedDate(DateUtils.format(phDocument.getReceivedDate(),null));
                form.setCurrentDocLoginDate(DateUtils.format(phDocument.getLoginDate(),null));
                PHDocumentType docType = phDocument.getDocumentType();
                PHDataSource dataSource = phDocument.getDataSource();
                form.setCurrentDocDocumentType(getLookupCode(docType));
                form.setCurrentDocDataSource(getLookupCode(dataSource));
            }
        }

        //populate the default values for the new document
        form.setNewDocLoginDate(DateUtils.format(DateUtils.getCurrentDate(),null));//default date
        form.setNewDocReceivedDate(DateUtils.format(DateUtils.getCurrentDate(),null));//default date
        //set new document to true to log the new document
        form.setNewDocument(Boolean.FALSE);        
    }

    private void convertFormToPerson(PurpleHeartForm form, Person person) 
    throws ConversionServiceException {
    	//Get current PH
    	PurpleHeart ph = person.getPurpleHeart();
        
        //get current looged in user name
        String loggedInUserName = getLoggedInUser().getName();

        //Create the new document if entered 
        PurpleHeartDocument newDocument = null;
        String newLAS = null;
        if (Boolean.TRUE.equals(form.getNewDocument())) {
            //create a new PH Document
            newDocument = new PurpleHeartDocument();
            //          convert current document attributes
            newDocument.setReceivedDate(DateUtils.getDate(form.getNewDocReceivedDate()));

            newDocument.setDocumentType((PHDocumentType) getLookup(
                    PHDocumentType.class, form.getNewDocDocumentType()));
            newDocument.setDataSource((PHDataSource) getLookup(
                    PHDataSource.class, form.getNewDocDataSource()));
            if (form.getNewDocAcceptable() == null || StringUtils.isEmpty(form.getNewDocAcceptable())) {            	
            	newDocument.setAcceptable(null);
            }
            else {
            	newDocument.setAcceptable(new Boolean(form.getNewDocAcceptable()));            	 
            }
            newDocument.setUnacceptableRemarks(StringUtils.isBlank(form.getNewDocUnacceptableRemarks()) ? null :
                form.getNewDocUnacceptableRemarks());
            newDocument.setLoginDate(DateUtils.getCurrentDateTime());
            
            //if the new assignement is set
            if (StringUtils.isNotEmpty(form.getNewAssignedContactUser())){
            	newLAS = form.getNewAssignedContactUser();
            }                
        }
        //if current PH is null and new document is not added ignore changes
        if (ph == null && newDocument == null) {
        	return;
        }
        
        //Create PH if it doesn't exist already
        if (ph == null) {
        	ph = new PurpleHeart();

            //update default fields for new PH creation
            ph.setAssignedContactUser(newLAS); //from new document added
            ph.setStatusLastUpdateUser(loggedInUserName);
            ph.setStatusLastEditDate(DateUtils.getCurrentDate());
            //set default facility to HEC
            ph.setFacility((VAFacility)getLookup(VAFacility.class,VAFacility.CODE_HEC.getCode()));
            person.addDecoration(ph);
        }
        //Existing PH and assigned LAS can be changed by the user while adding a new doc and 
        //editing explicitely
        else {
        	if (newLAS != null) {
        		ph.setAssignedContactUser(newLAS);
        	}
        	else if (StringUtils.isEmpty(form.getAssignedContactUser())) {
        		ph.setAssignedContactUser(null);
        	}else{
        		ph.setAssignedContactUser(form.getAssignedContactUser());
        	}
        }
        
        //convert editable PH fields
        ph.setRejectionRemark(
            (RejectionRemark)getLookup(RejectionRemark.class,form.getRejectionRemark()));
        
        //Add the new document if created
        if (newDocument != null) {
        	ph.addDocument(newDocument);
        }

        //Update the current document if exists
        PurpleHeartDocument phDocument = null;
        String currentDocId = form.getCurrentDocId();
        if (StringUtils.isNotEmpty(currentDocId)) {
            EntityKey entityKey = EntityKeyFactory.createEntityKey(
                    new BigDecimal(currentDocId), PurpleHeartDocument.class);
            //get the document from the PH
            phDocument = ph.getDocumentByEntityKey(entityKey);
            if (phDocument == null) {
                throw new ConversionServiceException("Current Document could not be found");
            }
            
            //update current document changes
            if (StringUtils.isNotEmpty(form.getCurrentDocReceivedDate())) {
            	phDocument.setReceivedDate(DateUtils.getDate(form.getCurrentDocReceivedDate()));
            }
            phDocument.setDocumentType((PHDocumentType)
                getLookup(PHDocumentType.class, form.getCurrentDocDocumentType()));
            phDocument.setDataSource((PHDataSource)
                getLookup(PHDataSource.class, form.getCurrentDocDataSource()));
            if (form.getCurrentDocAcceptable() == null || StringUtils.isEmpty(form.getCurrentDocAcceptable())) {            	
            	phDocument.setAcceptable(null);
            }
            else {
            	phDocument.setAcceptable(new Boolean(form.getCurrentDocAcceptable()));
            }
            phDocument.setUnacceptableRemarks(StringUtils.isBlank(form.getCurrentDocUnacceptableRemarks()) ? null :
                form.getCurrentDocUnacceptableRemarks());
        }        
    }
}
