package com.freemud.sdk.api.assortment.shoppingcart.adapter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ProductAttributeValueType;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductRequest;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateShopProductType;
import com.freemud.application.sdk.api.productcenter.request.product.valid.ValidateSkuProductType;
import com.freemud.sdk.api.assortment.shoppingcart.constant.*;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoods;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoodsStates;
import com.freemud.sdk.api.assortment.shoppingcart.exception.ServiceException;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.request.GetProductInfoRequest;
import com.freemud.sdk.api.assortment.shoppingcart.util.ShoppingSdkLogUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: ShoppingCartAdapter
 * @Package com.freemud.sdk.api.assortment.shoppingcart.adapter
 * @Description:
 * @author: yuhao.chi
 * @date: 2019/4/10 15:02
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */
@Component
public class ShoppingCartAdapter {
    private static final String ATTRIBUTEID = "attributeId";
    private static final String ATTRIBUTENAME = "attributeName";
    private static final String ATTRIBUTEFOREIGNNAME = "attributeForeignName";

    public GetProductInfoRequest convertGetProductInfoRequest(String partnerId, String storeId, List<String> goodsIds, String trackingNo) {
        GetProductInfoRequest request = new GetProductInfoRequest();
        request.setPartnerId(partnerId);
        request.setStoreId(storeId);
        request.setGoodsIds(goodsIds);
        request.setTrackingNo(trackingNo);
        return request;
    }

