/*******************************************************************************
 * Copyright © 2004 EDS. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.messaging.service.inbound;

// Java Classes
import java.math.BigDecimal;
import java.util.Date;

import gov.va.med.fw.hl7.HL7Message;
import gov.va.med.fw.hl7.HL7MessageUtils;
import gov.va.med.fw.hl7.InvalidMessageException;
import gov.va.med.fw.hl7.Message;
import gov.va.med.fw.hl7.constants.SegmentConstants;
import gov.va.med.fw.hl7.segment.PID;
import gov.va.med.fw.hl7.segment.ZEL;
import gov.va.med.fw.persistent.DAOException;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.util.StopWatchLogger;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.util.builder.BuilderException;

import gov.va.med.esr.common.builder.entity.ImpreciseDateBuilder;
import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.ee.EligibilityVerification;
import gov.va.med.esr.common.model.ee.VerificationInfo;
import gov.va.med.esr.common.model.lookup.EligibilityStatus;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.messaging.MessageLogEntry;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.workload.WorkflowCaseInfo;
import gov.va.med.esr.common.model.lookup.MessageType;
import gov.va.med.esr.common.persistent.messaging.MessageLogEntryDAO;

/**
 * Class to process ORUZ07 message.
 * 
 * @author Vu Le
 * @version 1.0
 */
public class K21ProcessService extends AbstractInboundProcessService {
     
    /**
     * An instance of messageLogEntryDAO
     */
    private MessageLogEntryDAO messageLogEntryDAO = null;

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

    /**
     * @see gov.va.med.esr.messaging.service.inbound.AbstractInboundProcessService#doProcessMessage(gov.va.med.esr.common.model.person.Person, gov.va.med.fw.hl7.Message, java.lang.String)
     */
    protected final MessageLogEntry doProcessMessage( Person person,
                                                        Message message, 
                                                     String formattedBody )
       throws InboundProcessException {
        
      if (person == null) {
            throw super.createInboundProcessException( message, 
                                                    formattedBody,
                                                    null, 
                                                    "AE: Could not find the person", 
                                                    null );
        }
        try {
            return this.doProcessMessage( person, 
                                       message, 
                                       formattedBody, 
                                       super.getReferencedMessageLogEntry( message ) );
        } 
      catch( InboundProcessException e ) {
            throw super.createInboundProcessException( message, 
                                                    formattedBody,
                                                    person, 
                                                    e.getMessage(), 
                                                    e );
        } 
      catch (ServiceException e) {
            throw super.createInboundProcessException( message, 
                                                    formattedBody,
                                                    person, 
                                                    e.getMessage(), 
                                                    e );
        }
    }
    
    /**
     * @param onFile
     * @param message
     * @param formattedBody
     * @param initiatingMessage
     * @return
     * @throws InboundProcessException
     */
    private final MessageLogEntry doProcessMessage( Person onFile,
                                                   Message message, 
                                                   String formattedBody, 
                                                   MessageLogEntry initiatingMessage ) 
       throws InboundProcessException {
        
        try {
                  
         // build a person from incoming message
            Person incoming = buildPerson( onFile, message );
            
            // Create a message log entry for this Z07 message
            MessageLogEntry mle = super.createMessageLog( message,
                                                       formattedBody, 
                                                       incoming, 
                                                       initiatingMessage );
                        
            VAFacility sendingFacility = super.getSendingFacility(message); 
            
            /* TODO DATABASE ENTRY -- update the seeding details table based on user id and facility ID to 'Received' */
            
            // not sure is K21 needs this infor and if the message has -- Z07 message doesn't have an entitlement code so set it to null
            VerificationInfo info = new VerificationInfo( getMessageTypeCode(),
                    HL7MessageUtils.getErrorText(message));
            // Set the site number to sending facility
            info.setSiteNumber(sendingFacility.getStationNumber());

            // Set the DFN in the Verification Info
            String dfn = getDfnFromPID((PID) message
                    .getSegment(SegmentConstants.PID));
            info.setDfn(dfn);

            // create workflow case object for potential usage by Rules
            WorkflowCaseInfo caseInfo = new WorkflowCaseInfo();
            caseInfo
                    .setTransmissionSite(getLookupService()
                            .getVaFacilityByStationNumber(
                                    message.getSendingFacility()));
            caseInfo.setMessageID(message.getMessageID());

            // create workflow case object for potential usage by Rules
            info.setWorkflowCaseInfo(caseInfo);
            
            //getMessagingService().processZ07( incoming, sendingFacility, info );
            getMessagingService().processK21( incoming, sendingFacility, info );
            mle.setPersonId( (BigDecimal)incoming.getEntityKey().getKeyValue() );
            
            //TODO update seeding state to complete in the seeding detail table 
            //TODO a check to the database will be done to see if all seeding is complete in order to mark seeding overview table 
            //to complete else keep it at under processing

            // set the result in a message log entry
            return mle;
        }
        catch( BuilderException e ) {
            throw super.createInboundProcessException( message, 
                                                    formattedBody,
                                                    onFile, 
                                                    e.getMessage(), 
                                                    e );
        }
        catch( Exception e ) {
            throw super.createInboundProcessException( message, 
                                                    formattedBody,
                                                    onFile, 
                                                    e.getMessage(), 
                                                    e );
        }
    }
  
    /**
     * @return Returns the personService.
    public PersonService getPersonService() {
        return personService;
    }

    public void setPersonService(PersonService personService) {
        this.personService = personService;
    }
    */

    /**
     * @return Returns the messageLogEntryDAO.
     */
    public MessageLogEntryDAO getMessageLogEntryDAO() {
        return messageLogEntryDAO;
    }

    /**
     * @param messageLogEntryDAO The messageLogEntryDAO to set.
     */
    public void setMessageLogEntryDAO(MessageLogEntryDAO messageLogEntryDAO) {
        this.messageLogEntryDAO = messageLogEntryDAO;
    }

}