

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


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;


public class HAMoodJournalBuilder
    extends
        AbstractEntryPointBuilder
{
    private int index;
    private static final String[] moods = { "Love", "Sad", "Depressed", "Jealous", "Greed", "Grumpy", "Anxiety", "Hopeful", "Angry", "Happy", "Fear" };
    private static final String[] worldTimezoneOffsets = { "+0000", "+0100", "+0200", "+0300", "+0330", "+0400", "+0430", "+0500", "+0530", "+0600", "+0630", "+0700", "+0800", "+0900", "+0930",
                    "+1000", "+1100", "+1200", "-1100", "-1000", "-0930", "-0900", "-0830", "-0800", "-0700", "-0600", "-0500", "-0400", "-0330", "-0300", "-0200", "-0100" };
    private String recordIdentifier;
    private String updatedMood;
    private String attachmentName;


    public HAMoodJournalBuilder( )
    {
        super();
    }


    public HAMoodJournalBuilder( String attachmentName )
    {
        super();
        this.attachmentName = attachmentName;
    }


    public HAMoodJournalBuilder( String recordIdentifier, String updatedMood, String attachmentName )
    {
        super();
        this.recordIdentifier = recordIdentifier;
        this.updatedMood = updatedMood;
        this.attachmentName = attachmentName;
    }


    public List<Element> makeJournalEntries( int number )
    {
        return makeJournalEntries( number, null );
    }


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


    public List<Element> makeJournalEntries( int number, Element patient, boolean updateRecordXml )
    {
        List<Element> journalEntry = new ArrayList<Element>( number );
        for ( int i = 0; i < number; i++ )
        {
            journalEntry.add( makeJournalEntry( "patientjournaling:patientEnteredMoodJournalEntry", patient, updateRecordXml ) );
        }

        return journalEntry;
    }


    @Override
    public Element createEntryPointRecord( Element personIdentifier )
    {
        return makeJournalEntry( "PatientJournalEntry", personIdentifier );
    }


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


    /*
     *  <xsd:complexType name="MoodJournalEntry">
     *    <xsd:all>
     *	    <xsd:element name="mood" type="xsd:string"/>
     *	    <xsd:element name="genericJournalEntryDetails" type="patientjournaling:BasicJournalEntry"/>
     *	  </xsd:all>
     *  </xsd:complexType>
     * <xsd:complexType name="BasicJournalEntry">
     *	<xsd:all>
     *		<xsd:element name="patient" type="common:PatientLite"/>
     *		<xsd:element name="journalEntryType" type="xsd:anyType"/>
     *		<xsd:element name="allowAccessByClinicalStaff" type="xsd:boolean" default="true"/>
     *		<xsd:element name="comments" type="xsd:string" minOccurs="0"/>
     *		<xsd:element name="observationDate" type="basedatatypes:PointInTime"/>
     *		<xsd:element name="dataEnterer" type="xsd:string" minOccurs="0"/>
     *	</xsd:all>
     * </xsd:complexType>
     */
    public Element makeJournalEntry( String elementName, Element patientIdentifier, boolean updateRecordXml )
    {
        index++ ;
        Element newPatientJournalEntry = DocumentHelper.createElement( elementName );
        //newPatientJournalEntry.add(patientJournalingNS);
        //Attribute moodJournalEntryAttr = DocumentHelper.createAttribute(newPatientJournalEntry, "xsi:type", "PatientJournaling:MoodJournalEntry");
        //newPatientJournalEntry.add(moodJournalEntryAttr);
        newPatientJournalEntry.add( createSimpleStringElement( "mood", updateRecordXml ? updatedMood : getRandomMood() ) );
        newPatientJournalEntry.add( createGenericJournalEntryDetails( "genericJournalEntryDetails", patientIdentifier, index, updateRecordXml, getDateTodayWithRandomTimezoneOffset(),
                        recordIdentifier, null ) );
        return newPatientJournalEntry;
    }


    public Element makeMoodJournalEntry( Element patientIdentifier, int countObservations, boolean updateRecordXml )
    {
        Element patientJournalEntries = DocumentHelper.createElement( "patientJournalEntries" );
        List<Element> patientJournalEntryList = makeJournalEntries( countObservations, patientIdentifier, updateRecordXml );
        for ( Element patientJournalEntry : patientJournalEntryList )
        {
            patientJournalEntries.add( patientJournalEntry );
        }

        return patientJournalEntries;
    }


    public static String getDateTodayWithRandomTimezoneOffset( )
    {
        String date = new SimpleDateFormat( "yyyyMMddHHmmss" ).format( new Date() );
        return date += getRandomXsTimezoneOffset();
    }


    public static String getRandomXsTimezoneOffset( )
    {
        int index = ( int )Math.round( Math.random() * ( worldTimezoneOffsets.length - 1 ) );
        return worldTimezoneOffsets[index];
    }


    private String getRandomMood( )
    {
        int index = ( int )Math.round( Math.random() * ( moods.length - 1 ) );
        return moods[index];
    }


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

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

        return returnString;
    }


    //TODO - integrate this method back into the AbstractEntryPointBuilder when it stabilizes
    @Override
    protected Element createGenericJournalEntryDetails( String elementName, Element patientIdentifier, int index, boolean updateRecordXml, String xsdDateString, String recordIdentifier,
                    String attachmentName )
    {
        Element genericJournalEntryDetailsElement = DocumentHelper.createElement( elementName );

        Element newPatient = createPatientLite( "patient" );
        if ( patientIdentifier != null )
        {
            newPatient.element( "identifier" ).element( "identity" ).setText( patientIdentifier.elementText( "identity" ) );
            newPatient.element( "identifier" ).element( "assigningFacility" ).setText( ASSIGNING_FACILITY_HDR );
            newPatient.element( "identifier" ).element( "assigningAuthority" ).setText( ASSIGNINGAUTHORITY_HDR );
        }
        genericJournalEntryDetailsElement.add( newPatient );

        if ( updateRecordXml )
        {
            Element newRecordIdentifier = createHL72EntityIdentifier( "recordIdentifier", recordIdentifier /*index*/);
            genericJournalEntryDetailsElement.add( newRecordIdentifier );
        }

        genericJournalEntryDetailsElement.addElement( "journalEntryType" ).addText( "JournalEntryType" );

        genericJournalEntryDetailsElement.addElement( "allowAccessByClinicalStaff" ).addText( "false" );

        genericJournalEntryDetailsElement.addElement( "comments" ).addText( "Comments" );

        /// convert from xs:date value if set, otherwise default to fixed point in time date
        Element newObservationDate = xsdDateString == null || xsdDateString.trim().equals( "" ) ? createFixedPointInTime( "observationDate" ) : createPointInTime( "observationDate", xsdDateString );

        genericJournalEntryDetailsElement.add( newObservationDate );

        Element binaryAttachmentsElement = createBase64BinaryAttachmentsElement( this.attachmentName );

        genericJournalEntryDetailsElement.add( binaryAttachmentsElement );

        genericJournalEntryDetailsElement.addElement( "dataEnterer" ).addText( "DataEnterer" );

        return genericJournalEntryDetailsElement;
    }
}
