package org.ofbiz.accounting.tax;

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

import org.ofbiz.base.util.Debug;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
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.entity.util.EntityUtil;

public class TaxServicesHelper {
	private static final String module = TaxServicesHelper.class.getName();
	
	GenericDelegator delegator;
	
	public TaxServicesHelper() {
	}
	public TaxServicesHelper(GenericDelegator delegator) {
		this.delegator = delegator;
	}
	
	//GenericValue product, BigDecimal itemPrice, BigDecimal itemAmount,
	public BigDecimal calcAdjustmentForItemList(List items,  String productStoreId, BigDecimal taxRate) throws TaxServicesException{
		BigDecimal totalAmount = new BigDecimal("0");
		
		for(Iterator itemIter = items.iterator();itemIter.hasNext();){
			Item item = (Item) itemIter.next();
			BigDecimal itemLineTotal = item.getAmount();
			totalAmount = totalAmount.add(itemLineTotal);
		}
		BigDecimal ratePlus1 = taxRate.add(new BigDecimal("1"));
		BigDecimal parcel = totalAmount.divide(ratePlus1,2, BigDecimal.ROUND_HALF_UP);
		BigDecimal adjustment = totalAmount.subtract(parcel);
		adjustment = adjustment.setScale(2, BigDecimal.ROUND_HALF_UP);
		return adjustment;
	}
	
	public BigDecimal getTaxForItem(GenericValue product, String productStoreId) throws TaxServicesException{
		String taxCategoryId = product.getString("taxCategory");
		String productId = product.getString("productId");
		
		EntityCondition storeCond = new EntityExpr("productStoreId", EntityOperator.EQUALS, productStoreId);
		
//		List countryExprs = UtilMisc.toList(new EntityExpr("countryGeoId", EntityOperator.EQUALS, countryCode), new EntityExpr("countryGeoId", EntityOperator.EQUALS, "_NA_"));
//		EntityCondition countryCond = new EntityConditionList(countryExprs, EntityOperator.OR);
		EntityCondition countryCond = new EntityExpr("countryGeoId", EntityOperator.EQUALS, "_NA_");
		
		//build the main condition clause
		EntityCondition categoryCond = new EntityExpr("taxCategory", EntityOperator.EQUALS, taxCategoryId);
		 
		List mainExprs = new ArrayList();
		mainExprs.add(storeCond);
		mainExprs.add(countryCond);
		mainExprs.add(categoryCond);
		
        EntityCondition mainCondition = new EntityConditionList(mainExprs, EntityOperator.AND);
        
		try {
			List lookupList = delegator.findByCondition("SimpleSalesTaxLookup", mainCondition, null, null);
			List filteredList = EntityUtil.filterByDate(lookupList);
			if(filteredList.isEmpty()){
				String errorMsg = "TaxCalc: No tax found for product " + productId + " Don't know what to do";
                Debug.logWarning(errorMsg, module);
                Debug.logVerbose("cond:"+mainExprs+".", module);
                //Debug.logVerbose("store:"++";country:"++";tax:"++".", module);
				throw new TaxServicesException(errorMsg);
			}
			if(filteredList.size() > 1){
				String errorMsg = "TaxCalc: More than 1 tax found for product " + productId + " Don't know what to do";
				Debug.logWarning(errorMsg, module);
				throw new TaxServicesException(errorMsg);
			}
			
			GenericValue taxLookup = (GenericValue) filteredList.get(0);
			BigDecimal taxRate = new BigDecimal(taxLookup.getString("salesTaxPercentage"));
			return taxRate;
		} catch (GenericEntityException e) {
			Debug.logError(e, module);
			throw new TaxServicesException(e);
		}
	}

	
	public GenericValue getOrderAdjustment(BigDecimal taxAmount, BigDecimal taxRate){
		GenericValue adjValue = delegator.makeValue("OrderIncludedAdjustment", null);
		adjValue.set("amount", taxAmount);
        adjValue.set("sourcePercentage", taxRate);
        adjValue.set("orderAdjustmentTypeId", "INCLUDED_TAX");
		return adjValue;
	}
	
	public GenericValue createItemAdjustment(BigDecimal taxRate) {
		GenericValue adjValue = delegator.makeValue("OrderIncludedAdjustment", null);
		//adjValue.set("amount", taxAmount);
        adjValue.set("sourcePercentage", taxRate);
        adjValue.set("orderAdjustmentTypeId", "INCLUDED_ITEM_TAX");
        return adjValue;
	}
	

	

    

	
}
