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

import java.util.Date;
import java.util.List;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.lookup.DeathDataSource;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.person.DeathRecord;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKey;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.PersonService;
import gov.va.med.esr.service.DemographicService;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.fw.batchprocess.AbstractDataFileIncrementalProcess;
import gov.va.med.fw.batchprocess.DataFileProcessExecutionContext;

/**
 * This class processes a Date of Death (DoD) record. The record contains a vpid and a date of death.
 *
 * UPDATED 6/17/2016 to allow the job to process date of death deletes
 * RTC WI 3397448
 *
 * The DoD record is updated if :
 * there is not a current DoD record
 * there is an enrollment record
 *
 * This class gets a Person from the DB, checks to make sure the record can be updated, and if so updates the
 * DoD record.
 *
 * The fields updated in the DeathRecord are:
 *   	dateOfDeath
 *		DeathReportDate - current time
 *
 *		try {
 *			deathRecord.setDataSource(this.lookupService.getDeathDataSourceByCode(
 *			DeathDataSource always CODE_DEATH_CERT_ON_FILE
 *			FacilityReceived always 742 HEC
 *
 * @author DNS   NELSOR
 *
 */
public class DateOfDeathFileData extends AbstractDataFileIncrementalProcess {

	private PersonService personService;

	private LookupService lookupService;

	private DemographicService demographicService;

	/**
	 *
	 */
	private static final long serialVersionUID = 9062379406331204087L;


	/** This is the entry point for the class.  This is called for each line in the input file.  The
	 * bean is of type DateOfDeathImportData and should contain a vpid and a date of death as a Date.
	 *
	 */
	public void processDataRecords(DataFileProcessExecutionContext context, List acquiredData) {

		for ( int i=0; acquiredData != null && i< acquiredData.size(); i++)
        {
			DateOfDeathImportData dodData = (DateOfDeathImportData) acquiredData.get(i);
			processRecord(dodData, context);

        }

	}

	private void processRecord(DateOfDeathImportData dodData, DataFileProcessExecutionContext context) {

		Person onFile = null;

		try {
			VPIDEntityKey key = CommonEntityKeyFactory.createVPIDEntityKey(dodData.getVpid());
			PersonIdEntityKey personkey = this.getPersonService().getPersonIdByVPID(key);
			onFile = this.getPersonService().getPerson(personkey);
			boolean updating = true;

			if (onFile.getDeathRecord() != null && dodData.getDateOfDeath() == null || dodData.getDateOfDeath().isEmpty()) {
				//onFile.setDeathRecord(null);
				onFile.getDeathRecord().setDataSource(null);
				onFile.getDeathRecord().setDeathReportDate(null);
				onFile.getDeathRecord().setDeathDate(null);
				onFile.getDeathRecord().setDeathReportedBy(null);
				onFile.getDeathRecord().setDodVerifiedInd(null);
				onFile.getDeathRecord().setFacilityReceived(null);
				onFile.getDeathRecord().setLazarusDate(new ImpreciseDate(new Date()));
			} else if (dodData.getDateOfDeath() != null && dodData.getDateOfDeath().equalsIgnoreCase("U")){
				updating = false;
				onFile.setMailStopReason("Unverified Date of Death indicated from MVI correlation");
				this.getPersonService().save(onFile);
			} else {
				DeathRecord deathRecord = new DeathRecord();
				deathRecord.setDeathDate(new ImpreciseDate(dodData.getDateOfDeath()));
				deathRecord.setDeathReportDate(new Date());

				try {
					deathRecord.setDataSource(this.lookupService.getDeathDataSourceByCode(
							DeathDataSource.CODE_DEATH_CERT_ON_FILE.getCode()));

					deathRecord.setFacilityReceived(this.lookupService.getVaFacilityByCode(VAFacility.CODE_HEC.getCode()));

				} catch (UnknownLookupTypeException e) {
					logger.error(e);
				}

				onFile.setDeathRecord(deathRecord);
			}

			if (updating) {
				this.getDemographicService().updateDemographicInformation(onFile);
			}
			context.getProcessStatistics().incrementNumberOfSuccessfulRecords();

		} catch (Exception ex) {
			logger.error("Error processing the Death Record from Idm" + ex);
			context.getProcessStatistics().incrementNumberOfErrorRecords();
		}

	}

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

    /**
     * @param lookupService
     *           The lookupService to set.
     */
    public void setLookupService(LookupService lookupService) {
        this.lookupService = lookupService;
    }

	public DemographicService getDemographicService() {
		return demographicService;
	}

	public void setDemographicService(DemographicService demographicService) {
		this.demographicService = demographicService;
	}
}
