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

import gov.va.med.esr.common.model.ee.IncompetenceRuling;
import gov.va.med.esr.common.model.lookup.AssociationType;
import gov.va.med.esr.common.model.person.Association;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.service.trigger.PersonTrigger;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;
import gov.va.med.esr.service.trigger.PersonTriggerIdentity;
import gov.va.med.fw.hl7.Segment;
import gov.va.med.fw.hl7.builder.HL7MetaData;
import gov.va.med.fw.hl7.constants.SegmentConstants;
import gov.va.med.fw.hl7.segment.ZGD;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.util.StringUtils;
import gov.va.med.fw.util.builder.Builder;
import gov.va.med.fw.util.builder.BuilderException;

/**
 * Builds the ZGD segment for Z05 message based on different datatypes.
 * 
 * @author Rajiv Patnaik Created on Sep 8, 2005
 * @version 1.0
 * 
 * Copyright © 2005 VHA. All rights reserved
 */
public class ZGDZ05Builder extends AbstractSegmentBuilder
{
    
    /**
    * An instance of serialVersionUID 
    */
   private static final long serialVersionUID = 964210774388515970L;
   private Builder guardianTypeBuilder; 
    
    /**
     * @return Returns the guardianTypeBuilder.
     */
    public Builder getGuardianTypeBuilder()
    {
        return guardianTypeBuilder;
    }
    /**
     * @param guardianTypeBuilder The guardianTypeBuilder to set.
     */
    
    public void setGuardianTypeBuilder(Builder guardianTypeBuilder)
    {
        this.guardianTypeBuilder = guardianTypeBuilder;
    }
    
    /**
     * Method to build the ZGD segment for the Z05 message.
     * 
     * @param metaData
     *            The parameter object used to build the a ZGD segment.
     * @param personTriggerEvent
     * @return The ZGD segment.
     */
    public Object build(HL7MetaData metaData, EntityKey entityKey,
            PersonTriggerEvent personTriggerEvent) throws BuilderException
    {
        if ((metaData == null) || (metaData.getEntity() == null)
                || !(metaData.getEntity() instanceof Person)
                || personTriggerEvent == null)
        {
            throw new BuilderException(
                    "Invalid input parameter to build a segment");
        }

        PersonTriggerIdentity personTriggerIdentity = (PersonTriggerIdentity) personTriggerEvent
                .getTriggerIdentity();
        PersonTrigger.DataType dataType = (PersonTrigger.DataType) personTriggerIdentity
                .getApplicableDataTypes().iterator().next();

        ZGD segment = new ZGD();
        //Sequence 1
        segment.setSetID("1");

        Person person = (Person) metaData.getEntity();
        
        if (dataType == PersonTrigger.DataType.GUARDIAN_INFO)
        {
            if(entityKey == null)
            {
                throw new BuilderException(
                "Entity key for association needed to build a ORUZ05 segment");
            }
            Association association = person.getAssociationByEntityKey(entityKey);
            
            if (association != null)
            {
                setDefaultValues(segment);
                
                //Sequence 2
                segment.setGuardianType(super.build(guardianTypeBuilder, association.getType()));

                //As per CR 5339, Guardian will only have the org name which will be populated in ZGD-3. 
                //ZGD-4 will never be populated
                //Sequence 3
                segment.setGuardianName(association.getOrganizationName());
                
                segment.setGuardianInstitution(StringUtils.EMPTY);
                
                //Sequence 5
                segment.setGuardianRelationship(association.getRelationship());
                //Sequence 6
                segment.setGuardianAddress(ElementFormatter
                        .formatAddress(association.getAddress()));
                //Sequence 7
                segment.setGuardianPhoneNumber(association.getPrimaryPhone());

                //Sequence 8
                IncompetenceRuling incompetenceRuling = person
                        .getIncompetenceRuling();
                if (incompetenceRuling != null)
                {
                    if (AssociationType.CODE_GUARDIAN_CIVIL.getName().equals(
                            association.getType().getCode()))
                    {
                        segment.setIncompetentRuledDate(DateFormatter
                                .formatDate(incompetenceRuling
                                        .getCivilRulingDate()));
                    } else if (AssociationType.CODE_GUARDIAN_VA.getName()
                            .equals(association.getType().getCode()))
                    {
                        segment.setIncompetentRuledDate(DateFormatter
                                .formatDate(incompetenceRuling
                                        .getVaRulingDate()));
                    }
                }
            }
        }
        return segment;
    }
    
    protected void setDefaultValues(Segment segment) 
    {
        ZGD zgd = (ZGD) segment;

        zgd.setGuardianType(SegmentConstants.DEFAULT_VALUE);
        zgd.setGuardianName(SegmentConstants.DEFAULT_VALUE);
        zgd.setGuardianInstitution(SegmentConstants.DEFAULT_VALUE);
        zgd.setGuardianRelationship(SegmentConstants.DEFAULT_VALUE);
        zgd.setGuardianAddress(SegmentConstants.DEFAULT_VALUE);
        zgd.setIncompetentRuledDate(SegmentConstants.DEFAULT_VALUE);
    }
}