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

import gov.va.med.cds.ars.exception.ValidationException;
import gov.va.med.cds.ars.requestresponse.generated.GeographicalAreaVendorPatientMaxNumberOfDaysDataType;
import gov.va.med.cds.ars.requestresponse.generated.RRTotalNonRespMaxReportDataType;
import gov.va.med.cds.ars.requestresponse.generated.RRTotalNonRespMaxReportFilterType;
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.VendorPatientMaxNumberOfDaysDataType;
import gov.va.med.cds.exception.PersistenceException;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.datatype.XMLGregorianCalendar;

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

public class CensusRrTotalNonRespMaxRportPersistenceManager extends AbstractReadableReportsPersistenceManager 
	implements ReadableReportsPersistenceManagerInterface {
	
	protected String censusRrTotalNonRespMaxRportQuery;
		
	@Override
	public HTResponseType performReadReportAggregate(
			HTReportFilterType aReportFilter) throws PersistenceException, ValidationException {
		
		RRTotalNonRespMaxReportFilterType filter = aReportFilter.getRRTotalNonRespMaxReportFilter();

		XMLGregorianCalendar xmlStartDate = filter.getStartDate();
		XMLGregorianCalendar xmlEndDate = filter.getEndDate();
		
		java.sql.Date sqlStartDate = formatDate(xmlStartDate);
		java.sql.Date sqlEndDate = formatDate(xmlEndDate);
		Session aSession = this.sessionFactory.getCurrentSession();
		
		List<CensusPatientCountDataType> results = null;
		
		try {
			Query query = aSession.getNamedQuery( censusRrTotalNonRespMaxRportQuery );
			
				String location  = filter.getGeographicalArea().getLocation();
				String vendor = filter.getVendor();
			    query.setDate("startDate", sqlStartDate);
			    query.setDate("endDate", sqlEndDate);
			    query.setString( "geographicalArea", location );
			    query.setString( "vendor", vendor );
			
			    if ( LOGGER.isDebugEnabled() )
			    {
			        LOGGER.debug("========== Calling CensusRRTotalNonRespMaxRportQuery query procedure: " + censusRrTotalNonRespMaxRportQuery + " ======"  );
			        LOGGER.debug( " CensusRRTotalNonRespMaxRport   startDate: '" + sqlStartDate  + "'");
			        LOGGER.debug( " CensusRRTotalNonRespMaxRport   endDate: '" + sqlEndDate + "'");
			        LOGGER.debug( " CensusRRTotalNonRespMaxRport   geographicalArea location: '" + location + "'");
			        LOGGER.debug( " CensusRRTotalNonRespMaxRport   vendor: '" + vendor + "'");
			    }
			    
			     results = (List<CensusPatientCountDataType>)queryForReportData(query);			    
		} finally{ 
			if( aSession != null){
				aSession.close();
			}
		}
		
		List <GeographicalAreaVendorPatientMaxNumberOfDaysDataType>  listData = null;
		listData = transformDataProcess(results);
		RRTotalNonRespMaxReportDataType data = new RRTotalNonRespMaxReportDataType();
		data.getGeographicalAreaData().addAll(listData);
		data.setReportID(filter.getReportID());
	
	    responseType.setRRTotalNonRespMaxReportData(data);
		
		return responseType;
		
	}

	public void setcensusRrTotalNonRespMaxRportQuery(
			String acensusRrTotalNonRespMaxRportQuery){
		this.censusRrTotalNonRespMaxRportQuery = acensusRrTotalNonRespMaxRportQuery;
	}
	
	private static List <GeographicalAreaVendorPatientMaxNumberOfDaysDataType> transformDataProcess ( List<CensusPatientCountDataType> dbResults){
		ArrayList <GeographicalAreaVendorPatientMaxNumberOfDaysDataType> transformData = new ArrayList <GeographicalAreaVendorPatientMaxNumberOfDaysDataType>();
		
		TreeMap <String, GeographicalAreaVendorPatientMaxNumberOfDaysDataType.Vendors> treeMap = new TreeMap<String, GeographicalAreaVendorPatientMaxNumberOfDaysDataType.Vendors>();
		
		int count;
		String number, name , location;
		GeographicalAreaVendorPatientMaxNumberOfDaysDataType.Vendors vendors = null;
		VendorPatientMaxNumberOfDaysDataType vendorPatientMaxNumberOfDaysCount= null;
				
		for (CensusPatientCountDataType dbResult: dbResults)
		{
			location = dbResult.location;
			number = dbResult.number;
			name = dbResult.name;
			count = dbResult.count.intValue();
			
			if (!treeMap.containsKey(location)){
				vendors = new GeographicalAreaVendorPatientMaxNumberOfDaysDataType.Vendors();
				treeMap.put(location, vendors);
			}
			else
			{
				vendors = treeMap.get(location);
			}
			vendorPatientMaxNumberOfDaysCount = new VendorPatientMaxNumberOfDaysDataType();
			vendorPatientMaxNumberOfDaysCount.setMaxNumberOfDays(count);
			vendorPatientMaxNumberOfDaysCount.setName(name);
			vendorPatientMaxNumberOfDaysCount.setNumber(number);
			vendors.getVendor().add(vendorPatientMaxNumberOfDaysCount);
		}
		
		GeographicalAreaVendorPatientMaxNumberOfDaysDataType geoType ;
		
		for (Map.Entry<String, GeographicalAreaVendorPatientMaxNumberOfDaysDataType.Vendors> entry : treeMap.entrySet()){
			String key = entry.getKey();
			vendors = entry.getValue();
			geoType = new GeographicalAreaVendorPatientMaxNumberOfDaysDataType();
			geoType.setLocation(key);
			geoType.setVendors(vendors);
			transformData.add(geoType);
		}
		
		return transformData;
	}

}
