package gov.va.med.esr.common.report.data.impl;

import gov.va.med.esr.common.model.lookup.ReportFacilityDisplayBy;
import gov.va.med.esr.common.model.lookup.ReportFormat;
import gov.va.med.esr.common.model.report.ReportEnrollmentStatusComponent;
import gov.va.med.esr.common.model.report.ReportParameterSet;
import gov.va.med.esr.common.model.report.ReportPersonMergeStatus;
import gov.va.med.esr.common.model.report.ReportSetup;
import gov.va.med.esr.common.model.report.ReportUser;
import gov.va.med.esr.common.report.data.CommonCriteria;
import gov.va.med.esr.common.report.data.StandardReportCriteria;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.report.ReportConfiguration;
import gov.va.med.fw.report.data.QueryCriteria;
import gov.va.med.fw.report.data.ReportDataException;
import gov.va.med.fw.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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

public class EED12ReportDataDAOImpl extends AbstractStandardReportDataDAOImpl {

    private static final long serialVersionUID = 7521588029497083337L;

    public void preDataRetrieval( ReportConfiguration config ) throws ReportDataException {
	      
	      QueryCriteria reportCriteria = config.getQueryCriteria();
		  StandardReportCriteria criteria = (StandardReportCriteria)reportCriteria;
		  ReportSetup setup = criteria.getReportSetup();
		  ReportParameterSet parameters = setup.getParameterSet();
			
	      if( reportCriteria instanceof StandardReportCriteria ) {
	         criteria.setStartDate( this.getDate( config, true ) );
	         criteria.setEndDate( this.getDate( config, false ) );
	         
	            //Optional fields for Detailed report
          if (ReportFormat.DETAIL.getName().equals(parameters.getReportFormat().getCode())){
      		
              Set personMergeStatuses = parameters.getPersonMergeStatuses();
              Iterator iter = personMergeStatuses.iterator();
              while (iter.hasNext()) {
              	ReportPersonMergeStatus comp = (ReportPersonMergeStatus)iter.next();
              	String code = comp.getPersonMergeStatus().getCode();
              	criteria.addCriterion("personMergeStatuses" + code, "Y");
              }
              
          }
	      }
    }
    
    protected Query buildQuery( ReportConfiguration config, Session session ) throws ReportDataException {
        
        QueryCriteria reportCriteria = config.getQueryCriteria();
        Query query = null;

        if( reportCriteria instanceof StandardReportCriteria ) {

            // Get a named query
            query = this.getNamedQuery( session );
            
            // Get a criteria
            StandardReportCriteria criteria = (StandardReportCriteria)reportCriteria;
            ReportSetup setup = criteria.getReportSetup();
            ReportParameterSet parameters = setup != null ? setup.getParameterSet() : null;
            if( parameters == null ) {
                throw new ReportDataException("Missing report parameters in report " + config.getReportID() );
            }

            Date startDate = parameters.getFromDate();
            if(startDate == null) {
                throw new ReportDataException( "Missing Start Date in report " + config.getReportID() );
            }
            
            Date endDate = parameters.getToDate();
            if(endDate == null) {
                throw new ReportDataException( "Missing End Date in report " + config.getReportID() );
            }
            
            query.setDate(CommonCriteria.START_DATE, startDate);
            query.setDate(CommonCriteria.END_DATE,endDate);
            
            //Optional fields for Detailed report
            if (ReportFormat.DETAIL.getName().equals(parameters.getReportFormat().getCode())){
                Set personMergeStatuses = parameters.getPersonMergeStatuses();
                Iterator iter = personMergeStatuses.iterator();
                ArrayList listComps = new ArrayList();
                while (iter.hasNext()) {
                	ReportPersonMergeStatus comp = (ReportPersonMergeStatus)iter.next();
                	String code = comp.getPersonMergeStatus().getCode();
                	listComps.add(code);
                }
                if (listComps.isEmpty()) {
                	listComps.add("");
                }
                query.setParameterList("personMergeStatuses", listComps);
            }
            
            Set reportUsers = parameters.getUsers();
            
            if (reportUsers != null && reportUsers.isEmpty()==false) {
            	List userIds = new ArrayList();
            	
            	Iterator iter = reportUsers.iterator();
            	while(iter.hasNext()) {
            		ReportUser reportuser = (ReportUser)iter.next();
            		String userId = reportuser.getUser().getUserCredentials().getUserID();
            		userIds.add(userId);
            	}
            	if (userIds.isEmpty()) {
            		userIds.add("");
            	}
            	query.setParameterList("recordModifiedBy", userIds);
            	query.setString(CommonCriteria.IS_ALL,"notAll");
            }
            else {
            	List userIds = new ArrayList();
            	userIds.add("");
            	query.setParameterList("recordModifiedBy", userIds);
            	query.setString(CommonCriteria.IS_ALL,"all");
            }
        }
        return query;
    }
    
}
