/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: CouponService
 * @Package cn.freemud.service
 * @Description:
 * @author: pengfei.liu
 * @date: 2020/11/23
 * @version V1.0
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */

package cn.freemud.service.shoppingCart.impl;

import cn.freemud.entities.dto.calculate.*;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.SubmitPageEnum;
import cn.freemud.service.impl.ShoppingCartNewServiceImpl;
import cn.freemud.service.shoppingCart.ShoppingCartRelationService;
import cn.freemud.utils.WebUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
@Service("cocoShoppingCartRelationService")
public class CocoShoppingCartRelationServiceImpl implements ShoppingCartRelationService {

    @Autowired
    private ShoppingCartNewServiceImpl shoppingCartNewServiceImpl;


    @Override
    public void buildShoppingCartGoodsResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,
                                               CalculationDiscountResult discountResult,
                                               Integer flag) {

        if(discountResult != null){

            List<Discount> discounts = new ArrayList<>();

            // coco返回的活动中剔除集点活动
            if(discountResult.getDiscounts() != null && !discountResult.getDiscounts().isEmpty()){
                discountResult.getDiscounts().forEach(discount -> {
                    if(ActivityTypeEnum.TYPE_221.getCode().equals(discount.getType())){
                        return;
                    }
                    discounts.add(discount);
                });
            }

            // 促销的活动信息和商品优惠信息给前端做展示、打标签用
            shoppingCartGoodsResponseVo.setDiscounts(discounts);
            shoppingCartGoodsResponseVo.setGoods(discountResult.getGoods());

            List<CartGoods> products = shoppingCartGoodsResponseVo.getProducts();
            List<String> gifeProductIds = new ArrayList<>();
            if(products != null && !products.isEmpty()){
                // 获取赠品的商品id
                gifeProductIds = products.stream().filter(product -> Objects.equals(product.getActivityType(),ActivityTypeEnum.TYPE_63.getCode())).map(CartGoods::getGoodsId).collect(Collectors.toList());
            }

            Map<String, Goods> goodsDiscountsMap = new HashMap<>();

            Map<String, GoodsDiscount> halfDiscountsMap = new HashMap<>();
            // 商品优惠信息
            List<Goods> goodsDiscounts = discountResult.getGoods();
            if(goodsDiscounts == null || goodsDiscounts.isEmpty()){
                return;
            }

            goodsDiscountsMap = goodsDiscounts.stream().collect(Collectors.toMap(Goods::getCartGoodsUid, g -> g,(k1, k2)->k1));

            goodsDiscounts.forEach(goodsDiscount ->{
                List<GoodsDiscount> oneGoodsDiscounts = goodsDiscount.getDiscounts();
                if(oneGoodsDiscounts == null || oneGoodsDiscounts.isEmpty()){
                    return;
                }
                oneGoodsDiscounts.forEach(discount -> {
                    if(Objects.equals(discount.getType(),ActivityTypeEnum.TYPE_53.getCode())){
                        halfDiscountsMap.put(goodsDiscount.getCartGoodsUid() + "-" + discount.getGoodsId(),discount);
                    }

                });
            });


            if(!Objects.equals(flag, SubmitPageEnum.YES.getCode())){
                // 非结算页
                orderingFoodPage(products,halfDiscountsMap,goodsDiscountsMap,gifeProductIds,shoppingCartGoodsResponseVo);
            }else {// 结算页
                settlementPage(products,halfDiscountsMap,goodsDiscountsMap,shoppingCartGoodsResponseVo,gifeProductIds);
            }
        }

        // 购物车顶部的提示不只是满减的提示，只要用户参加了活动，就应该把优惠的金额放到上面
        // 获取用户的优惠金额，重新编辑用户提示语
        // 这里比较暴力的做法直接把已经编辑的结合直接删了，重新用一个新的
        // 并且把tip类型设置为5，因为前端针对5直接显示立减文案
        if(!ObjectUtils.equals(shoppingCartGoodsResponseVo.getTotalDiscountAmount(),0L)){

            ArrayList<ActivityList> activityList = new ArrayList<>();

            ActivityList notInShopping = new ActivityList();
            notInShopping.setTipType(5);
            // 直接取出整车的优惠
            notInShopping.setDeduct(WebUtil.formatAmount(shoppingCartGoodsResponseVo.getTotalDiscountAmount() * 1.00 / 100).toString());
            activityList.add(notInShopping);

            ActivityTip activityTip = shoppingCartGoodsResponseVo.getActivityTip();
            activityTip.setActivityList(activityList);

            activityTip.setActivityList(activityList);

            shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        }


        // 将配送费放到一个字段去
        if(shoppingCartGoodsResponseVo.getIsDiscountDelivery() && ( shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() < shoppingCartGoodsResponseVo.getDeliveryAmount())){
            shoppingCartGoodsResponseVo.setDeliveryAmount(shoppingCartGoodsResponseVo.getDiscountDeliveryAmount());
        }

    }

    @Override
    public void cleanAfter(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartClearRequestVo shoppingCartClearRequestVo) {

        String receiveId = shoppingCartClearRequestVo.getReceiveId();
        String partnerId = shoppingCartClearRequestVo.getPartnerId();
        String storeId = shoppingCartClearRequestVo.getShopId();

        // 获取基础运费
        Long deliveryAmount = shoppingCartNewServiceImpl.calculateDeliveryAmount(receiveId, partnerId, storeId, null, shoppingCartGoodsResponseVo,shoppingCartClearRequestVo.getOrderType());

        shoppingCartGoodsResponseVo.setDeliveryAmount(deliveryAmount);
        shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliveryAmount);
    }


    public CartGoods buildNewLine(CartGoods cgs,Integer activityType,Integer qty,Long newPrice,String goodsId,Long originalPrice){
        CartGoods newCartGoods = new CartGoods();
        // 购物车的行设置和原来的行一致，便于前端在更新商品数量的时候。能够根据购物车行聚合商品数量
        // 因为半价行是从主行中拆出来的
        newCartGoods.setCartGoodsUid(cgs.getCartGoodsUid());
        // 这个地方不要放置商品id，因为半价行的商品不打活动标签
        // 前端会根据这个活动检索
        newCartGoods.setGoodsType(cgs.getGoodsType());
        newCartGoods.setGoodsId(goodsId);
        newCartGoods.setSpuId(cgs.getSpuId());
        newCartGoods.setSkuId(cgs.getSkuId());
        newCartGoods.setSpecProductId(cgs.getSpecProductId());
        // 价格只用一个商品的价格
        newCartGoods.setOriginalPrice(originalPrice);
        // 价格只用一个商品的价格
        newCartGoods.setPackPrice(cgs.getPackPrice());
        // 价格只用一个商品的价格
        newCartGoods.setOriginalAmount(originalPrice);
        // 价格只用一个商品的价格
        newCartGoods.setFinalPrice(newPrice);
        // 价格只用一个商品的价格
        newCartGoods.setAmount(newPrice);
        newCartGoods.setName(cgs.getName());
        newCartGoods.setSpuName(cgs.getSpuName());
        newCartGoods.setSubName(cgs.getSubName());
        newCartGoods.setNodeId(cgs.getNodeId());
        newCartGoods.setCategoryName(cgs.getCategoryName());
        List<CartGoods.CartGoodsExtra> extra = Lists.newArrayList();
        List<CartGoods.CartGoodsExtra> cartGoodsExtras = cgs.getExtra();
        if (CollectionUtils.isNotEmpty(cartGoodsExtras)) {
            cartGoodsExtras.forEach(cartGoodsExtra -> {
                CartGoods.CartGoodsExtra goodsExtra = new CartGoods.CartGoodsExtra();
                goodsExtra.setAttributeId(cartGoodsExtra.getAttributeId());
                goodsExtra.setAttributeName(cartGoodsExtra.getAttributeName());
                extra.add(goodsExtra);
            });
        }
        newCartGoods.setExtra(extra);
        newCartGoods.setPic(cgs.getPic());
        newCartGoods.setCreateTimeMili(cgs.getCreateTimeMili());
        newCartGoods.setSkuName(cgs.getSkuName());
        newCartGoods.setSkuName(cgs.getSkuName());
        newCartGoods.setClassificationId(cgs.getClassificationId());
        newCartGoods.setClassificationName(cgs.getClassificationName());
        newCartGoods.setActivityType(activityType);
        newCartGoods.setQty(qty);
        newCartGoods.setProductMaterialList(cgs.getProductMaterialList());

        return newCartGoods;
    }

    /**
     * 结算页
     * @param products
     * @param halfDiscountsMap
     * @param goodsDiscountsMap
     * @param shoppingCartGoodsResponseVo
     */
    public void settlementPage(List<CartGoods> products,
                               Map<String, GoodsDiscount> halfDiscountsMap,
                               Map<String, Goods> goodsDiscountsMap,
                               ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,
                               List<String> gifeProductIds){

        // 第二件优惠活动（单品优惠）要把一行商品分成多行，且每行商品数量是1，同时要有两行是打活动标的
        List<CartGoods> newProducts = new ArrayList<>();
        if(products == null || products.isEmpty()){
            return;
        }

        for(int x = 0 ; x < products.size() ; x ++){
            CartGoods product = products.get(x);

            List<SmallMaterial> smallMaterial = goodsDiscountsMap.get(product.getCartGoodsUid()).getSmallMaterial();
            Integer smallMaterialOriTotal = 0;
            Long halfSmallMaterialOriTotal = 0L;
            if(smallMaterial != null && !smallMaterial.isEmpty()){
                for(SmallMaterial sm : smallMaterial){
                    List<GoodsDiscount> smDiscounts = sm.getDiscounts();
                    if(smDiscounts != null && !smDiscounts.isEmpty()){
                        for(GoodsDiscount smDiscount : smDiscounts){
                            if(ObjectUtils.equals(smDiscount.getType(),ActivityTypeEnum.TYPE_53.getCode())){
                                halfSmallMaterialOriTotal = halfSmallMaterialOriTotal + smDiscount.getSignleDiscount();
                            }
                        }
                    }
                    smallMaterialOriTotal = smallMaterialOriTotal + sm.getOriginalPrice();
                }
            }

            // 商品的单价 = 商品单价+小料单价
            Long originalPrice = (new Long(smallMaterialOriTotal) + product.getOriginalPrice());


            // 这一行的商品参加了第二件优惠活动（单品优惠）
            if( halfDiscountsMap.get(product.getCartGoodsUid() + "-" + product.getGoodsId()) != null){
                // 行商品数量
                Integer  num = product.getQty();
                for(int i = 0 ; i < num ; i++){
                    // 构建半价行
                    CartGoods cartGoods = new CartGoods();
                    if(i < 2){
                        cartGoods = buildNewLine(product,ActivityTypeEnum.TYPE_53.getCode(),1,originalPrice,product.getGoodsId(),originalPrice);
                    }else{
                        cartGoods = buildNewLine(product,ActivityTypeEnum.TYPE_53.getCode(),1,originalPrice,null,originalPrice);
                    }

                    newProducts.add(cartGoods);

                }
                continue;
            }

            // 限时立减的现单价获取促销的现单价
            // 商品是否参加单品立减
            boolean cutFlag = hashCutActive(goodsDiscountsMap,product);
            if(cutFlag){
                product.setFinalPrice(goodsDiscountsMap.get(product.getCartGoodsUid()).getNowPrice());
            }

            // 商品的单价 = 商品单价+小料单价
            product.setOriginalPrice(originalPrice);
            // 如果是赠品行，这行的价格就不用算了
            if(!gifeProductIds.contains(product.getGoodsId()) && product.getActivityType() == null){

                // 商品现单价 = 商品现单价+小料现单价
                smallMaterialOriTotal = smallMaterialOriTotal == null ? 0 : smallMaterialOriTotal;
                product.setFinalPrice(new Long(smallMaterialOriTotal) + (product.getFinalPrice() == null ? 0L : product.getFinalPrice()));
            }

            newProducts.add(product);
        }
        shoppingCartGoodsResponseVo.setProducts(newProducts);
    }

    /**
     * 点餐页
     * @param products
     * @param halfDiscountsMap
     * @param goodsDiscountsMap
     * @param gifeProductIds
     * @param shoppingCartGoodsResponseVo
     */
    public void orderingFoodPage(List<CartGoods> products,
                                 Map<String, GoodsDiscount> halfDiscountsMap,
                                 Map<String, Goods> goodsDiscountsMap,
                                 List<String> gifeProductIds,
                                 ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo){
        List<CartGoods> newProducts = new ArrayList<>();
        if(products == null || products.isEmpty()){
            return;
        }
        Set<String> halfGoodIds = new HashSet<>();
        List<CartGoods> halfProduct = new ArrayList<>();

        for(int x = 0 ; x < products.size() ; x ++){

            CartGoods product = products.get(x);
            // 小料信息
            if(goodsDiscountsMap.get(product.getCartGoodsUid()) == null){
                continue;
            }
            List<SmallMaterial> smallMaterial = goodsDiscountsMap.get(product.getCartGoodsUid()).getSmallMaterial();
            Integer smallMaterialOriTotal = 0;
            Long halfSmallMaterialOriTotal = 0L;
            if(smallMaterial != null && !smallMaterial.isEmpty()){
                for(SmallMaterial sm : smallMaterial){
                    List<GoodsDiscount> smDiscounts = sm.getDiscounts();
                    if(smDiscounts != null && !smDiscounts.isEmpty()){
                        for(GoodsDiscount smDiscount : smDiscounts){
                            if(ObjectUtils.equals(smDiscount.getType(),ActivityTypeEnum.TYPE_53.getCode())){
                                halfSmallMaterialOriTotal = halfSmallMaterialOriTotal + smDiscount.getSignleDiscount();
                            }
                        }
                    }
                    smallMaterialOriTotal = smallMaterialOriTotal + sm.getOriginalPrice();
                }
            }

            // 商品的单价 = 商品单价+小料单价
            Long originalPrice = (new Long(smallMaterialOriTotal) + product.getOriginalPrice());

            // 要添加的半价行数量，该字段从促销返回
            Integer num = 0;
            // 商品优惠的金额
            Long discountAmount = 0L;
            if(halfDiscountsMap.get(product.getCartGoodsUid() + "-" + product.getGoodsId()) != null){
                GoodsDiscount discount = halfDiscountsMap.get(product.getCartGoodsUid() + "-" + product.getGoodsId());
                if(discount == null){
                    return;
                }
                num = discount.getActualGoodsNumber();
                for(int i = 0 ; i < num ; i++){
                    // 第二件优惠活动，在点餐页需要给优惠商品单独显示一行
                    // 复制商品加到购物车
                    discountAmount = discount.getDiscount();

                    // 现单价 = 商品原单价+小料原单价-商品现单价小料现单价
                    Long newPrice = originalPrice - discountAmount - halfSmallMaterialOriTotal;
                    // 构建半价行
                    CartGoods cartGoods = buildNewLine(product,ActivityTypeEnum.TYPE_53.getCode(),1,newPrice,product.getGoodsId(),originalPrice);
                    halfGoodIds.add(cartGoods.getGoodsId());
                    halfProduct.add(cartGoods);
                }
            }
            Integer newQty = product.getQty() - num;
            // 数量减去购物车行之后如果为0就不加入购物车
            // 主商品行要数量，价格
            if(!Objects.equals(newQty,0)){
                product.setAmount(product.getAmount() - discountAmount * num);
                product.setOriginalAmount(product.getOriginalAmount() - product.getOriginalPrice() * num);
                product.setQty(newQty);


                // 商品是否参加立减
                boolean cutFlag  = hashCutActive(goodsDiscountsMap,product);
                if(cutFlag){
                    product.setFinalPrice(goodsDiscountsMap.get(product.getCartGoodsUid()).getNowPrice());
                }

                // num代表拆出来的半价行数量
                // 所以只要不等于0就需要把ActivityType设置为空
                // 因为前端用这个判断是否能加减
                if(!Objects.equals(num,0)){
                    product.setActivityType(null);
                }

                // num代表拆出来的半价行数量，gifeProductIds代表赠品
                // 只要符合条件就需要设置为空
                // 因为前端指挥在半价行、赠品行上打标
                // 前端是从商品活动信息中查找活动，在商品列表中找商品
                if((gifeProductIds.contains(product.getGoodsId()) && product.getActivityType() == null) || !Objects.equals(num,0)
                   || halfGoodIds.contains(product.getGoodsId())
                ){
                    product.setGoodsId(null);
                }

                // 商品的单价 = 商品单价+小料单价
                product.setOriginalPrice(originalPrice);
                // 如果是赠品行，这行的价格就不用算了
                if(!gifeProductIds.contains(product.getGoodsId()) && product.getActivityType() == null){
                    // 商品现单价 = 商品现单价+小料现单价
                    smallMaterialOriTotal = smallMaterialOriTotal == null ? 0 : smallMaterialOriTotal;
                    product.setFinalPrice(new Long(smallMaterialOriTotal) + (product.getFinalPrice() == null ? 0L : product.getFinalPrice()));
                }

                newProducts.add(product);
            }
        }

        // 半价商品加到购物车
        newProducts.addAll(halfProduct);

        shoppingCartGoodsResponseVo.setProducts(newProducts);
    }

    /**
     * 判断商品是否参加了立减
     * @param goodsDiscountsMap
     * @param product
     * @return
     */
    public Boolean hashCutActive(Map<String, Goods> goodsDiscountsMap,
                                 CartGoods product){

        boolean cutFlag = false;
        if(goodsDiscountsMap.get(product.getCartGoodsUid()) != null){
            Goods goods = goodsDiscountsMap.get(product.getCartGoodsUid());
            List<GoodsDiscount> goodsDiscountsList = goods.getDiscounts();
            if(goodsDiscountsList != null && !goodsDiscountsList.isEmpty()){
                for(GoodsDiscount gd : goodsDiscountsList){
                    if(ObjectUtils.equals(gd.getType(),ActivityTypeEnum.TYPE_22.getCode())){
                        cutFlag = true;
                        break;
                    }
                }
            }
        }

        return cutFlag;
    }

}
