package org.ofbiz.extended;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericPK;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.condition.EntityConditionList;
import org.ofbiz.entity.condition.EntityExpr;
import org.ofbiz.entity.condition.EntityOperator;
import org.ofbiz.opentravelsystem.DateInterval;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.ServiceUtil;

public class HotelServices {
	public static final String PARTNERSHIP_RELATIONSHIP = "PARTNERSHIP";
	public static final String HOTEL_PARTY_TYPE_ID = "HOTEL";
	/**
	 * @param ctx
	 * @param context
	 * @return a List of hotels that belong the a specified party
	 * @throws GenericEntityException 
	 */
	public static Map getHotelList(DispatchContext ctx, Map context) throws GenericEntityException {
		GenericDelegator delegator = ctx.getDelegator();
		Map returnMap = ServiceUtil.returnSuccess();
		String partyId = (String) context.get("partyId");
		List partyList = new ArrayList();
		
		
		GenericValue party = delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", partyId));
		String partyType = party.getString("partyTypeId");
		if(partyType.equals(HOTEL_PARTY_TYPE_ID)){
			partyList.add(partyId);
		}
		else{
			List relatedHotels;
			if(partyId.equalsIgnoreCase("admin")){
				relatedHotels = delegator.findAll("Hotel");
				for(Iterator it = relatedHotels.iterator();it.hasNext();){
					partyList.add((String) ((GenericValue)it.next()).getString("partyId"));
				}
			} else{
				relatedHotels = delegator.findByAnd("PartyRelationship", UtilMisc.toMap("partyIdFrom", partyId, "partyRelationshipTypeId", PARTNERSHIP_RELATIONSHIP));
				for(Iterator it = relatedHotels.iterator();it.hasNext();){
					partyList.add((String) ((GenericValue)it.next()).getString("partyIdTo"));
				}
			}
			
		}
		
		
		returnMap.put("hotelPartyList", partyList);
		return returnMap;
	}
	
	
	/**
	 * @param ctx
	 *	* List of Hotel partyIds
	 *  * reservationStartDateInterval
	 *  * reservationEndDateInterval
	 *
	 * @param context
	 * @return A list of reservations for a specified hotel
	 */
	public static Map getReservationsForHotelList(DispatchContext dctx, Map context) {
		try {
			List mainCondList = new ArrayList();
			// //UtilMisc.toList(new EntityExpr("statusId",
			// EntityOperator.EQUALS, "ITEM_COMPLETED"));
			//
			List conditionList = new ArrayList();
			conditionList.add(new EntityExpr("statusId", EntityOperator.EQUALS, "ITEM_CREATED"));
			conditionList.add(new EntityExpr("statusId", EntityOperator.EQUALS, "ITEM_APPROVED"));
			conditionList.add(new EntityExpr("statusId", EntityOperator.EQUALS, "ITEM_COMPLETED"));
			EntityCondition ec = new EntityConditionList(conditionList, EntityOperator.OR);
			mainCondList.add(ec);

			DateInterval reservationStartInterval = (DateInterval) context.get("reservationStartInterval");
			DateInterval reservationEndInterval = (DateInterval) context.get("reservationEndInterval");

			if (reservationStartInterval != null) {
				if (reservationStartInterval.begin != null) {
					mainCondList.add(new EntityExpr("estimatedStartDate", EntityOperator.GREATER_THAN_EQUAL_TO,
							new Timestamp(reservationStartInterval.begin.getTime())));
				}
				if (reservationStartInterval.end != null) {
					mainCondList.add(new EntityExpr("estimatedStartDate", EntityOperator.LESS_THAN_EQUAL_TO,
							new Timestamp(reservationStartInterval.end.getTime())));
				}
			}
			if (reservationEndInterval != null) {
				if (reservationEndInterval.begin != null) {
					mainCondList.add(new EntityExpr("estimatedCompletionDate", EntityOperator.GREATER_THAN_EQUAL_TO,
							new Timestamp(reservationEndInterval.begin.getTime())));
				}
				if (reservationEndInterval.end != null) {
					mainCondList.add(new EntityExpr("estimatedCompletionDate", EntityOperator.LESS_THAN_EQUAL_TO,
							new Timestamp(reservationEndInterval.end.getTime())));
				}
			}
			
			List partyList = (List) context.get("partyList");
			if(partyList.size() == 0){
				Map resultMap = ServiceUtil.returnSuccess();
				resultMap.put("reservationsList", new ArrayList());
				return resultMap;
			}
			
			List manufacturerConditionList = new ArrayList();
				for (int i = 0; i < partyList.size(); i++) {
				String partyId = (String) partyList.get(i);
				manufacturerConditionList.add(new EntityExpr("manufacturerPartyId", EntityOperator.EQUALS, partyId));
			}
			mainCondList.add(new EntityConditionList(manufacturerConditionList, EntityOperator.OR));
			
			EntityCondition mainCond = new EntityConditionList(mainCondList,
					EntityOperator.AND);
			List ordersList = dctx.getDelegator().findByCondition("orders_manufacturer_outer_join", mainCond,
					null, null);
			
			Map resultMap = ServiceUtil.returnSuccess();
			resultMap.put("reservationsList", ordersList);
			return resultMap;
		}
		catch(Exception e){
			List errorList = new ArrayList();
			return ServiceUtil.returnError(errorList);
		}
		

//		    if (minDate_start != null && minDate_start.length() > 8) {
//	            minDate_start = minDate_start.trim();
//	            Debug.logInfo(":minDate_start:" + minDate_start, module);
//	            if (minDate_start.length() < 14) minDate_start = minDate_start + " " + "00:00:00.000";
//	            paramList = paramList + "&minDate_start=" + minDate_start;
//	            mainCondList.add(new EntityExpr("estimatedStartDate",
//	            		EntityOperator.GREATER_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(minDate_start, "Timestamp", null, null)));
//	            
//	            //andExprs.add(new EntityExpr("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(minDate_start, "Timestamp", null, null)));
//	        }
//	        if (maxDate_start != null && maxDate_start.length() > 8) {
//	            maxDate_start = maxDate_start.trim();
//	            if (maxDate_start.length() < 14) maxDate_start = maxDate_start + " " + "23:59:59.999";
//	            paramList = paramList + "&maxDate_start=" + maxDate_start;
//	            mainCondList.add(new EntityExpr("estimatedStartDate",
//	            		EntityOperator.LESS_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(maxDate_start, "Timestamp", null, null)));
//	            
//	            //andExprs.add(new EntityExpr("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(maxDate_start, "Timestamp", null, null)));
//	        }
//	        
//	        if (minDate_end != null && minDate_end.length() > 8) {
//	            minDate_end = minDate_end.trim();
//	            Debug.logInfo(":minDate_end:" + minDate_end, module);
//	            if (minDate_end.length() < 14) minDate_end = minDate_end + " " + "00:00:00.000";
//	            paramList = paramList + "&minDate_end=" + minDate_end;
//	            mainCondList.add(new EntityExpr("estimatedCompletionDate",
//	            		EntityOperator.GREATER_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(minDate_end, "Timestamp", null, null)));
//	            
//	            //andExprs.add(new EntityExpr("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(minDate_end, "Timestamp", null, null)));
//	        }
//	        if (maxDate_end != null && maxDate_end.length() > 8) {
//	            maxDate_end = maxDate_end.trim();
//	            if (maxDate_end.length() < 14) maxDate_end = maxDate_end + " " + "23:59:59.999";
//	            paramList = paramList + "&maxDate_end=" + maxDate_end;
//	            mainCondList.add(new EntityExpr("estimatedCompletionDate",
//	            		EntityOperator.LESS_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(maxDate_end, "Timestamp", null, null)));
//	            
//	            //andExprs.add(new EntityExpr("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, ObjectType.simpleTypeConvert(maxDate_end, "Timestamp", null, null)));
//	        }
//		}
//		
//		//mainCondList.add(new EntityExpr("entryDate",
//				//EntityOperator.GREATER_THAN_EQUAL_TO, someTimeAgo));
//		EntityCondition mainCond = new EntityConditionList(mainCondList,
//				EntityOperator.AND);
//		
//		ordersList = delegator.findByCondition("orders_manufacturer_outer_join", mainCond,
//				null, null);
//		
//		
//		
//		
		
		
		
		
		
		
	}
	
	
	/**
	 * @param ctx
	 * @param context
	 * @return a List of hotels that belong the a specified party
	 * @throws GenericEntityException 
	 */
	public static Map updateFixedAssetAvailability(DispatchContext ctx, Map context) throws GenericEntityException {
		GenericDelegator delegator = ctx.getDelegator();
		Map returnMap = ServiceUtil.returnSuccess();
		
		String fixedAssetId = (String) context.get("fixedAssetId");
		String calendarId = (String) context.get("calendarId");
		Date dateLastServiced = (Date) context.get("dateLastServiced");
		Date dateNextService = (Date) context.get("dateNextService");
		Double productionCapacity = (Double) context.get("productionCapacity");
		
		System.out.println("fixedAssetId " + fixedAssetId);
		System.out.println("calendarId " + calendarId);
		System.out.println("dateLastServiced " + dateLastServiced);
		System.out.println("dateNextService " + dateNextService);
		System.out.println("productionCapacity " + productionCapacity);
		
		Calendar calIterator = Calendar.getInstance();
			calIterator.setTime(dateLastServiced);
			calIterator.set(Calendar.HOUR,0);
			calIterator.set(Calendar.MINUTE,0);
			calIterator.set(Calendar.SECOND,0);
			calIterator.set(Calendar.MILLISECOND,0);
		
		Calendar limit = Calendar.getInstance();
			limit.setTime(dateNextService);
			limit.set(Calendar.HOUR,0);
			limit.set(Calendar.MINUTE,0);
			limit.set(Calendar.SECOND,0);
			limit.set(Calendar.MILLISECOND,0);
		
		List values = new ArrayList();
		if(calendarId == null || calendarId.length() == 0){
			//check if fixedAsset has one calendar. If not create it
			GenericValue fixedAsset = delegator.findByPrimaryKey(
					"FixedAsset", UtilMisc.toMap("fixedAssetId",
							fixedAssetId));
			String fixedAssetCalendarId = fixedAsset.getString("calendarId");
			if(fixedAssetCalendarId == null || fixedAssetCalendarId.length() == 0){
//				create the new Calendar
				GenericValue calendar = delegator.makeValue("TechDataCalendar", null);
				
				calendar.set("calendarId", fixedAssetId);
				calendar.set("description", "calendar for " + fixedAssetId);
				values.add(calendar);
				calendarId = calendar.getString("calendarId");
				fixedAsset.setString("calendarId", calendarId);
				values.add(fixedAsset);
			}
		}
		
		
		while(!calIterator.after(limit)){
			Timestamp exceptionDateStartTime = new Timestamp(calIterator.getTimeInMillis());
			
			GenericValue calendarRow = delegator.findByPrimaryKey(
					"TechDataCalendarExcDay", UtilMisc.toMap("calendarId",
							calendarId, "exceptionDateStartTime",
							exceptionDateStartTime));
			if(calendarRow == null){
				calendarRow = delegator.makeValue("TechDataCalendarExcDay", null);
				calendarRow.set("calendarId", calendarId);
				calendarRow.set("exceptionDateStartTime", exceptionDateStartTime);
				calendarRow.set("usedCapacity", new Double(0));
			} 
			
			calendarRow.set("exceptionCapacity", productionCapacity);
			values.add(calendarRow);
			
			calIterator.add(Calendar.DATE, 1);
		}
		delegator.storeAll(values);
		

		return returnMap;
	}
	
}
