/**
 * @filename Service.java
 * @project  ofbiz-accounting 
 * @class    org.ofbiz.creditcard3ds
 * @date     8/Mar/2006 11:37:23
 * @author   nelson.santos 
 */
package org.ofbiz.creditcard3ds;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.ofbiz.accounting.payment.PaymentGatewayServices;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.entity.GenericDelegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericEntityNotFoundException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.order.order.OrderChangeHelper;
import org.ofbiz.order.order.OrderReadHelper;
import org.ofbiz.order.shoppingcart.ShoppingCart;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;

/**
 * @author nelson.santos
 *
 */
public class Adapter3DS {
	public final static String module = Adapter3DS.class.getName();
	static String resource_error = "opentravelsystemErrorUiLabels";
	
	public static Map getAuthenticationFormData(DispatchContext ctx, Map context) {
		
		GenericDelegator delegator = ctx.getDelegator();

		ShoppingCart cart = (ShoppingCart) context.get("shoppingCart");
		String orderId = cart.getOrderId();
		
		GenericValue orderHeader = null;
		try {
            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
            if(orderHeader == null || !orderHeader.getString("statusId").equals("ORDER_CREATED")){
            	String message = UtilProperties.getMessage(resource_error,"OrderAlreadySubmited", (Locale) context.get("locale"));
            	Debug.logError(message, module);
            	return ServiceUtil.returnError(message);
            }
        } catch (GenericEntityException gee) {
            Debug.logError(gee, "Problems getting the order information", module);
            return ServiceUtil.returnError("Problems getting the order information");
        }
        OrderReadHelper orh = new OrderReadHelper(orderHeader);
        
		String cardNumber = (String) context.get("cardNumber");
		String expMonth = (String) context.get("expMonth");
		String expYear = (String) context.get("expYear");
		String cvv = (String) context.get("cardSecurityCode");
		String urlPrefix = (String) context.get("urlPrefix");
	
		String formattedExpDate = expYear+expMonth;
		
		Map map = new HashMap();
	    	
        return map;
		
		
    }
	
	public static String processCallBack(HttpServletRequest request, HttpServletResponse response) {
		LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
		GenericDelegator delegator = dispatcher.getDelegator();
		
		HttpSession session = request.getSession();
        ShoppingCart cart = (ShoppingCart) session.getAttribute("shoppingCart");
		String orderId = cart.getOrderId();

        GenericValue orderHeader = null;
        try {
            orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
            if(null==orderHeader)
                throw new GenericEntityNotFoundException("Unknown Order Id:"+orderId);
            OrderReadHelper orh = new OrderReadHelper(orderHeader);
    		
            BigDecimal amount = new BigDecimal(""+orh.getOrderGrandTotal());
            
            String ofbizCurrency = orh.getCurrency();
            String currency = ofbizCurrency;
            
            GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
            try {
				if(ofbizCurrency.equalsIgnoreCase("EUR")){
					currency = "9782";
				}
	            else{
					throw new InternalException("currency not supported");
				}
				
	            
	            List acceptablePaymentReferences = new ArrayList();
	            acceptablePaymentReferences.add(orderId);
	            
	         
	            
    		} catch (InternalException e) {
				OrderChangeHelper.cancelOrder(dispatcher, userLogin, orderId);
				String errorMsg = UtilProperties.getMessage(resource_error,"authentication.internalError", request.getLocale());
				request.setAttribute("_ERROR_MESSAGE_", errorMsg);
    			return "error";
			}
            
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return "error";
        }
        
		/*
		 * compatibility code
		 */
        request.setAttribute("order_id", orderId);
        request.setAttribute("orderId", orderId);
        request.setAttribute("orderAdditionalEmails", cart.getOrderAdditionalEmails());
        
		return "success";
	}
	
	public static Map ccAuth(DispatchContext dctx, Map context) {
        Double processAmount = (Double) context.get("processAmount");
        if (processAmount == null){
        	Map result =  ServiceUtil.returnFailure("Error processing payment. processAmount = null");
        	//result.put("authMessage", "Error processing payment. processAmount = null");
	        result.put("customerRespMsgs", UtilMisc.toList("Error processing payment. processAmount = null"));
            result.put("authResult", null);
            return result;
        }
        
       
			Map result = new HashMap();

			GenericValue orderPaymentPreference = (GenericValue) context
					.get("orderPaymentPreference");
			
			String paymentReference;
			try {
				paymentReference = orderPaymentPreference.getRelatedOne("OrderHeader").getString("orderId");
			} catch (GenericEntityException e) {
				Map errorResult = ServiceUtil.returnError(e.getMessage());
				errorResult.put("authResultMsgs", "D");
				Debug.logError(e, module);
				return ServiceUtil.returnError(e.getMessage());
				
			}
			
			Double contextAmount = (Double) context.get("processAmount");
			BigDecimal amount = new BigDecimal(contextAmount.doubleValue());
	        
	        
	        String ofbizCurrency = (String) context.get("currency");
            String currency = ofbizCurrency;

            if (ofbizCurrency.equalsIgnoreCase("EUR")) {
				currency = "9782";
			} else {
				return ServiceUtil.returnError("currency not supported");
			}
	        
			result.put("authDate", new Date().toString());
			result.put("authResult", new Boolean(true));
			result.put("processAmount", contextAmount);
			result.put("authRefNum", ""+ new Date().getTime());
		    result.put("authAltRefNum", null);
		    result.put("authFlag", "X");
		        
		        
		    result.put("authMessage", new Date().toString());
		    result.put("internalRespMsgs", UtilMisc.toList("2"));
		    result.put("customerRespMsgs", UtilMisc.toList("3."));
			return result;
    }

	public static Map ccCapture(DispatchContext dctx, Map context) {
	    Double processAmount = (Double) context.get("captureAmount");
	    Debug.logInfo("amount to capture: " + processAmount, module);
        if (processAmount == null){
        	Debug.logError("I don't know whta's the capture amount", module);
        	Map result = new HashMap();
        	result.put("authMessage", "Error processing payment. processAmount = null");
	        result.put("internalRespMsgs", UtilMisc.toList("Error processing payment. processAmount = null"));
            result.put("authResult", null);
            return result;
        }
        
			Map result = new HashMap();

			GenericValue orderPaymentPreference = (GenericValue) context
					.get("orderPaymentPreference");
			
			Double contextAmount = (Double) context.get("captureAmount");
			BigDecimal amount = new BigDecimal(contextAmount.doubleValue());
	        
	       
	        String ofbizCurrency = (String) context.get("currency");
			String currency = ofbizCurrency;

			if (ofbizCurrency.equalsIgnoreCase("EUR")) {
				currency = "9782";
			} else {
				return ServiceUtil.returnError("currency not supported");
			}
			
	        
			GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference);
			
			String authDate = authTransaction.getString("gatewayMessage");
		



			result.put("captureResult", new Boolean(true));
			result.put("captureAmount", contextAmount);
			result.put("captureRefNum", "" + new Date().getTime());
			result.put("captureMessage",
							"This is a test processor; no payments were captured or authorized.");
			result.put(
							"internalRespMsgs",
							UtilMisc
									.toList("This is a test processor; no payments were captured or authorized."));
			return result;
	
	}
	
	

	/**
	 * @deprecated
	 * @param request
	 * @param response
	 * @return
	 */
	public static String setup3DSPayment(HttpServletRequest request, HttpServletResponse response){
		request.setAttribute("paymentMethodId", request.getParameter("paymentMethodId"));
		return "success";
	}
	

}
