package org.ofbiz.accounting.tax;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.ofbiz.base.util.Debug;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.ServiceUtil;

public class TaxServices {
	
	private static String module = TaxServices.class.getName();

	public static Map calcTaxAdjustmentsByTaxRate(DispatchContext ctx, Map context) throws TaxServicesException{
		GenericDelegator delegator = ctx.getDelegator();
		String productStoreId = (String) context.get("productStoreId");
		List itemProductList = (List) context.get("itemProductList");
		List itemAmountList = (List) context.get("itemAmountList");
		List itemPriceList = (List) context.get("itemPriceList");
//		List itemShippingList = (List) context.get("itemShippingList");
		
		List orderAdjustments = new ArrayList();
		List itemAdjustments = new ArrayList(itemProductList.size());
		
		TaxServicesHelper taxServicesHelper = new TaxServicesHelper(delegator);
		
		//map whose key is a product rate and value a list of prices
		Map prices = new HashMap();
		for (int i = 0; i < itemProductList.size(); i++) {
			GenericValue product = (GenericValue) itemProductList.get(i);
			
			Boolean isTaxable = product.getBoolean("taxable");
			if(isTaxable.booleanValue()){
	            BigDecimal itemAmount = (BigDecimal) itemAmountList.get(i);
	            BigDecimal itemPrice = (BigDecimal) itemPriceList.get(i);
				
				BigDecimal taxRate = taxServicesHelper.getTaxForItem(product, productStoreId);
				
				List priceListForRate = (List) prices.get(taxRate);
				if(priceListForRate == null  ){
					priceListForRate = new ArrayList();
					prices.put(taxRate, priceListForRate);
				}
				priceListForRate.add(new Item(product, itemPrice, itemAmount));
				
				//add item adjustment
				itemAdjustments.add(i, taxServicesHelper.createItemAdjustment(taxRate));
			}
			else{
//				add item adjustment
				itemAdjustments.add(i, null);//sorry
			}
		}
		
		

		for (Iterator it = prices.keySet().iterator(); it.hasNext();) {
			BigDecimal taxRate = (BigDecimal) it.next();
			List items = (List) prices.get(taxRate);
			BigDecimal adjustmentValue = taxServicesHelper.calcAdjustmentForItemList(items, productStoreId, taxRate);
			GenericValue orderAdjustment = taxServicesHelper.getOrderAdjustment(adjustmentValue, taxRate);
			
			orderAdjustments.add(orderAdjustment);
		}

		Map result = ServiceUtil.returnSuccess();
		result.put("orderAdjustments", orderAdjustments);
		result.put("itemAdjustments", itemAdjustments);

		return result;
	}
	
	public static Map cancelTaxAdjustments(DispatchContext dctx, Map context){
		GenericDelegator delegator = dctx.getDelegator();
		String orderId = (String) context.get("orderId");
		
		try {
			IncludedAdjustmentsHelper includedAdjustmentsHelper = new IncludedAdjustmentsHelper(dctx.getDelegator(), orderId, null);
			List toStore = new ArrayList();
			
			/*clear each order tax adjustment */
			List orderTaxAdjustments = includedAdjustmentsHelper.getOrderTaxAdjustments();
			Iterator it = orderTaxAdjustments.iterator();
			while (it.hasNext()) {
				GenericValue orderTaxAdjustment = (GenericValue) it.next();
				orderTaxAdjustment.set("amount", new BigDecimal("0.00"));
				toStore.add(orderTaxAdjustment);
			}
			
			/*clear item tax adjustments*/
			List itemTaxAdjustments = includedAdjustmentsHelper.getItemTaxAdjustments();
			it = itemTaxAdjustments.iterator();
			while (it.hasNext()) {
				GenericValue itemTaxAdjustment = (GenericValue) it.next();
				itemTaxAdjustment.set("amount", new BigDecimal("0.00"));
				toStore.add(itemTaxAdjustment);
			}
			
			delegator.storeAll(toStore);
			
		} catch (Exception e) {
			Debug.logError(e, "Unable to clear reservations from Calendar - Order: " + orderId, module );
			return ServiceUtil.returnError(e.getMessage());
		}
		
		
		return ServiceUtil.returnSuccess();
	}
	
	
}
