/**
 *
 */
package gov.va.med.esr.voa.webservice.builder.impl;

import java.util.Date;
import java.util.Iterator;
import java.util.Set;

import gov.va.med.esr.common.infra.ImpreciseDate;
import gov.va.med.esr.common.infra.TriState;

import gov.va.med.esr.common.model.ee.ClinicalDetermination;

import gov.va.med.esr.common.model.ee.NoseThroatRadium;
import gov.va.med.esr.common.model.ee.RadiationExposure;

import gov.va.med.esr.common.model.ee.AgentOrangeExposure;
import gov.va.med.esr.common.model.ee.CampLejeuneVerification;
import gov.va.med.esr.common.model.ee.EnvironmentalContaminationExposure;
import gov.va.med.esr.common.model.ee.MedicaidFactor;
import gov.va.med.esr.common.model.ee.ServiceConnectionAward;
import gov.va.med.esr.common.model.ee.SpecialFactor;
import gov.va.med.esr.common.model.lookup.CampLejeuneChangeSource;
import gov.va.med.esr.common.model.lookup.Indicator;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.voa.webservice.NoseThroatRadiumInfo;
import gov.va.med.esr.voa.webservice.ServiceConnectionAwardInfo;
import gov.va.med.esr.voa.webservice.SubmitFormRequest;
import gov.va.med.esr.voa.webservice.builder.EnrollmentDeterminationBuilderFactory;
import gov.va.med.fw.service.AbstractComponent;
import gov.va.med.fw.service.config.SingletonApplicationContext;

/**
 * @author DNS   CHINNR
 *
 */
public class EnrollmentDeterminationBuilderFactoryImpl extends AbstractComponent implements EnrollmentDeterminationBuilderFactory {
	private LookupService lookupService = null;

