

package gov.va.med.cds.ars.persistence;


import gov.va.med.cds.ars.filter.StatusInterface;
import gov.va.med.cds.ars.requestresponse.generated.HTBaseGeographicalAreaDateReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.HTBaseReportType;
import gov.va.med.cds.ars.requestresponse.generated.HTReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.HTResponseType;
import gov.va.med.cds.ars.requestresponse.generated.PSLocationReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.PSReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.PSReportFilterType;
import gov.va.med.cds.ars.requestresponse.generated.PsSurveyQuestionType;
import gov.va.med.cds.exception.PersistenceException;

import java.sql.Date;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;


public class SatisfactionReportsPersistenceManager
    extends
        AbstractReadableReportsPersistenceManager
    implements
        ReadableReportsPersistenceManagerInterface
{
    protected String satisfactionQuery = "SurveyReports.patientSatisfaction";
    protected String acceptedSurveyCountQuery = "SurveyReports.countSurveys";
    

    @Override
    public HTResponseType performReadReportAggregate( HTReportFilterType aReportFilter )
        throws PersistenceException
    {
    	PSReportFilterType filter = aReportFilter.getPatientSatisfactionReportFilter();
        PSReportDataType data = new PSReportDataType();
        Session session = this.sessionFactory.getCurrentSession();
                
        try
        {
            List<PSLocationReportDataType> results = null;
            Integer surveyCount = null;
            
            results = patientSatisfactionReport( session, filter );
            surveyCount = getAcceptedSurveyCount( session, filter);

            data.getReportData().addAll( results );
            data.setNumberOfRecordsConsidered( surveyCount );
            data.setReportID( filter.getReportID() );
        }
        finally
        {
            session.close();
        }
        
        responseType.setPatientSatisfactionReportData( data );
        
        return responseType;
    }
    

    @SuppressWarnings( "unchecked" )
    private List<PSLocationReportDataType> patientSatisfactionReport( Session aSession, PSReportFilterType aPSReportFilter )
        throws PersistenceException
    {
        StringBuilder questions = new StringBuilder();
        PSReportFilterType.ReportQuestions reportQuestions = aPSReportFilter.getReportQuestions();
        
        if ( reportQuestions == null )
        {
        	// use all questions
        	// ideally just let the stored procedure include them all
        	// may need to do if there's ever another version of the survey
        	questions.append( "1,2,3,4,5,6,7,8" );
        }
        else
        {
        	// build string from list of questions
	        List<PsSurveyQuestionType> questionList = reportQuestions.getReportQuestion();
	        
	        for ( PsSurveyQuestionType psSurveyQuestionType : questionList )
	        {
	            questions.append( psSurveyQuestionType.getPsQuestionNumber() );
	            questions.append( "," );
	        }
	        questions.deleteCharAt( questions.length() -1 );  // remove last comma
        }
        
        String surveyVersion = aPSReportFilter.getSurveyVersion();
        String location = aPSReportFilter.getGeographicalArea().getLocation();
        Date startDate = formatDate( aPSReportFilter.getStartDate() );
        Date endDate = formatDate( aPSReportFilter.getEndDate() );

        Query query = aSession.getNamedQuery( satisfactionQuery );
        query.setString( "surveyVersion", surveyVersion );
        query.setString( "questions", questions.toString() );
        query.setString( "location", location );
        query.setDate( "startDate", startDate );
        query.setDate( "endDate", endDate );
                
        if ( LOGGER.isDebugEnabled() )
        {
            LOGGER.debug("+++++ Calling Patient Satisfaction stored proc: *****(  " + satisfactionQuery + "  )*****" );
            LOGGER.debug( " version: " + surveyVersion );
            LOGGER.debug( " questions: " + questions );
            LOGGER.debug( " location: " + location );
            LOGGER.debug( " startDate: " + startDate );
            LOGGER.debug( " endDate: " + endDate );
        }
        
        List<PSLocationReportDataType> results = ( List<PSLocationReportDataType> )queryForReportData( query );
        
        if ( LOGGER.isDebugEnabled() )
        {
            LOGGER.debug( "----- Done with Patient Statisfaction stored proc" );
        }

        return results;
    }
    

    @SuppressWarnings( "unchecked" )
    protected Integer getAcceptedSurveyCount( Session aSession, HTBaseGeographicalAreaDateReportFilterType aReportFilter )
    {
        String surveyVersion = aReportFilter.getSurveyVersion();
        String surveyType = aReportFilter.getSurveyType() == null ? null : aReportFilter.getSurveyType().value();
        String location = aReportFilter.getGeographicalArea().getLocation();
        Date startDate = formatDate( aReportFilter.getStartDate() );
        Date endDate = formatDate( aReportFilter.getEndDate() );
        
        Query query = aSession.getNamedQuery( acceptedSurveyCountQuery );
        query.setString( "surveyVersion", surveyVersion );
        query.setString( "surveyType", surveyType );
        query.setString( "location", location );
        query.setString( "acceptedStatus", StatusInterface.STATUS_ACCEPTED );
        query.setDate( "startDate", startDate );
        query.setDate( "endDate", endDate );
        
        if ( LOGGER.isDebugEnabled() )
        {
            LOGGER.debug( "+++++ Calling Count Surveys stored proc: *****(  " + acceptedSurveyCountQuery + "  )*****" );
            LOGGER.debug( " surveyVersion: " + surveyVersion );
            LOGGER.debug( " surveyType: " + surveyType );
            LOGGER.debug( " location: " + location );
            LOGGER.debug( " acceptedStatus: " + StatusInterface.STATUS_ACCEPTED );
            LOGGER.debug( " startDate: " + startDate );
            LOGGER.debug( " endDate: " + endDate );
        }
        
        List<HTBaseReportType> results = null;
        Integer count = null;

        try
        {
            results = query.list();
            
            if ( LOGGER.isDebugEnabled() )
            {
                LOGGER.debug( "Count result size: " + results.size() );
//                for ( Object object : results )
//                {
//                    LOGGER.debug( object.getClass().getName() + " *** " + object );
//                }
            }
            
            if ( ( results != null ) && ( results.size() > 0 ) && ( results.get( 0 ) instanceof HTBaseReportType ) )
            {
                count = ( (HTBaseReportType)results.get( 0 ) ).getNumberOfRecordsConsidered();
            }
        }
        catch ( HibernateException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw e;
        }
        
        if ( LOGGER.isDebugEnabled() )
        {
            LOGGER.debug( "----- Done with Count Surveys stored proc" );
        }

        return count;
    }


    public void setSatisfactionQuery( String aSatisfactionQuery )
    {
        this.satisfactionQuery = aSatisfactionQuery;
    }


    public void setAcceptedSurveyCountQuery( String aAcceptedSurveyCountQuery )
    {
        this.acceptedSurveyCountQuery = aAcceptedSurveyCountQuery;
    }

}

