package gov.va.med.esr.messaging.builder.message;

import gov.va.med.esr.common.model.financials.FinancialStatement;
import gov.va.med.esr.common.model.financials.RelationFinancials;
import gov.va.med.esr.common.model.lookup.AssetType;
import gov.va.med.esr.common.model.lookup.ExpenseType;
import gov.va.med.esr.common.model.lookup.IncomeType;
import gov.va.med.esr.common.model.lookup.Relationship;
import gov.va.med.esr.common.model.person.Person;

import gov.va.med.fw.hl7.segment.ZIC;
import gov.va.med.fw.util.builder.BuilderException;

/**
 * Builder to build a ZIC segment for Spouse and Dependents
 * 
 * @author Rajiv Patnaik Created on Jan 5, 2006
 * @version 1.0
 * 
 * Copyright © 2005 VHA. All rights reserved
 */
public class ZICDependentBuilder extends AbstractZICBuilder
{
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = 3892587203797841087L;

   /**
     * Method to build the ZIC segment.
     * 
     * @param metaData
     *            The parameter object used to build the a ZIC segment.
     * @return The ZIC segment.
     */
    public Object build(ZICMetaData metaData) throws BuilderException
    {
        if ((metaData == null) || (metaData.getEntity() == null)
                || !(metaData.getEntity() instanceof Person)
                || metaData.getSetId() == null
                || metaData.getRelationship() == null)
        {
            throw new BuilderException(
                    "Invalid input parameter to build a segment");
        }

        Relationship relationship = metaData.getRelationship();
        RelationFinancials relationFinancials = metaData.getRelationFinancials();
        Integer incomeYear = metaData.getIncomeYear();
        
        //Get isPost2005Format
        Person person = (Person) metaData.getEntity();

        ZIC segment = new ZIC();
        segment.setSetID(metaData.getSetId());

        //SEQ 1-12,16-20 for spouse and SEQ 1-12,15 for all
        //other dependents when ZMT-30 = 0
        //SEQ 1-3,9,12,16,18-19 for spouse and dependents when ZMT-30 = 1
        if(relationFinancials != null)
        {
            FinancialStatement financialStatement = person
            	.getFinancialStatement(incomeYear);
    
		    Boolean isPost2005Format = financialStatement.getIsPost2005Format();

            if (isPost2005Format != null && isPost2005Format.booleanValue())
	        {
	            segment = buildPost2005Attributes(segment, incomeYear,
	                    relationFinancials, relationship);
	        } else
	        //assume it is a Pre2005 format(ZMT-30 = 0)
	        {
	            segment = buildPre2005Attributes(segment, incomeYear,
	                    relationFinancials, relationship);
	        }
        }
        return segment;
    }

    /**
     * SEQ 1-12,16-20 for spouse and SEQ 1-12,15 for all other dependents when
     * ZMT-30 = 0
     * 
     * @param segment
     * @param incomeYear
     * @param financialStatement
     * @return
     * @throws BuilderException
     */
    private ZIC buildPre2005Attributes(ZIC segment, Integer incomeYear,
            RelationFinancials relationFinancials, Relationship relationship)
            throws BuilderException
    {
        segment = buildCommonPre2005Attributes(segment, incomeYear,
                relationFinancials);
        //For spouse
        if (Relationship.CODE_SPOUSE.getName().equals(relationship.getCode()))
        {
            //Seq 16
            segment.setCashAmountInBankAccounts(
                    getAssetAmountAsString(relationFinancials, AssetType.CODE_CASH.getName()));
            //Seq 17
            segment.setStocksAndBonds(getAssetAmountAsString(
                    relationFinancials, AssetType.CODE_STOCKS_AND_BONDS.getName()));
            //Seq 18
            segment.setRealProperty(
                    getAssetAmountAsString(relationFinancials, AssetType.CODE_REAL_ESTATE.getName()));
            //Seq 19
            segment.setOtherPropertyAssets(
                    getAssetAmountAsString(relationFinancials, AssetType.CODE_OTHER.getName()));
    
            //Seq 20
            segment.setDebts(relationFinancials.getDebt() == null ? null : super
                    .build(relationFinancials.getDebt().getAmount()));
        } else
        {
            //Seq 15
            segment.setEducationalExpenses(getExpensesAsString(
                    relationFinancials,
                    ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT.getName()));

        }
        return segment;
    }