	public void buildEntrollmentDeterminationServices(Person person,SubmitFormRequest submitFormRequest) throws Exception{

		if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo() != null){

			buildSpecialFactors(person,submitFormRequest);
			buildNSTData(person,submitFormRequest);
			buildServiceConnectionAward(person,submitFormRequest);
			MedicaidFactor mf = new MedicaidFactor();
			if( submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().isEligibleForMedicaid()!= null &&
					submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().isEligibleForMedicaid()){

				mf.setEligibleForMedicaid(Boolean.TRUE);
				mf.setLastUpdateDate(new Date());
				person.setMedicaidFactor(mf);

			} else {
				mf.setEligibleForMedicaid(Boolean.FALSE);
				mf.setLastUpdateDate(new Date());
				person.setMedicaidFactor(mf);
			}

		}
	}

		private  void buildSpecialFactors(Person person,SubmitFormRequest submitFormRequest) throws Exception {

			try {
				RadiationExposure re = new RadiationExposure();
				if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors() != null &&
						submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isRadiationExposureInd() != null){
					try{
						if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isRadiationExposureInd()){
							re.setRadiationExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.YES));
						}else{
							re.setRadiationExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.NO));
						}
					}catch(Exception ex){
						logger.error("Exception @buildSpecialFactors-RadiationExposure  :", ex);
						throw new Exception (ex);
					}
					SpecialFactor sf = (SpecialFactor)re;
					person.addSpecialFactor(sf);
				}

				AgentOrangeExposure aoe = new AgentOrangeExposure();
				if(	submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors() != null &&
						 submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isAgentOrangeInd() != null){
					try{
						if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isAgentOrangeInd()){
							aoe.setAgentOrangeExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.YES));
						}else{
							aoe.setAgentOrangeExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.NO));
						}
					}catch(Exception ex){
						logger.error("Exception @buildSpecialFactors-AgentOrangeExposure  :", ex);
						throw new Exception (ex);
					}
					SpecialFactor sfa = (SpecialFactor)aoe;
					person.addSpecialFactor(sfa);
				}

				//CCR13831: pull back CLV indicator from VOA submission so ES will not process it until MSDS query response is fixed
				//CCR12789: added Camp Lejeune CL indicator
				if (submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors() != null
						&& submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isCampLejeuneInd() != null) {
					try {
						CampLejeuneVerification cl = new CampLejeuneVerification();
						cl.setChangeSource(getLookupService().getCampLejeuneChangeSourceByCode(CampLejeuneChangeSource.CODE_VOA.getCode()));
						if (submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isCampLejeuneInd()) {
							//CL-V_CodeCR13530
							cl.setSpecialFactorIndicator(getLookupService().getIndicatorByCode(Indicator.YES));
							cl.setRegistrationDate(new ImpreciseDate(new Date()));
						} else {
							cl.setSpecialFactorIndicator(getLookupService().getIndicatorByCode(Indicator.NO));
						}
						SpecialFactor sfa = (SpecialFactor)cl;
						person.addSpecialFactor(sfa);
					} catch (Exception ex) {
						logger.error("Exception @buildSpecialFactors-Camp Lejeune  :", ex);
						throw new Exception (ex);
					}
				}

				EnvironmentalContaminationExposure ece = new EnvironmentalContaminationExposure();
				if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors() != null &&
						 submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isEnvContaminantsInd() != null){
					try{
						if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getSpecialFactors().isEnvContaminantsInd()){
							ece.setEnvironmentalContaminationExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.YES));
						}else{
							ece.setEnvironmentalContaminationExposureIndicator((Indicator)this.getLookupService().getIndicatorByCode(Indicator.NO));
						}
					}catch(Exception ex){
						logger.error("Exception @buildSpecialFactors-EnvironmentalContaminationExposure  :", ex);
						throw new Exception (ex);
					}
					SpecialFactor sfe = (SpecialFactor)ece;
					person.addSpecialFactor(sfe);
				}
			} catch(Exception ex) {
				throw new Exception("Failed to build person from special factors:" + ex.getMessage());
			}
		}

		private  void buildNSTData(Person person,SubmitFormRequest submitFormRequest) {
			if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getNoseThroatRadiumInfo() != null){
				NoseThroatRadium ntr = (NoseThroatRadium) getClinicalDetermination(NoseThroatRadium.class, person);

				if(ntr == null) ntr = new NoseThroatRadium();
				NoseThroatRadiumInfo ntrinfo = submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getNoseThroatRadiumInfo();

				if (ntrinfo.getReceivingTreatment() != null && ntrinfo.getReceivingTreatment().equalsIgnoreCase("true")){
					ntr.setReceivingTreatment(TriState.TRUE);
				}else{
						ntr.setReceivingTreatment(TriState.FALSE);
				}
				if(ntrinfo.getReceivingTreatment() == null) ntr.setReceivingTreatment(TriState.UNKNOWN);

				person.addClinicalDetermination(ntr);
			}
		}


		private void buildServiceConnectionAward(Person person,SubmitFormRequest submitFormRequest) {

			if(submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getServiceConnectionAward() != null){
				ServiceConnectionAward scAward =  new ServiceConnectionAward();
				ServiceConnectionAwardInfo scaInfo= submitFormRequest.getForm().getSummary().getEnrollmentDeterminationInfo().getServiceConnectionAward();

				if(scaInfo != null ){

				   if(scaInfo.isServiceConnectedIndicator() != null && scaInfo.isServiceConnectedIndicator()){
					   scAward.setServiceConnectedIndicator(Boolean.TRUE);
				   } else {
					   scAward.setServiceConnectedIndicator(Boolean.FALSE);
				   }

				   person.setServiceConnectionAward(scAward);
				}
			}

		}
		   /**
	     * Return the particular type of clinical determination from person.
	     *
	     * @param classObject
	     * @param person
	     * @return
	     */
	    @SuppressWarnings("rawtypes")
		public  ClinicalDetermination getClinicalDetermination(Class classObject,
	            Person person) {

	        if (person == null) {
	            return null;
	        }
	        Set clinicalDeterminations = person.getClinicalDeterminations();
	        ClinicalDetermination clinicalDetermination = null;

	        if (clinicalDeterminations != null && clinicalDeterminations.size() > 0) {
	            Iterator iterClinicalDeterminations = clinicalDeterminations
	                    .iterator();

	            while (iterClinicalDeterminations.hasNext()) {
	                ClinicalDetermination temp = (ClinicalDetermination) iterClinicalDeterminations
	                        .next();

	                if (temp != null
	                        && temp.getClass().isAssignableFrom(classObject)) {
	                    clinicalDetermination = temp;
	                    break;
	                }
	            }
	        }

	        return clinicalDetermination;
	}

	public LookupService getLookupService() {

				if(lookupService == null){
					lookupService= (LookupService) SingletonApplicationContext.getInstance().getSingletonContext()
					.getBean("lookupService");
				}
				return lookupService;
	}

   public void setLookupService(LookupService lookupService) {
				this.lookupService = lookupService;
	}
}