    public ValidateShopProductRequest getValidateShopProductRequest(CheckCartRequest checkCartRequest) {
        ValidateShopProductRequest validateShopProductRequest = new ValidateShopProductRequest();
        validateShopProductRequest.setChannel(checkCartRequest.getMenuType());
        validateShopProductRequest.setPartnerId(checkCartRequest.getPartnerId());
        validateShopProductRequest.setStoreId(checkCartRequest.getStoreId());
        validateShopProductRequest.setProductTypeList(new ArrayList<>());
        for (CartGoods cartGoods : checkCartRequest.getCartGoodsList()) {
            // 过滤非商品券商品
            if (cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX) || StringUtils.isNotBlank(cartGoods.getCouponCode())) {
                continue;
            }
            ValidateShopProductType productType = new ValidateShopProductType();
            productType.setSpuId(cartGoods.getSpuId());
            productType.setSkuId(ObjectUtils.equals(GoodsTypeEnum.SKU_GOODS.getGoodsType(), cartGoods.getGoodsType()) ? cartGoods.getSkuId() : cartGoods.getSpuId());
            // 应产品要求
            // 普通商品，取商品的finalePrice(普通商品售价);套餐商品，取originalPrice(套餐价格)
            productType.setPrice(cartGoods.getFinalPrice() == null ? 0 : cartGoods.getFinalPrice().intValue());
            productType.setValidatePrice(productType.getPrice() == 0 ? 0 : 1);
            productType.setValidateAttribute(1);
            productType.setValidateStatuses(Arrays.asList(2));
            productType.setUuid(cartGoods.getCartGoodsUid());
            //属性
            productType.setAttributeList(getAttributes(cartGoods.getExtra()));
            //可选搭配&固定搭配
            productType.setComboProductTypeList(getValidateSkuProductType(cartGoods.getProductComboList()));
            productType.setProductGroupTypeList(getValidateSkuProductType(cartGoods.getProductGroupList()));
            productType.setMemberDiscount(cartGoods.getMemberDiscount());
            validateShopProductRequest.getProductTypeList().add(productType);
        }
        ShoppingSdkLogUtil.infoLog("替换购物车数据检验结果 01 --> validateShopProductRequest:{} cartGoodsList:{}", validateShopProductRequest, JSON.toJSON(checkCartRequest.getCartGoodsList()));
        return validateShopProductRequest;
    }

    public List<ProductAttributeValueType> getAttributes(List<CartGoods.CartGoodsExtra> extra) {
        List<ProductAttributeValueType> attributeValueTypes = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(extra)) {
            for (CartGoods.CartGoodsExtra cartGoodsExtra : extra) {
                ProductAttributeValueType productAttributeValueType = new ProductAttributeValueType();
                productAttributeValueType.setAttributeId(cartGoodsExtra.getAttributeId());
                productAttributeValueType.setAttributeValue(cartGoodsExtra.getAttributeName());
                productAttributeValueType.setForeignAttributeValue(cartGoodsExtra.getAttributeForeignName());
                attributeValueTypes.add(productAttributeValueType);
            }
        }
        return attributeValueTypes;
    }

    public List<ValidateSkuProductType> getValidateSkuProductType(List<CartGoods.ComboxGoods> productComboList) {
        List<ValidateSkuProductType> result = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(productComboList)) {
            for (CartGoods.ComboxGoods comboxGoods : productComboList) {
                ValidateSkuProductType validateSkuProductType = new ValidateSkuProductType();
                validateSkuProductType.setProductId(comboxGoods.getGoodsId());
                validateSkuProductType.setPrice(comboxGoods.getOriginalPrice() == null ? 0 : comboxGoods.getOriginalPrice().intValue());
                validateSkuProductType.setMarkUpPrice(comboxGoods.getFinalPrice() == null ? 0 : comboxGoods.getFinalPrice().intValue());
                validateSkuProductType.setQty(comboxGoods.getQty());
                validateSkuProductType.setAttributeList(getAttributes(comboxGoods.getExtra()));
                validateSkuProductType.setProductGroupId(comboxGoods.getProductGroupId());
                result.add(validateSkuProductType);
            }
        }
        return result;
    }

    public GetProductInfoRequest convertGetProductInfoRequest(CheckCartRequest checkCartRequest) {
        //获取goodsId集合，包含套餐内的固定商品和可选商品
        List<List<CartGoods.ComboxGoods>> productGroupLists = checkCartRequest.getCartGoodsList().stream().filter(goods -> CollectionUtils.isNotEmpty(goods.getProductGroupList())).map(CartGoods::getProductGroupList).collect(Collectors.toList());
        List<List<CartGoods.ComboxGoods>> productComboLists = checkCartRequest.getCartGoodsList().stream().filter(goods -> CollectionUtils.isNotEmpty(goods.getProductComboList())).map(CartGoods::getProductComboList).collect(Collectors.toList());
        List<String> goodsIds = checkCartRequest.getCartGoodsList().stream().filter(cartGoods -> !cartGoods.getCartGoodsUid().startsWith("spq")).map(CartGoods::getGoodsId).collect(Collectors.toList());
        goodsIds.addAll(checkCartRequest.getCartGoodsList().stream().filter(t -> !t.getCartGoodsUid().startsWith("spq") && StringUtils.isNotEmpty(t.getSpuId())).map(CartGoods::getSpuId).collect(Collectors.toList()));
        for (List<CartGoods.ComboxGoods> productGroupList : productGroupLists) {
            goodsIds.addAll(productGroupList.stream().map(CartGoods.ComboxGoods::getGoodsId).collect(Collectors.toList()));
        }
        for (List<CartGoods.ComboxGoods> productComboList : productComboLists) {
            goodsIds.addAll(productComboList.stream().map(CartGoods.ComboxGoods::getGoodsId).collect(Collectors.toList()));
        }
        //
        GetProductInfoRequest request = new GetProductInfoRequest();
        request.setPartnerId(checkCartRequest.getPartnerId());
        request.setStoreId(checkCartRequest.getStoreId());
        request.setGoodsIds(goodsIds.stream().distinct().collect(Collectors.toList()));
        request.setMenuType(checkCartRequest.getMenuType());
        return request;
    }


    /**
     * 更新当前购物车商品行信息
     *
     * @param cartGoods       当前购物车商品行
     * @param productBeans    购物车中所有的productId对应的商品详情
     * @param cartGoodsStates 购物车状态
     */
    public void updateCartGoodsInfo(CartGoods cartGoods, List<ProductBeanDTO> productBeans, CartGoodsStates cartGoodsStates, List<String> invalidGoodsIdList) {
        Optional<ProductBeanDTO> firstProduct = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), cartGoods.getGoodsId())).findFirst();
        if (!firstProduct.isPresent()) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return;
        }
        ProductBeanDTO productBean = firstProduct.get();
        // 如果是sku普通商品，则商品属相取sku对应的spu的属性
        List<ProductBeanDTO.ProductAttributeGroupListBean> productAttributeGroupList = productBean.getProductAttributeGroupList();
        ProductBeanDTO spuProduct = productBean;
        if (ObjectUtils.equals(GoodsTypeEnum.SKU_GOODS.getGoodsType(), cartGoods.getGoodsType()) || StringUtils.isNotEmpty(cartGoods.getSkuId())) {
            Optional<ProductBeanDTO> spuProduct1 = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), cartGoods.getSpuId())).findFirst();
            if (!spuProduct1.isPresent()) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return;
            }
            spuProduct = spuProduct1.get();
            productAttributeGroupList = spuProduct1.get().getProductAttributeGroupList();
        }
        // 商品非上架状态
        if (ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), productBean.getStatus()) || ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), spuProduct.getStatus())) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return;
        }
        Map<String, String> attributes = getAttributes(cartGoods, cartGoods.getExtra(), productAttributeGroupList, invalidGoodsIdList);
        cartGoods.setName(spuProduct.getName());
        cartGoods.setSpuName(spuProduct.getName());
        cartGoods.setSkuName(productBean.getName());
        cartGoods.setSpecProductId(attributes.get(ATTRIBUTEID));

        String skuSpecName = "";
        if (CollectionUtils.isNotEmpty(productBean.getSkuSpecValues())) {
            List<String> skuSpecValus = productBean.getSkuSpecValues().stream().map(p -> p.getSpecValue()).collect(Collectors.toList());
            skuSpecName = StringUtils.join(skuSpecValus, "/");
        }
        String attributeName = attributes.get(ATTRIBUTENAME) == null ? "" : attributes.get(ATTRIBUTENAME);
        cartGoods.setSubName(StringUtils.isNotEmpty(skuSpecName) && StringUtils.isNotEmpty(attributeName) ?
                skuSpecName + "/" + attributeName : skuSpecName + attributeName);
        cartGoods.setPic(StringUtils.isBlank(productBean.getPicture()) ? spuProduct.getPicture() : productBean.getPicture());
        cartGoods.setPackPrice(productBean.getPackPrice());
        cartGoods.setStockLimit(ObjectUtils.equals(1, productBean.getStockLimit()));
        cartGoods.setCustomerCode(productBean.getCustomerCode());
        // 如果是套餐商品，更新套餐内固定商品&可选商品的详细信息
        boolean isSetMealProduct = ObjectUtils.equals(ProductType.SetMeal.getCode(), productBean.getType()) || ObjectUtils.equals(ProductType.IncreasedPackage.getCode(), productBean.getType());
        if (isSetMealProduct) {
            if (CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
                //check 套餐内固定商品是否有变化，若有变化移除购物车
                if (checkComboProductChange(cartGoods.getProductComboList(), productBean, cartGoods, invalidGoodsIdList)) {
                    return;
                }
                for (CartGoods.ComboxGoods productCombo : cartGoods.getProductComboList()) {
                    //如果套餐内固定商品移除，默认移除当前商品行
                    boolean isExist = productBean.getProductComboList().stream().anyMatch(p -> ObjectUtils.equals(productCombo.getGoodsId(), p.getProductId()));
                    if (!isExist) {
                        // 标记非法商品
                        invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                        return;
                    }
                    if (!updateComboxGoodsInfo(cartGoods, productCombo, firstProduct.get(), productBeans, cartGoodsStates, invalidGoodsIdList)) {
                        return;
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
                List<String> productGroupIdList = new ArrayList<>();
                productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> t.stream().forEach(group -> productGroupIdList.add(group.getProductId())));
                for (CartGoods.ComboxGoods productGroup : cartGoods.getProductGroupList()) {
                    //如果套餐内可选商品移除，默认移除当前商品行
                    boolean isExist = productGroupIdList.stream().anyMatch(p -> ObjectUtils.equals(productGroup.getGoodsId(), p));
                    if (!isExist) {
                        // 标记非法商品
                        invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                        return;
                    }
                    if (!updateComboxGoodsInfo(cartGoods, productGroup, firstProduct.get(), productBeans, cartGoodsStates, invalidGoodsIdList)) {
                        return;
                    }
                }
            }
        }
        //更新当前商品行价格，check价格是否变更
        Long newOrigOriginalPrice = 0L;
        if (isSetMealProduct) {
            //如果是套餐，则当前商品行价格为：固定套餐价格* 数量+可选商品加价 价格
            Map<String, Integer> productOriginalPrices = new HashMap<>();
            Map<String, Integer> productMarkUpPrices = new HashMap<>();
            productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> productMarkUpPrices.putAll(t.stream().collect(Collectors.toMap(ProductBeanDTO.ProductGroupType.GroupDetailType::getProductId, ProductBeanDTO.ProductGroupType.GroupDetailType::getMarkUpPrice))));
            productBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(t -> productOriginalPrices.putAll(t.stream().collect(Collectors.toMap(ProductBeanDTO.ProductGroupType.GroupDetailType::getProductId, ProductBeanDTO.ProductGroupType.GroupDetailType::getProductFinalPrice))));
            if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
                for (CartGoods.ComboxGoods groupProduct : cartGoods.getProductGroupList()) {
                    Integer originalPrice = productOriginalPrices.get(groupProduct.getGoodsId()) == null ? 0 : productOriginalPrices.get(groupProduct.getGoodsId());
                    newOrigOriginalPrice += originalPrice * groupProduct.getQty();
                }
            }
            newOrigOriginalPrice += productBean.getProductComboList().stream().mapToInt(t -> t.getQuantity() * t.getFinalPrice()).sum();
        } else {
            newOrigOriginalPrice = productBean.getFinalPrice();
        }
        Long oldOrigOriginalPrice = cartGoods.getOriginalPrice();
        if (null != oldOrigOriginalPrice && !Objects.equals(newOrigOriginalPrice, oldOrigOriginalPrice)) {
            cartGoodsStates.setPriceChanged(true);
        }
        cartGoods.setOriginalPrice(newOrigOriginalPrice);
        cartGoods.setOriginalAmount(newOrigOriginalPrice * cartGoods.getQty());
        cartGoods.setAmount(newOrigOriginalPrice * cartGoods.getQty());
        //咨询商品服务，套餐售价取originalPrice
        cartGoods.setFinalPrice(isSetMealProduct ? productBean.getOriginalPrice() : productBean.getFinalPrice());
        cartGoods.setWeight(productBean.getWeight());
        cartGoods.setUnit(productBean.getUnit());
        cartGoods.setWeightType(CommonsConstant.WEIGHT_PRODUCT.equals(productBean.getWeightType()));
    }

    /**
     * 更新当前购物车商品行信息
     *
     * @param cartGoods    当前购物车商品行
     * @param productBeans 购物车中所有的productId对应的商品详情
     */
    public void updateCartGoodsInfoNew(CartGoods cartGoods, List<ProductBeanDTO> productBeans) {
        try {
            Optional<ProductBeanDTO> firstProduct = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), cartGoods.getSpuId())).findFirst();
            if (!firstProduct.isPresent()) {
                return;
            }
            ProductBeanDTO spuProduct = firstProduct.get();
            // fisherman 添加原有商品服务的商品类型 -> 后续只为存表B端使用, 暂无其他地方有逻辑判断 20210810
            cartGoods.setOriginalProductType(spuProduct.getType());
            //是否是sku商品
            boolean isSkuProduct = ObjectUtils.equals(GoodsTypeEnum.SKU_GOODS.getGoodsType(), cartGoods.getGoodsType());
            // 如果是套餐商品，更新套餐内固定商品&可选商品的详细信息
            boolean isSetMealProduct = ObjectUtils.equals(ProductType.SetMeal.getCode(), spuProduct.getType()) || ObjectUtils.equals(ProductType.IncreasedPackage.getCode(), spuProduct.getType());
            ProductBeanDTO.SkuProductBean skuProduct = isSkuProduct ? spuProduct.getSkuList().stream().filter(p -> ObjectUtils.equals(cartGoods.getSkuId(), p.getSkuId())).findFirst().orElse(null): null;
            if(isSkuProduct && skuProduct == null){//特殊场景前端传一个skuid非spuid下多规格商品
                throw new ServiceException(CartResponseConstant.FAIL);
            }
            Map<String, String> attributes = getAttributesNew(cartGoods.getExtra());
            if(!"早餐啡常搭".equals(cartGoods.getName()) && !"早餐啡常搭".equals(cartGoods.getSkuName()) && !"早餐啡常搭".equals(cartGoods.getSpuName())
                && !"啡常搭".equals(cartGoods.getName()) && !"啡常搭".equals(cartGoods.getSkuName()) && !"啡常搭".equals(cartGoods.getSpuName())) {
                cartGoods.setName(spuProduct.getName());
                cartGoods.setForeignName(spuProduct.getForeignName());
                cartGoods.setSpuName(spuProduct.getName());
                cartGoods.setSpuForeignName(spuProduct.getForeignName());
                cartGoods.setSkuName(isSkuProduct ? skuProduct.getProductName() : spuProduct.getName());
                cartGoods.setSkuForeignName(isSkuProduct ? skuProduct.getForeignProductName() : spuProduct.getForeignName());

            }
            cartGoods.setSpecProductId(attributes.get(ATTRIBUTEID));
            cartGoods.setPic(spuProduct.getPicture());
            cartGoods.setPackPrice(isSkuProduct ? skuProduct.getPackPrice() : spuProduct.getPackPrice());
            cartGoods.setStockLimit(isSkuProduct ? ObjectUtils.equals(1, skuProduct.getStockLimit()) : ObjectUtils.equals(1, spuProduct.getStockLimit()));
            cartGoods.setCustomerCode(isSkuProduct ? skuProduct.getCustomerCode() : spuProduct.getCustomerCode());
            cartGoods.setRiseSell(isSkuProduct ? skuProduct.getRiseSell() : spuProduct.getRiseSell());
            cartGoods.setMemberDiscount(spuProduct.getMemberDiscountResult());
            cartGoods.setClassificationId(spuProduct.getCategory());
            cartGoods.setClassificationName(spuProduct.getCategoryName());
            cartGoods.setClassificationForeignName(spuProduct.getCategoryName());

            cartGoods.setTax(spuProduct.getTax());
            cartGoods.setTaxId(spuProduct.getTaxId());
            String skuSpecName = "";
            String skuForeignSpecName = "";
            if (isSkuProduct && CollectionUtils.isNotEmpty(skuProduct.getSkuSpecValues())) {
                List<String> skuSpecValus = skuProduct.getSkuSpecValues().stream().map(p -> p.getSpecValue()).collect(Collectors.toList());
                skuSpecName = StringUtils.join(skuSpecValus, "/");
            }
            if (isSkuProduct && CollectionUtils.isNotEmpty(skuProduct.getSkuSpecValues())) {
                List<String> skuSpecValus = skuProduct.getSkuSpecValues().stream().map(p -> p.getForeignSpecValue()).collect(Collectors.toList());
                skuForeignSpecName = StringUtils.join(skuSpecValus, "/");
            }
            String attributeName = attributes.get(ATTRIBUTENAME) == null ? "" : attributes.get(ATTRIBUTENAME);
            String attributeForeignName = attributes.get(ATTRIBUTEFOREIGNNAME) == null ? "" : attributes.get(ATTRIBUTEFOREIGNNAME);
            //购物车小标题
            cartGoods.setSubName(StringUtils.isNotEmpty(skuSpecName) && StringUtils.isNotEmpty(attributeName) ?
                    skuSpecName + "/" + attributeName : skuSpecName + attributeName);
            //购物车英文小标题
            cartGoods.setSubForeignName(StringUtils.isNotEmpty(skuForeignSpecName) && StringUtils.isNotEmpty(attributeForeignName) ?
                    skuForeignSpecName + "/" + attributeForeignName : skuForeignSpecName + attributeForeignName);


            if (isSetMealProduct) {
                if (CollectionUtils.isNotEmpty(cartGoods.getProductComboList())) {
                    for (CartGoods.ComboxGoods productCombo : cartGoods.getProductComboList()) {
                        updateComboxGoodsInfoNew(productCombo, spuProduct, true);
                    }
                }
                if (CollectionUtils.isNotEmpty(cartGoods.getProductGroupList())) {
                    for (CartGoods.ComboxGoods productGroup : cartGoods.getProductGroupList()) {
                        updateComboxGoodsInfoNew(productGroup, spuProduct, false);
                    }
                }
                cartGoods.setGoodsType(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType());
            }
            //更新当前商品行价格
            Long newOrigOriginalPrice = 0L;
            if (isSetMealProduct) {
                newOrigOriginalPrice += cartGoods.getProductComboList().stream().mapToLong(t -> t.getOriginalAmount()).sum();
                newOrigOriginalPrice += cartGoods.getProductGroupList().stream().mapToLong(t -> t.getOriginalAmount()).sum();
            } else {
                newOrigOriginalPrice = isSkuProduct ? skuProduct.getFinalPrice() : spuProduct.getFinalPrice();
            }
            cartGoods.setOriginalPrice(newOrigOriginalPrice);
            cartGoods.setOriginalAmount(newOrigOriginalPrice * cartGoods.getQty());
            cartGoods.setAmount(newOrigOriginalPrice * cartGoods.getQty());
            //咨询商品服务，套餐售价取originalPrice
            cartGoods.setFinalPrice(isSetMealProduct ? spuProduct.getOriginalPrice() : isSkuProduct ? skuProduct.getFinalPrice() : spuProduct.getFinalPrice());
            cartGoods.setWeight(isSkuProduct ? skuProduct.getWeight() : spuProduct.getWeight());
            cartGoods.setUnit(isSkuProduct ? skuProduct.getUnit() : spuProduct.getUnit());
            cartGoods.setWeightType(CommonsConstant.WEIGHT_PRODUCT.equals(spuProduct.getWeightType()));
            cartGoods.setMaterialAmount(0L);
            cartGoods.setOriginalMaterialAmount(0L);
            // todo 设置加料
            this.checkMaterialProduct(cartGoods, spuProduct);

        } catch (Exception ex) {
            ShoppingSdkLogUtil.errorLog( "updateCartGoodsInfoNew_Error cartGoods:{},productBeans:{}", ex, JSONObject.toJSONString(cartGoods),JSONObject.toJSONString(productBeans));
            cartGoods.setCartGoodsUid(null);
        }
    }

    /**
     * 单独处理加料及标识小料信息是否有变化
     *
     * @param cartGoods
     * @param spuProduct
     */
    private void checkMaterialProduct(CartGoods cartGoods, ProductBeanDTO spuProduct) {

        if (CollectionUtils.isEmpty(cartGoods.getProductMaterialList())) return;
        ProductBeanDTO.SkuProductBean skuProductBean = null;
        boolean isSkuProduct = ObjectUtils.equals(GoodsTypeEnum.SKU_GOODS.getGoodsType(), cartGoods.getGoodsType());
        if (isSkuProduct){
            if (CollectionUtils.isEmpty(spuProduct.getSkuList())){
                cartGoods.setGoodsType(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType());
                cartGoods.setProductMaterialList(new ArrayList<>());
                return;
            } else {
                skuProductBean = spuProduct.getSkuList().stream().filter(p -> p.getSkuId().equals(cartGoods.getSkuId())).findFirst().orElse(null);
                if (skuProductBean == null || CollectionUtils.isEmpty(skuProductBean.getAdditionalGroupList())){
                    cartGoods.setGoodsType(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType());
                    cartGoods.setProductMaterialList(new ArrayList<>());
                    return;
                }
            }
        } else {
            //加料信息为空
            if (CollectionUtils.isEmpty(spuProduct.getAdditionalGroupList())) {
                cartGoods.setGoodsType(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType());
                cartGoods.setProductMaterialList(new ArrayList<>());
                return;
            }
        }
        //提取加料信息
        List<String> materialSpu = new ArrayList<>();
        HashMap<String, ProductBeanDTO.ProductGroupType.GroupDetailType> materialHash = new HashMap<>();
        if (isSkuProduct){
            List<ProductBeanDTO.ProductGroupType> groupList = skuProductBean.getAdditionalGroupList();
            for (ProductBeanDTO.ProductGroupType groupDetail : groupList) {
                for (ProductBeanDTO.ProductGroupType.GroupDetailType groupDetailType : groupDetail.getGroupDetail()) {
                    materialHash.put(groupDetailType.getProductId(), groupDetailType);
                    materialSpu.add(groupDetailType.getProductId());
                }
            }
        } else {
            List<ProductBeanDTO.ProductGroupType> groupList = spuProduct.getAdditionalGroupList();
            for (ProductBeanDTO.ProductGroupType groupDetail : groupList){
                for (ProductBeanDTO.ProductGroupType.GroupDetailType groupDetailType : groupDetail.getGroupDetail()) {
                    materialHash.put(groupDetailType.getProductId(), groupDetailType);
                    materialSpu.add(groupDetailType.getProductId());
                }
            }
        }
        //加车小料和商品小料没有交集则提示商品信息有异常
        if(CollectionUtils.isEmpty(cartGoods.getProductMaterialList().stream().filter(e->materialSpu.contains(e.getSpuId())).collect(Collectors.toList()))) {
            cartGoods.setGoodsType(GoodsTypeEnum.EXCEPTION_GOODS.getGoodsType());
            cartGoods.setProductMaterialList(new ArrayList<>());
            return;
        }
        ArrayList<CartGoods.MaterialGoods> materialGoodsList = new ArrayList<>();
        Long materialAmount = 0L;
        Long originalMaterAmount = 0L;
        String materialSubName = cartGoods.getSubName();
        for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
            ProductBeanDTO.ProductGroupType.GroupDetailType detail = materialHash.get(materialGoods.getSpuId());
            if (detail == null) continue;
            CartGoods.MaterialGoods material = new CartGoods.MaterialGoods();
            material.setQty(materialGoods.getQty());
            material.setSpuName(detail.getProductName());
            material.setSpuForeignName(detail.getForeignProductName());
            material.setSpuId(detail.getProductId());
            //fisherman 小料商品设置原始商品类型
            material.setOriginalProductType(detail.getProductType());
            //行单价 \ 行总价
            material.setFinalPrice(detail.getProductFinalPrice().longValue());
            material.setAmount(detail.getProductFinalPrice().longValue() * materialGoods.getQty() * cartGoods.getQty());
            //原行单价*数量
            material.setOriginalAmount(detail.getProductFinalPrice().longValue() * materialGoods.getQty() * cartGoods.getQty());
            material.setOriginalPrice(detail.getProductFinalPrice().longValue());
            material.setCustomerCode(detail.getCustomerCode());
            materialGoodsList.add(material);
            materialAmount += detail.getProductFinalPrice().longValue() * materialGoods.getQty() * cartGoods.getQty();
            originalMaterAmount += detail.getProductFinalPrice().longValue() * materialGoods.getQty() * cartGoods.getQty();
            ;
            materialSubName = materialSubName + "/" + detail.getProductName();
        }
        //设置购物车行记录
        cartGoods.setProductMaterialList(materialGoodsList);
        //加料行记录现价总价
        cartGoods.setMaterialAmount(materialAmount);
        //加料行记录原价总价
        cartGoods.setOriginalMaterialAmount(originalMaterAmount);
        //cartGoods.setOriginalAmount(cartGoods.getOriginalAmount() + originalMaterAmount);
        //cartGoods.setSubName(StringUtils.strip(materialSubName, "/"));
    }

    private boolean updateComboxGoodsInfo(CartGoods cartGoods, CartGoods.ComboxGoods comboxGoods, ProductBeanDTO parentProductBean, List<ProductBeanDTO> productBeans, CartGoodsStates cartGoodsStates, List<String> invalidGoodsIdList) {
        // 可选商品详情
        Optional<ProductBeanDTO> firstProduct = productBeans.stream().filter(p -> ObjectUtils.equals(p.getPid(), comboxGoods.getGoodsId())).findFirst();
        if (!firstProduct.isPresent()) {
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return false;
        }
        ProductBeanDTO productBean = firstProduct.get();
        // 商品非上架状态
        if (ObjectUtils.notEqual(ProductStatus.SALEON.getCode(), productBean.getStatus())) {
            // 标记非法商品
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return false;
        }
        // 查找可选商品的加价价格，若无则取商品详情的FinalPrice，若有则取MarkUpPrice
        Long finalPrice = productBean.getFinalPrice();
        List<ProductBeanDTO.ProductGroupType.GroupDetailType> groupDetailList = new ArrayList<>();
        parentProductBean.getProductGroupList().forEach(group -> groupDetailList.addAll(group.getGroupDetail()));
        List<ProductBeanDTO.ProductGroupType.GroupDetailType> groupProducts = groupDetailList.stream().filter(g -> ObjectUtils.equals(comboxGoods.getGoodsId(), g.getProductId())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(groupProducts)) {
            finalPrice = groupProducts.get(0).getMarkUpPrice() == null ? 0L : groupProducts.get(0).getMarkUpPrice().longValue();
        }
        // 设置商品详情
        Map<String, String> attributes = getAttributes(cartGoods, comboxGoods.getExtra(), productBean.getProductAttributeGroupList(), invalidGoodsIdList);
        comboxGoods.setName(productBean.getName());
        comboxGoods.setSpuName(productBean.getName());
        comboxGoods.setSpecProductId(attributes.get(ATTRIBUTEID));
        comboxGoods.setSubName(attributes.get(ATTRIBUTENAME));
        // check价格是否变更
        Long newOrigOriginalPrice = productBean.getFinalPrice();
        Long oldOrigOriginalPrice = comboxGoods.getOriginalPrice();
        if (!Objects.equals(newOrigOriginalPrice, oldOrigOriginalPrice)) {
            cartGoodsStates.setPriceChanged(true);
        }
        comboxGoods.setPic(productBean.getPicture());
        comboxGoods.setPackPrice(productBean.getPackPrice());
        comboxGoods.setOriginalPrice(productBean.getFinalPrice());
        comboxGoods.setOriginalAmount(productBean.getFinalPrice() * comboxGoods.getQty());
        comboxGoods.setAmount(finalPrice * comboxGoods.getQty());
        comboxGoods.setCustomerCode(productBean.getCustomerCode());
        comboxGoods.setFinalPrice(finalPrice);
        comboxGoods.setWeightType(CommonsConstant.WEIGHT_PRODUCT.equals(productBean.getWeightType()));
        comboxGoods.setWeight(productBean.getWeight());
        comboxGoods.setUnit(productBean.getUnit());
        return true;
    }

    /**
     * 更新套餐固定商品、可选商品信息
     *
     * @param comboxGoods       固定商品或可选商品
     * @param parentProductBean 套餐服商品
     * @param isComboxGoods     是否是固定商品
     * @return
     */
    private void updateComboxGoodsInfoNew(CartGoods.ComboxGoods comboxGoods, ProductBeanDTO parentProductBean, boolean isComboxGoods) {

        ProductBeanDTO.ProductComboType productComboType = new ProductBeanDTO.ProductComboType();
        ProductBeanDTO.ProductGroupType.GroupDetailType groupDetailType = new ProductBeanDTO.ProductGroupType.GroupDetailType();
        if (isComboxGoods) {
            productComboType = parentProductBean.getProductComboList().stream().filter(p -> ObjectUtils.equals(comboxGoods.getGoodsId(), p.getProductId())).findFirst().orElse(new ProductBeanDTO.ProductComboType());
        } else {
            Map<String, ProductBeanDTO.ProductGroupType.GroupDetailType> map = new HashMap<>();
            parentProductBean.getProductGroupList().stream().map(t -> t.getGroupDetail()).forEach(group -> group.forEach(detailType -> map.put(detailType.getProductId(), detailType)));
            groupDetailType = map.get(comboxGoods.getGoodsId());
        }

        // 若是固定商品则取商品详情的FinalPrice，若是可选商品则取MarkUpPrice
        Long finalPrice = isComboxGoods ? productComboType.getFinalPrice().longValue() : groupDetailType.getMarkUpPrice().longValue();
        // 设置商品详情
        Map<String, String> attributes = getAttributesNew(comboxGoods.getExtra());
        comboxGoods.setName(isComboxGoods ? productComboType.getProductName() : groupDetailType.getProductName());
        comboxGoods.setForeignName(isComboxGoods ? productComboType.getForeignProductName() : groupDetailType.getForeignProductName());
        comboxGoods.setSpuName(comboxGoods.getName());
        // 组合商品类型存放
        comboxGoods.setOriginalProductType(isComboxGoods ? productComboType.getProductType() : groupDetailType.getProductType());
        comboxGoods.setSpuForeignName(comboxGoods.getForeignName());
        comboxGoods.setSpecProductId(attributes.get(ATTRIBUTEID));
        comboxGoods.setSubName(attributes.get(ATTRIBUTENAME));
        comboxGoods.setSubForeignName(attributes.get(ATTRIBUTEFOREIGNNAME));

        comboxGoods.setPic(isComboxGoods ? productComboType.getPicture() : groupDetailType.getPicture());
        comboxGoods.setOriginalPrice(isComboxGoods ? productComboType.getFinalPrice().longValue() : groupDetailType.getProductFinalPrice().longValue());
        comboxGoods.setOriginalAmount(comboxGoods.getOriginalPrice() * comboxGoods.getQty());
        comboxGoods.setAmount(finalPrice * comboxGoods.getQty());
        comboxGoods.setCustomerCode(isComboxGoods ? productComboType.getCustomerCode() : groupDetailType.getCustomerCode());
        comboxGoods.setFinalPrice(finalPrice);
        comboxGoods.setWeightType(isComboxGoods ? CommonsConstant.WEIGHT_PRODUCT.equals(productComboType.getWeightType()) : CommonsConstant.WEIGHT_PRODUCT.equals(groupDetailType.getWeightType()));
        comboxGoods.setUnit(isComboxGoods ? productComboType.getUnit() : groupDetailType.getUnit());
        comboxGoods.setWeight(isComboxGoods ? productComboType.getWeight() : groupDetailType.getWeight());
        comboxGoods.setTax(isComboxGoods ? productComboType.getTax() : groupDetailType.getTax());
        comboxGoods.setTaxId(isComboxGoods ? productComboType.getTaxId() : groupDetailType.getTaxId());
    }

    private Map<String, String> getAttributes(CartGoods cartGoods, List<CartGoods.CartGoodsExtra> extra, List<ProductBeanDTO.ProductAttributeGroupListBean> attributeGroupListBeanList, List<String> invalidGoodsIdList) {
        if (CollectionUtils.isEmpty(extra) && CollectionUtils.isNotEmpty(attributeGroupListBeanList)) {
            invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
            return new HashMap<>();
        }
        if (CollectionUtils.isEmpty(extra)) {
            return new HashMap<>();
        }
        // 查询到的商品信息
        List<String> allAttributes = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(attributeGroupListBeanList)) {
            for (ProductBeanDTO.ProductAttributeGroupListBean productAttributeGroupListBean : attributeGroupListBeanList) {
                List<String> attributes = productAttributeGroupListBean
                        .getAttributeValues()
                        .parallelStream()
                        .map(ProductBeanDTO.ProductAttributeGroupListBean.AttributeValueBean::getAttributeId)
                        .collect(Collectors.toList());
                allAttributes.addAll(attributes);
            }
        }
        // 购物车商品属性信息check是否非法（例如属性下架）
        for (CartGoods.CartGoodsExtra cartGoodsExtra : extra) {
            if (!allAttributes.contains(cartGoodsExtra.getAttributeId())) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                break;
            }
        }
        List<String> attributeIds = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
        List<String> attributeNames = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
        Map<String, String> result = new HashMap<>();
        result.put(ATTRIBUTEID, StringUtils.join(attributeIds, "/"));
        result.put(ATTRIBUTENAME, StringUtils.join(attributeNames, "/"));
        return result;
    }

    private Map<String, String> getAttributesNew(List<CartGoods.CartGoodsExtra> extra) {
        if (CollectionUtils.isEmpty(extra)) {
            return new HashMap<>();
        }
        List<String> attributeIds = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
        List<String> attributeNames = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
        List<String> attributeForeignNames = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeForeignName).collect(Collectors.toList());
        Map<String, String> result = new HashMap<>();
        result.put(ATTRIBUTEID, StringUtils.join(attributeIds, "/"));
        result.put(ATTRIBUTENAME, StringUtils.join(attributeNames, "/"));
        result.put(ATTRIBUTEFOREIGNNAME, StringUtils.join(attributeForeignNames, "/"));
        return result;
    }

    private boolean checkComboProductChange(List<CartGoods.ComboxGoods> comboxGoods, ProductBeanDTO productBean, CartGoods cartGoods, List<String> invalidGoodsIdList) {

        for (ProductBeanDTO.ProductComboType product : productBean.getProductComboList()) {
            if (!comboxGoods.stream().anyMatch(goods -> ObjectUtils.equals(product.getProductId(), goods.getGoodsId()))) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return true;
            }
        }
        for (CartGoods.ComboxGoods combo : comboxGoods) {
            if (!productBean.getProductComboList().stream().anyMatch(product -> ObjectUtils.equals(combo.getGoodsId(), product.getProductId()))) {
                // 标记非法商品
                invalidGoodsIdList.add(cartGoods.getCartGoodsUid());
                return true;
            }
        }
        return false;
    }

}
