

package gov.va.med.cds.testharness.vhim400.builders;


import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


public class HAAssessmentDocumentBuilder
    extends
        AbstractEntryPointBuilder
{
    protected static Log logger = null;
    public static final String LOGGER_CONFIG_PATH = "log4j.properties";
    protected static String ASSIGNINGAUTHORITY_HDR = "USDOD";
    private static final int RECORD_VERSION = 12345;
    
    private String recordIdentifierIdentity;
    protected boolean isCDATA=false;
    private int IDX;

    public HAAssessmentDocumentBuilder()
    {
    	super();
    }

    public HAAssessmentDocumentBuilder( Random random )
    {
        super( random );
    }
    
    public HAAssessmentDocumentBuilder( String recordIdentifierIdentity )
    {
        super();
        this.recordIdentifierIdentity = recordIdentifierIdentity;
    }
    
    public HAAssessmentDocumentBuilder( String recordIdentifierIdentity, boolean isCDATA )
    {
        super();
        this.recordIdentifierIdentity = recordIdentifierIdentity;
        this.isCDATA = isCDATA;
    }
    
    public HAAssessmentDocumentBuilder( boolean isCDATA)
    {
        super();
        this.isCDATA = isCDATA;
    }
    
    
    public List<Element> makeDocuments( int number )
    {
        return makeDocuments( number, null );
    }


    public List<Element> makeDocuments( int number, Element patient )
    {
        return makeDocuments( number, patient, true );
    }


    public List<Element> makeDocuments( int number, Element patient, boolean updateRecordXml )
    {
        List<Element> assessmentDocuments = new ArrayList<Element>( number );
        for ( int i = 0; i < number; i++ )
        {
            assessmentDocuments.add( makeAssessmentDocument( "assessmentDocument", patient, updateRecordXml ) );
        }

        return assessmentDocuments;
    }
    

    @Override
    public Element createEntryPointRecord( Element personIdentifier )
    {
        return makeAssessmentDocument( "questionnaireResult", personIdentifier );
    }


    public Element makeAssessmentDocument( String elementName, Element patientIdentifier )
    {
        return makeAssessmentDocument( elementName, patientIdentifier, false );
    }


    /*
     	<?xml version="1.0" encoding="UTF-8"?>
            <xsd:schema xmlns:basedatatypes="Basedatatypes" xmlns:common="Common" xmlns:assessments="Assessments" xmlns:vitasigns="Vitalsigns" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="Assessments">
            <xsd:import namespace="Basedatatypes" schemaLocation="Basedatatypes.xsd"/>
            <xsd:import namespace="Common" schemaLocation="Common.xsd"/>
                <xsd:complexType name="AssessmentDocument">
                    <xsd:all>
                        <xsd:element name="patient" type="common:PatientLite"/>
                        <xsd:element name="category" type="xsd:string"/>
                        <xsd:element name="categoryVersion" type="xsd:string" minOccurs="0"/>
                        <xsd:element name="userId" type="xsd:string" minOccurs="0"/>
                        <xsd:element name="assessmentDateTime" type="basedatatypes:PointInTime"/>
                        <xsd:element name="assessmentScore" type="xsd:integer" minOccurs="0"/>
                        <xsd:element name="assessmentResponses" type="xsd:string"/>
                        <xsd:element name="recordIdentifier" type="basedatatypes:HL72EntityIdentifier"/>
                        <xsd:element name="recordUpdateTime" type="basedatatypes:PointInTime" minOccurs="0"/>
                        <xsd:element name="recordVersion" type="xsd:integer" minOccurs="0"/>
                        <xsd:element name="allowAccessByClinicalStaff" type="xsd:boolean" default="true"/>
                    </xsd:all>
                </xsd:complexType>
            </xsd:schema>
     */
    public Element makeAssessmentDocument( String elementName, Element patientIdentifier, boolean updateRecordXml )
    {
        IDX++ ;

        Element assessmentDocument = DocumentHelper.createElement( elementName );
        Element patient = null;
        
        if ( patientIdentifier != null )
        {
            patient = createPatientLite( "patient" );
            patient.element( "identifier" ).element( "identity" ).setText( patientIdentifier.elementText( "identity" ) );
            patient.element( "identifier" ).element( "assigningFacility" ).setText( patientIdentifier.elementText( "assigningFacility" ) );
            patient.element( "identifier" ).element( "assigningAuthority" ).setText( patientIdentifier.elementText( "assigningAuthority" ) );
        }

        assessmentDocument.add( patient );
        
        String updatedText="";
        String assessmentScore="1";
        if(updateRecordXml){
            updatedText="UPDATED ";
            assessmentScore="10";
        }
        assessmentDocument.addElement( "category" ).addText(updatedText+"Category Text" );
        assessmentDocument.addElement( "categoryVersion" ).addText( updatedText+"Category Version" );
        assessmentDocument.addElement( "dataEnterer" ).addText( "Data Enterer" );
        
        Element dateCreated = createFixedPointInTime("assessmentDateTime");
        assessmentDocument.add(dateCreated);
        
        assessmentDocument.addElement( "assessmentScore" ).addText( assessmentScore );
        
        Element assessmentResponses = assessmentDocument.addElement( "assessmentResponses" );
        
        if(isCDATA)
        {
            assessmentResponses.add(DocumentHelper.createCDATA("<xml>HeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8JbzlpaiHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8JbzlpaiHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8JbzlpaiHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8JbzlpaiHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpairy6XhA_t4QE9KsIMVBx32PSUNmfjwHeuDGvgkCZWnOqd-5RY1Foc7T0L8Jbzlpai01</xml>"));
        }
        else
        {
            try {
               //assessmentResponses.add(DocumentHelper.parseText("<xmlData>First Assessment Response<question>Describe your pain throughout the day.><response>It is mild early, becoming severe as the day progresses into eveing</response></question></xmlData>").getRootElement());
               assessmentResponses.add(DocumentHelper.parseText(buildEmbeddedAssessmentResponsesXml()).getRootElement());            
            } catch (DocumentException e) {
                throw new RuntimeException("Error parsing test XML data.", e);
            }
        }
               
        if ( updateRecordXml )
        {
            if ( this.recordIdentifierIdentity != null )
            {
                assessmentDocument.add( createHL72EntityIdentifier( "recordIdentifier", this.recordIdentifierIdentity ) );
            }
            else
            {
                assessmentDocument.add( createHL72EntityIdentifier( "recordIdentifier", IDX ) );
            }

        }
        
        assessmentDocument.addElement( "allowAccessByClinicalStaff" ).addText( "true" );
        
       
        return assessmentDocument;
    }
    
       
     public Element makeAssessmentDocuments( Element patientIdentifier, int countObservations, boolean updateRecordXml )
     {
         Element assessmentDocuments = DocumentHelper.createElement( "assessmentDocuments" );
         List<Element> assessmentDocumentList = makeDocuments( countObservations, patientIdentifier, updateRecordXml );
         for ( Element assessmentDocument : assessmentDocumentList )
         {
             assessmentDocuments.add( assessmentDocument );
         }
    
         return assessmentDocuments;
    }

    public Element makeAssessmentDocuments( String elementName, String recordIdentifier, String recordStatus )
    {
        Element assessmentDocuments = DocumentHelper.createElement(elementName );
        Element assessementDocument = DocumentHelper.createElement( "assessmentDocument" );
        Element newRecordIdentifier = createHL72EntityIdentifier( "recordIdentifier", recordIdentifier );
        assessementDocument.add( newRecordIdentifier );

        assessementDocument.addElement( "recordStatus" ).addText( recordStatus );
        assessmentDocuments.add( assessementDocument );

        return assessmentDocuments;

    }

    //TODO add print methods

    public String fillPrintBuffer( Object object )
    {
        String returnString = "";

        if ( ( object != null ) && ( object instanceof Element ) )
        {
            returnString = ( ( Element )object ).asXML();
        }

        return returnString;
    }
    
    protected String buildEmbeddedAssessmentResponsesXml(){
        
        String embeddedXml =  "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
         "<ns3:assessmentResponses xmlns:ns2=\"http://www.w3.org/2005/Atom\" xmlns:ns3=\"http://healthcare.agilex.com/mobilehealthplatform\" size=\"12\">" +
         "<object-type>AssessmentResponses</object-type>"+
         "<ns3:response>"+
         "<question>"+
         "<object-type>AssessmentQuestion</object-type>"+
         "<id>Q1</id>"+
         "<questionNumber>1</questionNumber>"+
         "<type>MULTI_OPTION_SINGLE_RESPONSE</type>"+
         "<prompt>Indicate how often you have felt the following in the past week: Because of the time you spend with your Veteran, you don't have enough time for yourself.</prompt>"+
         "<questionProperty>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>toolRecommendationText</name>"+
         "<value>DUMMY TOOL Q1</value>"+
         "</questionProperty>"+
         "</question>"+       
         "<assessmentQuestionChoice>"+
         "<object-type>AssessmentQuestionChoice</object-type>"+
         "<property>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>displayText</name>"+
         "<value>Never</value>"+
         "</property>"+
         "<property>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>pointValue</name>"+
         "<value>1</value>"+
         "</property>"+
         "</assessmentQuestionChoice>"+
         "</ns3:response>"+        
         "<ns3:response>"+
         "<question>"+
         "<object-type>AssessmentQuestion</object-type>"+
         "<id>Q6</id>"+
         "<questionNumber>6</questionNumber>"+
         "<type>MULTI_OPTION_SINGLE_RESPONSE</type>"+
         "<prompt>Indicate how often you have felt the following in the past week: Your health has suffered because of your involvement in caring for your Veteran.</prompt>"+
         "<questionProperty>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>toolRecommendationText</name>"+
         "<value>DUMMY TOOL Q6</value>"+
         "</questionProperty>"+
         "</question>"+
         "<assessmentQuestionChoice>"+
         "<object-type>AssessmentQuestionChoice</object-type>"+
         "<property>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>displayText</name>"+
         "<value>Never</value>"+
         "</property>"+
         "<property>"+
         "<object-type>AssessmentProperty</object-type>"+
         "<name>pointValue</name>"+
         "<value>1</value>"+
         "</property>"+
         "</assessmentQuestionChoice>"+
         "</ns3:response>"+
         "</ns3:assessmentResponses>";      
        return embeddedXml;
    }

}
