/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.apache.ofbiz.webpos;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.order.shoppingcart.ShoppingCart;
import org.apache.ofbiz.order.shoppingcart.ShoppingCartEvents;
import org.apache.ofbiz.order.shoppinglist.ShoppingListEvents;
import org.apache.ofbiz.product.product.ProductWorker;
import org.apache.ofbiz.product.store.ProductStoreWorker;
import org.apache.ofbiz.securityext.login.LoginEvents;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;
import org.apache.ofbiz.webpos.session.WebPosSession;
import org.apache.ofbiz.service.ServiceUtil;

public class WebPosEvents {

    private static final String MODULE = WebPosEvents.class.getName();

    public static String posLogin(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        HttpSession session = request.getSession(true);

        // get the posTerminalId
        String posTerminalId = request.getParameter("posTerminalId");
        session.removeAttribute("shoppingCart");
        session.removeAttribute("webPosSession");
        WebPosSession webPosSession = WebPosEvents.getWebPosSession(request, posTerminalId);
        String responseString = LoginEvents.storeLogin(request, response);
        GenericValue userLoginNew = (GenericValue) session.getAttribute("userLogin");

        if (userLoginNew != null && UtilValidate.isNotEmpty(posTerminalId)) {
            webPosSession.setUserLogin(userLoginNew);
        }
        return responseString;
    }

    public static String existsWebPosSession(HttpServletRequest request, HttpServletResponse response) {
        String responseString = "success";
        HttpSession session = request.getSession(true);
        WebPosSession webPosSession = (WebPosSession) session.getAttribute("webPosSession");

        if (UtilValidate.isEmpty(webPosSession)) {
            responseString = "error";
        }
        return responseString;
    }

    public static WebPosSession getWebPosSession(HttpServletRequest request, String posTerminalId) {
        HttpSession session = request.getSession(true);
        GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
        WebPosSession webPosSession = (WebPosSession) session.getAttribute("webPosSession");
        ShoppingCart cart = (ShoppingCart) session.getAttribute("shoppingCart");
        Delegator delegator = (Delegator) request.getAttribute("delegator");
        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");

        if (UtilValidate.isEmpty(webPosSession)) {
            String productStoreId = ProductStoreWorker.getProductStoreId(request);
            GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
            String facilityId = null;
            String currencyUomId = request.getParameter("currencyUomId");

            if (productStore != null) {
                facilityId = productStore.getString("inventoryFacilityId");
                if (UtilValidate.isEmpty(currencyUomId)) {
                    currencyUomId = productStore.getString("defaultCurrencyUomId");
                }
            }

            if (userLogin != null) {
                session.setAttribute("userLogin", userLogin);
            }

            if (UtilValidate.isEmpty(cart)) {
                cart = new ShoppingCart(delegator, productStoreId, request.getLocale(), currencyUomId);
                session.setAttribute("shoppingCart", cart);
            }

            if (UtilValidate.isNotEmpty(posTerminalId)) {
                webPosSession = new WebPosSession(posTerminalId, null, userLogin, request.getLocale(), productStoreId, facilityId, currencyUomId,
                        delegator, dispatcher, cart);
                session.setAttribute("webPosSession", webPosSession);
            } else {
                Debug.logError("PosTerminalId is empty cannot create a webPosSession", MODULE);
            }
        }
        return webPosSession;
    }

    public static void removeWebPosSession(HttpServletRequest request, String posTerminalId) {
        HttpSession session = request.getSession(true);
        session.removeAttribute("shoppingCart");
        session.removeAttribute("webPosSession");
        getWebPosSession(request, posTerminalId);
    }

    public static String completeSale(HttpServletRequest request, HttpServletResponse response) throws GeneralException {
        HttpSession session = request.getSession(true);
        WebPosSession webPosSession = (WebPosSession) session.getAttribute("webPosSession");
        if (UtilValidate.isNotEmpty(webPosSession)) {
            webPosSession.getCurrentTransaction().processSale();
            emptyCartAndClearAutoSaveList(request, response);
            String posTerminalId = webPosSession.getId();
            removeWebPosSession(request, posTerminalId);
        }
        return "success";
    }

