package gov.va.med.esr.common.batchprocess;

import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.ee.EligibilityVerification;
import gov.va.med.esr.common.model.lookup.AACIndicator;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;
import gov.va.med.esr.service.GenerateQRYZ11MessagingService;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.PersonService;
import gov.va.med.esr.service.impl.GenerateQRYZ11MessagingServiceImpl;
import gov.va.med.esr.service.trigger.PersonTrigger;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;
import gov.va.med.fw.batchprocess.AbstractDataFileIncrementalProcess;
import gov.va.med.fw.batchprocess.DataFileProcessExecutionContext;
import gov.va.med.fw.batchprocess.ProcessStatisticsHandler;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.service.trigger.TriggerEvent;
import gov.va.med.fw.service.trigger.TriggerRouter;

import java.math.BigDecimal;
import java.util.List;

import org.apache.commons.lang.Validate;

public class QueryVBAOnSelectedPersonsProcess extends AbstractDataFileIncrementalProcess {
	         
	private TriggerRouter triggerRouter;
	private GenerateQRYZ11MessagingService messagingService = null;
    private PersonService personService;
    private LookupService lookupService;  
	// private ProcessStatisticsHandler processStatisticsHandler;

	public void processDataRecords(
			DataFileProcessExecutionContext context, List beans) {
		
		if (logger.isDebugEnabled())
		{
			int listSize = 0;
			if ( beans != null ) 
				listSize = beans.size();
			logger.error("Processing VPID  " + listSize);
		}
		
		for ( int i=0; beans != null && i< beans.size(); i++)
		{
			VPIDFileData vpidDataRecord = (VPIDFileData) beans.get(i);
			String VPID = vpidDataRecord.getVpid();
			
			try {	
				 VPIDEntityKey vpidEntityKey = CommonEntityKeyFactory.createVPIDEntityKey(vpidDataRecord.getVpid());
				// PersonEntityKey personEntityKey = personService.getPersonIdByVPID(vpidEntityKey);

				 // following codes would be used if input file is PersonID
				/*
				 String personIdinString = vpidDataRecord.getVpid();
				 BigDecimal personId = new BigDecimal(personIdinString);
				 PersonIdEntityKey personKey = new PersonIdEntityKeyImpl(personId);
				 VPIDEntityKey vpidKey = personService.getVPIDByPersonId(personKey);
				 if ( vpidKey == null)
					 throw new RuntimeException("Unable to find Person for vpid: "+ personId);
				 
				 String vpid_value = vpidKey.getVPID();
				 if (personEntityKey == null)
					throw new RuntimeException("Unable to find Person for VPID: "+ VPID);
				*/  
				 if (logger.isDebugEnabled())
			           logger.error("Processing VPID  " + vpidDataRecord.getVpid());
				
				 processRecord(vpidEntityKey,VPID);
				 context.getProcessStatistics().incrementNumberOfSuccessfulRecords();
				
			} catch (Exception e) {
				if (logger.isErrorEnabled())
		           logger.error("Error during Sending Query Z11 From a file process for  VPID " + vpidDataRecord.getVpid(), e);   
				context.getProcessStatistics().incrementNumberOfErrorRecords();
			}
			finally
			{
				// Check if we need to update the job result
				if(shouldUpdateJobResult(context))
						updateJobResult(context);
				
				if ( isInterrupted(context))
				{
					break;
				}
			}
		}
	}

	  /**
     * Processes data for a particular person
     * @param key
     * @param VPID
     * @throws ServiceException 
     */
    protected void processRecord(PersonEntityKey key, String VPID) throws Exception 
    {
    	// send query z11
       	messagingService.generateMessage(key, VPID);
       	
       	// after QRYZ11 message was sent, set VBA Query Status = "VBA Queried, Pending Response"
       	// retrieve Person
		Person person = personService.getPerson(key);
		if (person == null)
			throw new RuntimeException("Unable to find Person for VPID: "+ VPID);
		
		// set person AAC indicator for VBA query status 
		 if (person.getEligibilityVerification() == null) {
	            EligibilityVerification eligibilityVerification = new EligibilityVerification();
	            person.setEligibilityVerification(eligibilityVerification);
	    }
		person.getEligibilityVerification().setAacIndicator(this.getLookupService().getAACIndicatorByCode(AACIndicator.CODE_AAC_QUERIED_PENDING.getCode()));
		
		personService.save(person);
    }
        
    /**
     * @param messagingService
     *            The messagingService to set.
     */
    public void setMessagingService(GenerateQRYZ11MessagingService messagingService) {
        this.messagingService = messagingService;
    }

    protected GenerateQRYZ11MessagingService getMessagingService() {
    	return messagingService;
    }

    public PersonService getPersonService() {
		return personService;
	}

    /**
     * @return Returns the lookupService.
     */
    public LookupService getLookupService() {
        return lookupService;
    }
    
    /**
     * @param lookupService The lookupService to set.
     */
    public void setLookupService(LookupService lookupService) {
        this.lookupService = lookupService;
    }    
	/**
	 * @param personService
	 *            The personService to set.
	 */
	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}
	/**
	 * @return Returns the bulletinService.
	 */

    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        Validate.notNull(personService);
        Validate.notNull(lookupService);
        Validate.notNull(messagingService, "A MessagingService is needed");
        Validate.isTrue(!(messagingService instanceof GenerateQRYZ11MessagingServiceImpl), 
                "A GenerateQRYZ11 Messaging Service is required");
    }
    
	private TriggerEvent getTriggerEvent(PersonEntityKey key)
	{
		PersonTriggerEvent triggerEvent = new PersonTriggerEvent(PersonTrigger.DestinationType.MESSAGING,
                PersonTrigger.TargetType.VISTA, PersonTrigger.DispatchType.NOTIFY,  PersonTrigger.DataType.ELIGIBILITY);
		triggerEvent.setPersonId(key);
		return triggerEvent;
	}


	public TriggerRouter getTriggerRouter() {
		return triggerRouter;
	}


	public void setTriggerRouter(TriggerRouter triggerRouter) {
		this.triggerRouter = triggerRouter;
	}
}
