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

import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.person.BirthRecord;
import gov.va.med.esr.common.model.person.Name;
import gov.va.med.esr.service.PersonIdentityTraits;
import gov.va.med.fw.io.RawFileDataList;
import gov.va.med.fw.util.StringUtils;

import java.util.Iterator;
import java.util.List;

/**
 * 
 * @author Rajiv Patnaik
 * Created on Apr 29, 2006
 * @version 1.0
 * 
 * Copyright © 2006 VHA. All rights reserved
 */
public class OPPExtractMainOutputFileProducer extends
        AbstractOPPExtractOutputFileProducer
{

    private static final String CODE_NO = "0";

    private static final String CODE_YES = "1";    
    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.esr.common.batchprocess.AbstractOPPExtractProcess#setIdentityTraitsOnOutputData(gov.va.med.fw.io.RawFileDataList,
     *      gov.va.med.esr.service.PersonIdentityTraits)
     */
    protected RawFileDataList setIdentityTraitsOnOutputData(
            RawFileDataList rawFileDataRow, PersonIdentityTraits traits)
    {
        //Elements start with 0
        rawFileDataRow.set(1, (traits == null ||  traits.getSsn() == null) ? "" : traits.getSsn().getSsnText());
        
        //4th element - DOB
        BirthRecord birthRecord = traits.getBirthRecord();    
        if(birthRecord != null && birthRecord.getBirthDate() != null)
        {
	        String formattedDateOfBirth = getCenturyFormattedDate(birthRecord.getBirthDate().getDate());
	        rawFileDataRow.set(4, (formattedDateOfBirth == null) ? "" : formattedDateOfBirth);        
        }
        //21 -Gender
        rawFileDataRow.set(21, (traits == null ||  traits.getGender() == null) ? "" : traits.getGender().getCode());
        
        //33-37 - Name
        Name name = traits.getLegalName();
        if (name != null)
        {
            rawFileDataRow.set(33, (name.getGivenName() == null) ? "" : name.getGivenName());
            rawFileDataRow.set(34, (name.getMiddleName() == null) ? "" : name.getMiddleName());
            rawFileDataRow.set(35, (name.getFamilyName() == null) ? "" : name.getFamilyName());
            rawFileDataRow.set(36, (name.getSuffix() == null) ? "" : name.getSuffix());
            rawFileDataRow.set(37, (name.getPrefix() == null) ? "" : name.getPrefix());
        }
            
        return rawFileDataRow;
        
    }

    /*
     * (non-Javadoc)
     * 
     * @see gov.va.med.esr.common.batchprocess.AbstractOPPExtractProcess#incrementStatistics(gov.va.med.esr.common.batchprocess.OPPExtractProcessStatistics,
     *      java.util.List)
     */
    protected void incrementStatistics(OPPExtractExecutionContext context, 
            List outputFileData)
    {
        // Set statistsics
        
        OPPExtractProcessStatistics statistics = (OPPExtractProcessStatistics)context.getProcessStatistics();
 
        //Set the successful records stats
        setStatistics(statistics, outputFileData);
    }

    /**
     * @param statistics
     * @param outputFileData
     * @param queryStatisticsData
     */
    private void setStatistics(OPPExtractProcessStatistics statistics, List outputFileData)
    {
        statistics.incrementNumberOfSuccessfulRecords(outputFileData.size());

        statistics.incrementNumberOfMainFileRecords(outputFileData.size());
        
        for (Iterator iter = outputFileData.iterator(); iter.hasNext();)
        {
            RawFileDataList fileData = (RawFileDataList) iter.next();
            
            if (isEnrolleeStatusCriteriaMatched(fileData))
                statistics.incrementNumberOfTotalEnrollees(1);

            if (isDeceasedBeneficiariesCriteriaMatched(fileData))
                statistics.incrementNumberOfDeceasedBeneficiaries(1);

            if (isCanceledDeclinedCriteriaMatched(fileData))
                statistics.incrementNumberOfCanceledDeclinedEnrollees(1);

            if (isIneligibleCriteriaMatched(fileData))
                statistics.incrementNumberOfIneligibleEnrolees(1);

            if(isPendingMeansTestCriteriaMatched(fileData))
                statistics.incrementNumberOfPendingMeansTestRecords(1);

            if (isAutoEnrolledRecordsCriteriaMatched(fileData))
                statistics.incrementNumberOfAutoEnrolledRecords(1);

            if (isOfficialEnrolleeCriteriaMatched(fileData))
                statistics.incrementNumberOfOfficialEnrollees(1);

            if (isUnOfficialEnrolleeCriteriaMatched(fileData))
                statistics.incrementNumberOfUnOfficialEnrollees(1);

            if (isActiveHealthInsuranceCriteriaMatched(fileData))
                statistics.incrementNumberOfActiveHealthInsuranceRecords(1);
        }
    }
    
    
    /**
     * @param fileData
     * @return
     */
    private boolean isActiveHealthInsuranceCriteriaMatched(
            RawFileDataList fileData)
    {
        String activeHealthInsurance = (String)fileData.get(12);
        return (StringUtils.isNotEmpty(activeHealthInsurance) && StringUtils.equals(activeHealthInsurance, CODE_YES));
    }

    /**
     * @param fileData
     * @return
     */
    private boolean isUnOfficialEnrolleeCriteriaMatched(
            RawFileDataList fileData)
    {
        String officialEnrollee = (String)fileData.get(56);
        return (StringUtils.isNotEmpty(officialEnrollee) && officialEnrollee.equals(CODE_NO));
    }

    /**
     * @param fileData
     * @return
     */
    private boolean isOfficialEnrolleeCriteriaMatched(
            RawFileDataList fileData)
    {
        String officialEnrollee = (String)fileData.get(56);
        return (StringUtils.isNotEmpty(officialEnrollee) && officialEnrollee.equals(CODE_YES));
    }

    /**
     * @param fileData
     * @return
     */
    private boolean isAutoEnrolledRecordsCriteriaMatched(
            RawFileDataList fileData)
    {
        String officialEnrollee = (String)fileData.get(38);
        return (officialEnrollee != null && officialEnrollee.equals(CODE_YES));
    }

    /**
     * Enrollment Status of Not Eligible; Ineligible Date and if no Enrollment Status include those 
     * with an Ineligible Date populated.
     * 
     * @param fileData
     * @return
     */
    private boolean isIneligibleCriteriaMatched(RawFileDataList fileData)
    {
        String enrollmentStatus = (String)fileData.get(9);
        String ineligibleDate = (String)fileData.get(39);

        return ( (StringUtils.isNotEmpty(enrollmentStatus) && 
                EnrollmentStatus.CODE_NOT_ELIGIBLE_INELIGIBLE_DATE.getCode().equals(enrollmentStatus) )
                || (enrollmentStatus == null && ineligibleDate != null) );
    }

    /**
     * @param fileData
     * @return
     */
    private boolean isCanceledDeclinedCriteriaMatched(
            RawFileDataList fileData)
    {
        String enrollmentStatus = (String)fileData.get(9);

        return (StringUtils.isNotEmpty(enrollmentStatus) && EnrollmentStatus.CODE_CANCELLED_DECLINED
                .getCode().equals(enrollmentStatus));
    }

    /**
     * 1. Enrollment Status = Deceased 2. OR Enrollment Status NOT Deceased &&
     * DOD populated
     * 
     * @param fileData
     * @return
     */
    private boolean isDeceasedBeneficiariesCriteriaMatched(
            RawFileDataList fileData)
    {
        String enrollmentStatus = (String)fileData.get(9);
        String dateOfDeath = (String)fileData.get(40);

        return (StringUtils.isNotEmpty(enrollmentStatus) && ((EnrollmentStatus.CODE_DECEASED
                .getCode().equals(enrollmentStatus)) || (!(EnrollmentStatus.CODE_DECEASED
                .getCode().equals(enrollmentStatus)) && StringUtils.isNotEmpty(dateOfDeath))));
    }

    /**
     * @param fileData
     * @return
     */
    private boolean isEnrolleeStatusCriteriaMatched(
            RawFileDataList fileData)
    {
        String enrollmentStatus = (String)fileData.get(9);

        return (StringUtils.isNotEmpty(enrollmentStatus));
    }

    /**
     * Enrollment Status is Pending; Means Test Required
     * 
     * @param fileData
     * @return
     */
    private boolean isPendingMeansTestCriteriaMatched(
            RawFileDataList fileData)
    {
        String enrollmentStatus = (String)fileData.get(9);
        
        return (StringUtils.isNotEmpty(enrollmentStatus) && (EnrollmentStatus.CODE_PENDING_MEANS_TEST_REQUIRED
                .getCode().equals(enrollmentStatus)));
    }
    
    

}