    public static String emptyCartAndClearAutoSaveList(HttpServletRequest request, HttpServletResponse response) throws GeneralException {
        HttpSession session = request.getSession(true);
        WebPosSession webPosSession = (WebPosSession) session.getAttribute("webPosSession");
        ShoppingCartEvents.clearCart(request, response);

        if (UtilValidate.isNotEmpty(webPosSession)) {
            String autoSaveListId = ShoppingListEvents.getAutoSaveListId(webPosSession.getDelegator(), webPosSession.getDispatcher(), null,
                    webPosSession.getUserLogin(), webPosSession.getProductStoreId());
            ShoppingListEvents.clearListInfo(webPosSession.getDelegator(), autoSaveListId);
        }
        return "success";
    }
    public static String getProductType(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> featureMap = null;
        Map<String, Object> variantTreeMap = null;
        Map<String, Object> featureTypes = new HashMap<>();
        WebPosSession webPosSession = getWebPosSession(request, null);
        if (webPosSession != null) {
            Delegator delegator = webPosSession.getDelegator();
            LocalDispatcher dispatcher = webPosSession.getDispatcher();
            GenericValue product = null;
            try {
                String productId = request.getParameter("productId");
                product = EntityQuery.use(delegator).from("Product").where("productId", productId).queryOne();
                if (product != null) {
                    request.setAttribute("product", product);
                    if (UtilValidate.isNotEmpty(product.getString("isVirtual")) && "Y".equalsIgnoreCase(product.getString("isVirtual"))) {
                        String virtualVariantMethodEnum = product.getString("virtualVariantMethodEnum");
                        if (UtilValidate.isEmpty(virtualVariantMethodEnum)) {
                            virtualVariantMethodEnum = "VV_VARIANTTREE";
                        }
                        if ("VV_VARIANTTREE".equalsIgnoreCase(virtualVariantMethodEnum)) {
                            String productStoreId = webPosSession.getProductStoreId();
                            try {
                                featureMap = dispatcher.runSync("getProductFeatureSet", UtilMisc.toMap("productId", productId));
                                if (ServiceUtil.isError(featureMap)) {
                                    String errorMessage = ServiceUtil.getErrorMessage(featureMap);
                                    request.setAttribute("_ERROR_MESSAGE_", errorMessage);
                                    Debug.logError(errorMessage, MODULE);
                                    return "error";
                                }
                                Set<String> featureSet = UtilGenerics.cast(featureMap.get("featureSet"));
                                if (UtilValidate.isNotEmpty(featureSet)) {
                                    request.setAttribute("featureSet", featureSet);
                                    try {
                                        variantTreeMap = dispatcher.runSync("getProductVariantTree",
                                                UtilMisc.toMap("productId", productId, "featureOrder", featureSet, "productStoreId", productStoreId));
                                        if (ServiceUtil.isError(variantTreeMap)) {
                                            String errorMessage = ServiceUtil.getErrorMessage(variantTreeMap);
                                            request.setAttribute("_ERROR_MESSAGE_", errorMessage);
                                            Debug.logError(errorMessage, MODULE);
                                            return "error";
                                        }
                                        Map<String, Object> variantTree = UtilGenerics.cast(variantTreeMap.get("variantTree"));
                                        if (UtilValidate.isNotEmpty(variantTree)) {
                                            request.setAttribute("variantTree", variantTree);
                                            request.setAttribute("variantTreeSize", variantTree.size());
                                            List<String> featureOrder = new LinkedList<>(featureSet);
                                            for (int i = 0; i < featureOrder.size(); i++) {
                                                String featureKey = featureOrder.get(i);
                                                GenericValue featureValue = EntityQuery.use(delegator).from("ProductFeatureType").where(
                                                        "productFeatureTypeId", featureOrder.get(i)).cache().queryOne();
                                                if (featureValue != null
                                                        && UtilValidate.isNotEmpty(featureValue.get("description"))) {
                                                    featureTypes.put(featureKey, featureValue.get("description"));
                                                } else {
                                                    featureTypes.put(featureKey, featureValue.get("productFeatureTypeId"));
                                                }
                                            }
                                            request.setAttribute("featureTypes", featureTypes);
                                            request.setAttribute("featureOrder", featureOrder);
                                            if (UtilValidate.isNotEmpty(featureOrder)) {
                                                request.setAttribute("featureOrderFirst", featureOrder.get(0));
                                            }
                                        }
                                        Map<String, Object> imageMap = UtilGenerics.cast(variantTreeMap.get("variantSample"));
                                        if (UtilValidate.isNotEmpty(imageMap)) {
                                            List<String> variantSampleList = new LinkedList<>();
                                            variantSampleList = new LinkedList<>(imageMap.keySet());
                                            request.setAttribute("variantSample", imageMap);
                                            request.setAttribute("variantSampleList", variantSampleList);
                                            request.setAttribute("variantSampleSize", imageMap.size());
                                        }
                                    } catch (GenericServiceException e) {
                                        Debug.logError(e, MODULE);
                                        return "error";
                                    }
                                }
                            } catch (GenericServiceException e) {
                                Debug.logError(e, MODULE);
                                return "error";
                            }
                        }
                        if ("VV_FEATURETREE".equalsIgnoreCase(virtualVariantMethodEnum)) {
                            request.setAttribute("featureLists", ProductWorker.getSelectableProductFeaturesByTypesAndSeq(product));
                        }
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, MODULE);
                return "error";
            }
        }
        return "success";
    }
}