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

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.Validate;

import gov.va.med.fw.batchprocess.AbstractDataFileSingleRowIncrementProcess;
import gov.va.med.fw.batchprocess.DataFileProcessExecutionContext;
import gov.va.med.fw.service.ServiceException;

import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.messaging.SiteIdentity;
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.PersonIdEntityKeyImpl;
import gov.va.med.esr.service.MessagingService;
import gov.va.med.esr.service.PSDelegateService;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.esr.service.PersonService;

/**
 * Batch process that simply triggers QRYZ07 messages from parsing
 * a file from HECLegacy.
 *
 * TODO: Perhaps do the triggering in bulk, rather than one at a time
 *
 * @author DNS   BOHMEG
 *
 */
public class ReceiveUnmigratedICNFileProcess extends
		AbstractDataFileSingleRowIncrementProcess {
	protected MessagingService messagingService;
	protected PSDelegateService psDelegateService;
	protected PersonService personService;

	protected boolean processDataRecord(
			DataFileProcessExecutionContext context, Object bean) {
		UnmigratedICNFileData dataRecord = (UnmigratedICNFileData) bean;

		boolean success = true;
		Person person = null;

		try {
			person = matchPerson(dataRecord);
			if (person != null) {

				// CodeCR7321 - Needed for deployment phase 1: add logic to the income year
				// (If IY < 1992 set IY = 2007)
				Integer incomeYear = new Integer(Calendar.getInstance().get(Calendar.YEAR));
				//if (incomeYear == null || incomeYear.intValue() < 1992)
					//incomeYear = new Integer(Calendar.getInstance().get(Calendar.YEAR));

				VAFacility facility = getFacility(person);

				if (facility != null) {
					messagingService.triggerQRYZ07(person, facility, incomeYear, false);
				} else {
					throw new Exception("no facility found");
				}
				if(logger.isInfoEnabled()) {
					logger.info("QRYZ07 triggered for Person: " + person.getPersonEntityKey().getKeyValueAsString());
				}
			} else
				success = false;
		} catch (Exception e) {
			PersonEntityKey key = person != null ? person.getPersonEntityKey() : null;
			if(key != null) {
				throwIllegalStateException("Unable to trigger QRYZ07 for person: " +
						key.getKeyValueAsString(), e);
			} else {
				throwIllegalStateException("Unable to trigger QRYZ07 because can not find person " +
						"for DFN: " + dataRecord.getDFN(), e);
			}
		}
		return success;
	}

	private VAFacility getFacility(Person person) throws ServiceException {

		Set<?> sites = this.getPsDelegateService().getSites(person.getVPIDEntityKey());

        if (sites != null && !sites.isEmpty()) {

        	for( Iterator<?> iter = sites.iterator(); iter.hasNext(); ) {

        		SiteIdentity siteIdentity = (SiteIdentity) iter.next();
        		if (siteIdentity.getVaFacility().getType().getIsMedicalTreating()) {
            		return siteIdentity.getVaFacility();
            	}
        	}
        }

        return null;
	}


	//Use compositeCall
	private Person matchPerson(UnmigratedICNFileData data) throws ServiceException {
		//PersonIdentityTraits traits = psDelegateService.getIdentityTraitsWithCompositeCall(data.getDFN(),
				//data.getFacility().getCode());

		PersonEntityKey key = new PersonIdEntityKeyImpl(data.getPersonId());

		return personService.getPerson(key);
		//return personService.find(traits);
	}


	/*private Person matchPerson(UnmigratedICNFileData data) throws ServiceException {
		PersonIdentityTraits traits = psDelegateService.getIdentityTraits(data.getDFN(),
				data.getFacility().getCode());
		return personService.find(traits);
	}*/

	public MessagingService getMessagingService() {
		return messagingService;
	}

	public void setMessagingService(MessagingService messagingService) {
		this.messagingService = messagingService;
	}

	public void afterPropertiesSet() {
		super.afterPropertiesSet();
		Validate.notNull(messagingService, "messagingService is required");
		Validate.notNull(personService, "personService is required");
		Validate.notNull(psDelegateService, "psDelegateService is required");
	}

	public PersonService getPersonService() {
		return personService;
	}

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

	public PSDelegateService getPsDelegateService() {
		return psDelegateService;
	}

	public void setPsDelegateService(PSDelegateService psDelegateService) {
		this.psDelegateService = psDelegateService;
	}

}