    /**
     * SEQ 1-3,9,12,16,18-19 for spouse and dependents when ZMT-30 = 1
     * 
     * @param segment
     * @param financialStatement
     * @throws BuilderException
     */
    private ZIC buildPost2005Attributes(ZIC segment, Integer incomeYear,
            RelationFinancials relationFinancials, Relationship relationship) throws BuilderException
    {
        segment = buildCommonPost2005Attributes(segment, incomeYear, relationFinancials);
        //For Dependent
        if (!Relationship.CODE_SPOUSE.getName().equals(relationship.getCode()))
        {
            //Seq 15
            segment.setEducationalExpenses(getExpensesAsString(
                    relationFinancials,
                    ExpenseType.EXPENSE_TYPE_EDUCATIONAL_EXPENSES_BY_DEPENDENT.getName()));

        }
        return segment;
    }

    /**
     * @param segment
     * @param incomeYear
     * @param financialStatement
     * @throws BuilderException
     */
    private ZIC buildCommonPre2005Attributes(ZIC segment, Integer incomeYear,
            RelationFinancials relationFinancials) throws BuilderException
    {
        //Seq 2        
        super.setIncomeYear(segment, incomeYear);
    
        //Seq 3
        segment.setSocialSecurity(
                getIncomeAsString(relationFinancials, IncomeType.INCOME_TYPE_SOCIAL_SECURITY.getName()));
        //Seq 4
        segment.setCivilService(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_CIVIL_SERVICE.getName()));
        //Seq 5
        segment.setRailroadRetirement(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_RAILROAD_RETIREMENT.getName()));
        //Seq 6
        segment.setMilitaryRetirement(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_MILITARY_RETIREMENT.getName()));
        //Seq 7
        segment.setUnemploymentCompensation(getIncomeAsString(
                relationFinancials,
                IncomeType.INCOME_TYPE_UNEMPLOYMENT_COMPENSATION.getName()));
        //Seq 8
        segment.setOtherRetirement(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_OTHER_RETIREMENT.getName()));
        //Seq 9
        segment.setEmploymentIncome(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT.getName()));
        //Seq 10
        segment.setInterestDividendAnnuity(getIncomeAsString(
                relationFinancials,
                IncomeType.INCOME_TYPE_INTEREST_DIVIDEND_ANNUITY.getName()));
        //Seq 11
        segment.setWorkersCompBlackLung(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_WORKERS_COMP_BLACK_LUNG.getName()));
        //Seq 12
        segment.setOtherIncome(
                getIncomeAsString(relationFinancials, IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME.getName()));     
        
        return segment;
    }
    
    private ZIC buildCommonPost2005Attributes(ZIC segment, Integer incomeYear, RelationFinancials relationFinancials) throws BuilderException {
        //Seq 2
        super.setIncomeYear(segment, incomeYear);
        
        
        //Seq 3
        segment.setSocialSecurity(
                getIncomeAsString(relationFinancials, IncomeType.INCOME_TYPE_TOTAL_ALL_OTHER_INCOME.getName()));
        //Seq 12
        segment.setOtherIncome(
                getIncomeAsString(relationFinancials, IncomeType.INCOME_TYPE_FARM_RANCH_PROPERTY_OR_BUSINESS_INCOME.getName()));
        //Seq 9
        segment.setEmploymentIncome(getIncomeAsString(relationFinancials,
                IncomeType.INCOME_TYPE_TOTAL_INCOME_FROM_EMPLOYMENT.getName()));
        
        // VFA: seq 16, 18, 19: Populated only if Income Year is earlier than 2009
        this.discontinueNetWorth(incomeYear, segment, relationFinancials);


        return segment;
    } 
}