package cn.freemud.adapter;

import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.GoodsTypeEnum;
import cn.freemud.enums.ProductType;
import cn.freemud.utils.BeanUtil;
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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: ShoppingCartMccafeAdapter
 * @Package cn.freemud.adapter
 * @Description: 简单描述下这个类是做什么用的
 * @author: yu.sun
 * @date: 2020/12/4 11:45
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Component
public class ShoppingCartMccafeAdapter {

    /**
     * @param cartGoods
     * @return
     */
    public List<ShoppingCartGoodsDto.CartGoodsDetailDto> convertComboxGoods2DetailGoods(CartGoods cartGoods, Integer totalDiscountAmount) {
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = new ArrayList<>();
        cartGoodsDetailDtos.addAll(getComboxGoods2DetailGoods(cartGoods, cartGoods.getProductComboList(), true,totalDiscountAmount));
        cartGoodsDetailDtos.addAll(getComboxGoods2DetailGoods(cartGoods, cartGoods.getProductGroupList(), false,totalDiscountAmount));
        return cartGoodsDetailDtos;
    }


    /**
     * @param cartGoods
     * @return
     */
    public List<ShoppingCartGoodsDto.CartGoodsDetailDto> getComboxGoods2DetailGoods(CartGoods cartGoods, List<CartGoods.ComboxGoods> comboxGoodsList, boolean isFixed,Integer totalDiscountAmount) {
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = new ArrayList<>();
        if (CollectionUtils.isEmpty(comboxGoodsList)) {
            return cartGoodsDetailDtos;
        }
        int size = comboxGoodsList.size();
        //当前套餐(固定搭配)总优惠=原总价-现总价-可选商品优惠价
        Long discountAmount = totalDiscountAmount -
                cartGoods.getProductGroupList().stream().mapToLong(product -> (product.getOriginalPrice() - product.getFinalPrice()) * product.getQty()).sum() * cartGoods.getQty();
        // 当前套餐（固定搭配）总原价
//        Long totalOriginalPrice = cartGoods.getProductComboList().stream().mapToLong(cart -> cart.getQty() * cart.getOriginalPrice()).sum() * cartGoods.getQty();
        Long totalOriginalPrice = cartGoods.getProductComboList().stream().mapToLong(cart -> cart.getQty() * cart.getFinalPrice()).sum() * cartGoods.getQty();
        Integer tempDiscount = 0;
        for (CartGoods.ComboxGoods comboxGoods : comboxGoodsList) {
            ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = new ShoppingCartGoodsDto.CartGoodsDetailDto();
            cartGoodsDetailDto.setTaxId(cartGoods.getTaxId());
            cartGoodsDetailDto.setTax(cartGoods.getTax());
            cartGoodsDetailDto.setSpuId(comboxGoods.getSpuId());
            cartGoodsDetailDto.setSpuName(comboxGoods.getSpuName());
            cartGoodsDetailDto.setSkuId(comboxGoods.getGoodsId());
            cartGoodsDetailDto.setSkuName(StringUtils.isEmpty(comboxGoods.getSkuName()) ? comboxGoods.getSpuName() : comboxGoods.getSkuName());
            cartGoodsDetailDto.setOriginalPrice(comboxGoods.getFinalPrice());
            cartGoodsDetailDto.setPicture(comboxGoods.getPic());
            cartGoodsDetailDto.setOriginalProductType(cartGoods.getGoodsType());
            int qty = comboxGoods.getQty() * cartGoods.getQty();
            cartGoodsDetailDto.setQty(qty);
            cartGoodsDetailDto.setProductType(comboxGoods.isWeightType() ? ProductType.WEIGHT_PRODUCT.getCode() : ProductType.SETMEAL.getCode());
            cartGoodsDetailDto.setParentProductId(cartGoods.getGoodsId());
            cartGoodsDetailDto.setIsFixedProduct(isFixed);
            cartGoodsDetailDto.setStockLimit(cartGoods.isStockLimit());
            cartGoodsDetailDto.setCustomerCode(comboxGoods.getCustomerCode());
            cartGoodsDetailDto.setWeight(comboxGoods.getWeight());
            cartGoodsDetailDto.setUnit(comboxGoods.getUnit());
            List<ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra> cartGoodsExtras = BeanUtil.convertBeans(comboxGoods.getExtra(), ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra::new);
            cartGoodsDetailDto.setExtraList(cartGoodsExtras);
            cartGoodsDetailDto.setSpecialExtra(comboxGoods.getSpecialExtra());
            cartGoodsDetailDto.setProductGroupId(comboxGoods.getProductGroupId());
            //小料
            if (CollectionUtils.isNotEmpty(comboxGoods.getProductMaterialList())) {
                List<ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods> materialList = new ArrayList<>(0);
                for (CartGoods.MaterialGoods materialGoods : comboxGoods.getProductMaterialList()) {
                    ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods goods = new ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods();
                    goods.setSpuId(materialGoods.getSpuId());
                    goods.setSpuName(materialGoods.getSpuName());
                    goods.setOriginalPrice(materialGoods.getOriginalPrice());
                    goods.setSalePrice(materialGoods.getFinalPrice());
                    goods.setQty(cartGoods.getQty());
                    goods.setTotalDiscountAmount(0);
                    goods.setProductCode(materialGoods.getCustomerCode());
                    goods.setCustomerCode(materialGoods.getCustomerCode());
                    goods.setOriginalProductType(materialGoods.getOriginalProductType());
                    materialList.add(goods);
                }
                cartGoodsDetailDto.setMaterialList(materialList);
            }
            //获取当前套餐固定商品的均摊价格
            if (isFixed) {
                if (size-- == 1) {
                    cartGoodsDetailDto.setTotalDiscountAmount(discountAmount.intValue() - tempDiscount);
                } else {
                    Long currentDiscountAmount = (qty * comboxGoods.getOriginalPrice() * discountAmount) / totalOriginalPrice;
                    cartGoodsDetailDto.setTotalDiscountAmount(currentDiscountAmount.intValue());
                    tempDiscount += currentDiscountAmount.intValue();
                }
            } else {
                cartGoodsDetailDto.setTotalDiscountAmount((comboxGoods.getOriginalPrice().intValue() - comboxGoods.getFinalPrice().intValue()) * comboxGoods.getQty() * cartGoods.getQty());
            }
            cartGoodsDetailDtos.add(cartGoodsDetailDto);
        }
        return cartGoodsDetailDtos;
    }

    /**
     * @param cartGoods
     * @return
     */
    public ShoppingCartGoodsDto.CartGoodsDetailDto convertCartGoods2DetailGoodsList(CartGoods cartGoods, List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList, Map<String, String> duplicateGoodsMap) {
        if (StringUtils.isEmpty(cartGoods.getCouponCode()) && GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
            return null;
        } else {
            ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = convertCartGoods2DetailGoods(cartGoods, apportionGoodsList, duplicateGoodsMap);
            if(GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                cartGoodsDetailDto.setComboProducts(this.convertComboxGoods2DetailGoods(cartGoods,cartGoodsDetailDto.getTotalDiscountAmount()));
            }
            return cartGoodsDetailDto;
        }
    }

    /**
     * @param cartGoods
     * @return
     */
    public ShoppingCartGoodsDto.CartGoodsDetailDto convertCartGoods2DetailGoods(CartGoods cartGoods, List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList, Map<String, String> duplicateGoodsMap) {
        // 设置基础信息
        ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = new ShoppingCartGoodsDto.CartGoodsDetailDto();
        cartGoodsDetailDto.setCartGoodsUid(cartGoods.getCartGoodsUid());
        cartGoodsDetailDto.setTaxId(cartGoods.getTaxId());
        cartGoodsDetailDto.setTax(cartGoods.getTax());
        cartGoodsDetailDto.setSpuId(cartGoods.getSpuId());
        cartGoodsDetailDto.setSpuName(cartGoods.getSpuName());
        cartGoodsDetailDto.setSkuId(StringUtils.isEmpty(cartGoods.getSkuId()) ? cartGoods.getSpuId() : cartGoods.getSkuId());
        cartGoodsDetailDto.setSkuName(StringUtils.isEmpty(cartGoods.getSkuName()) ? cartGoods.getSpuName() : cartGoods.getSkuName());
        cartGoodsDetailDto.setOriginalPrice(cartGoods.getFinalPrice());
//        cartGoodsDetailDto.setTotalDiscountAmount(0);
        cartGoodsDetailDto.setSalePrice(cartGoods.getFinalPrice());
        cartGoodsDetailDto.setOriginalProductType(cartGoods.getGoodsType());
        cartGoodsDetailDto.setPicture(cartGoods.getPic());
        cartGoodsDetailDto.setQty(cartGoods.getQty());
        cartGoodsDetailDto.setActivityType(cartGoods.getActivityType());
        cartGoodsDetailDto.setNodeId(cartGoods.getNodeId());
        cartGoodsDetailDto.setCategoryName(cartGoods.getCategoryName());
        cartGoodsDetailDto.setCouponCode(cartGoods.getCouponCode());
        cartGoodsDetailDto.setStockLimit(cartGoods.isStockLimit());
        cartGoodsDetailDto.setProductCode(cartGoods.getCustomerCode());
        cartGoodsDetailDto.setCustomerCode(cartGoods.getCustomerCode());
        cartGoodsDetailDto.setWeight(cartGoods.getWeight());
        cartGoodsDetailDto.setUnit(cartGoods.getUnit());
        cartGoodsDetailDto.setActivityDiscountsDtos(new ArrayList<>());
        cartGoodsDetailDto.setTotalDiscountAmount(0);
        cartGoodsDetailDto.setSpecialExtra(cartGoods.getSpecialExtra());
        cartGoodsDetailDto.setClassificationId(cartGoods.getClassificationId());
        cartGoodsDetailDto.setClassificationName(cartGoods.getClassificationName());
        //菜单购月享卡信息
        cartGoodsDetailDto.setIsMonthCard(cartGoods.getIsMonthCard());
        cartGoodsDetailDto.setMonthCardInfo(cartGoods.getMonthCardInfo());
        cartGoodsDetailDto.setIsB3S1Coupon(cartGoods.getIsB3S1Coupon());
        cartGoodsDetailDto.setB3S1CouponGoodsInfo(cartGoods.getB3S1CouponGoodsInfo());
        cartGoodsDetailDto.setIsB3S1CouponGoods(cartGoods.getIsB3S1CouponGoods());
        if (GoodsTypeEnum.SET_MEAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
            cartGoodsDetailDto.setProductType(ProductType.SETMEAL.getCode());
        } else if(GoodsTypeEnum.VIRTUAL_GOODS.getGoodsType().equals(cartGoods.getGoodsType())){
            cartGoodsDetailDto.setProductType(ProductType.VIRTUAL_PRODUCT.getCode());
        }

        //小料
        if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            List<ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods> materialList = new ArrayList<>(0);
            for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods goods = new ShoppingCartGoodsDto.CartGoodsDetailDto.MaterialGoods();
                goods.setSpuId(materialGoods.getSpuId());
                goods.setSpuName(materialGoods.getSpuName());
                goods.setOriginalPrice(materialGoods.getOriginalPrice());
                goods.setSalePrice(materialGoods.getFinalPrice());
                goods.setCustomerCode(materialGoods.getCustomerCode());
                goods.setProductCode(materialGoods.getCustomerCode());
                goods.setQty(cartGoods.getQty());
                goods.setTotalDiscountAmount(0);
                goods.setOriginalProductType(materialGoods.getOriginalProductType());
                materialList.add(goods);
            }
            cartGoodsDetailDto.setMaterialList(materialList);
        }
        // 设置总优惠&售价
        List<ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra> cartGoodsExtras = BeanUtil.convertBeans(cartGoods.getExtra(), ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra::new);
        cartGoodsDetailDto.setExtraList(cartGoodsExtras);
        //61: 单品买M赠N  \  62:买赠  \ 6:买M赠N
//        if (ObjectUtils.equals(ActivityTypeEnum.TYPE_61.getCode(), cartGoods.getActivityType()) || ObjectUtils.equals(ActivityTypeEnum.TYPE_6.getCode(), cartGoods.getActivityType())
//                || ObjectUtils.equals(ActivityTypeEnum.TYPE_62.getCode(), cartGoods.getActivityType())) {
//            cartGoodsDetailDto.setTotalDiscountAmount(cartGoods.getOriginalAmount().intValue() - cartGoods.getAmount().intValue());
//        } else {
//            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> collect = apportionGoodsList.stream().filter(a -> ObjectUtils.equals(cartGoods.getCartGoodsUid(), a.getCartGoodsUid())).collect(Collectors.toList());
//            //List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> collect = apportionGoodsList.stream().filter(a -> ObjectUtils.equals(cartGoods.getSkuId(), a.getGoodsId()) || ObjectUtils.equals(cartGoods.getSpuId(), a.getGoodsId())).collect(Collectors.toList());
//            if (CollectionUtils.isNotEmpty(collect)) {
//                setTotalDiscountAndSalePrice(collect, cartGoodsDetailDto, duplicateGoodsMap);
//                // 设置商品行，优惠活动均摊
//                setActivityDiscounts(collect, cartGoodsDetailDto, duplicateGoodsMap);
//            }
//        }
        return cartGoodsDetailDto;
    }

    /**
     *  活动级别的促销均摊
     * 获取当前商品的售后价格
     *
     * @param apportionGoodsList 促销均摊列表
     * @param cartGoodsDetailDto 当前商品行
     * @param duplicateGoodsMap 当前商品行  此map是为了促销除不尽时，拆商品行所用，例如，3份折扣10元
     * key为：goodsId；value以逗号分割：0为goodsId分组对应的数量，value为已计算的折扣金额
     *
     */
    private void setTotalDiscountAndSalePrice(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList, ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto, Map<String, String> duplicateGoodsMap) {
        Long originalPrice = cartGoodsDetailDto.getOriginalPrice();
        Long discountPrice = 0L;
        int goodsTotalQty = apportionGoodsList.stream().mapToInt(apportionGoods -> apportionGoods.getGoodsQuantity()).sum();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGoods : apportionGoodsList) {
            //折扣=所有折扣和*百分比（当前行商品数量/购物车总商品数量）
            discountPrice += apportionGoods.getApportionDetails().stream().filter(d -> ObjectUtils.notEqual(ActivityTypeEnum.TYPE_32.getCode(), d.getActivityType())
                    && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_104.getCode(), d.getActivityType()) //X件Y折
                    && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_2.getCode(), d.getActivityType()) //单品特价
                    && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_21.getCode(), d.getActivityType())//单品折扣
            ).mapToLong(t -> t.getActivityApportionAmount() * apportionGoods.getGoodsQuantity()).sum() * cartGoodsDetailDto.getQty() / goodsTotalQty;
        }
        String currentGoodsIdMap = duplicateGoodsMap.get(cartGoodsDetailDto.getCartGoodsUid());
        if (currentGoodsIdMap != null) {
            String[] value = currentGoodsIdMap.split(",");
            //不是最后一行商品，折扣为discountPrice
            if (Integer.parseInt(value[0]) > 1) {
                int totalDiscountPrice = Integer.parseInt(value[1]) + discountPrice.intValue();
                int index = Integer.parseInt(value[0]) - 1;
                duplicateGoodsMap.put(cartGoodsDetailDto.getCartGoodsUid(), String.format("%s,%s", index, totalDiscountPrice));
            } else {
                //最后一行
                Long totalDiscountAmount = 0L;
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGoods : apportionGoodsList) {
                    totalDiscountAmount += apportionGoods.getApportionDetails().stream().filter(d -> ObjectUtils.notEqual(ActivityTypeEnum.TYPE_32.getCode(), d.getActivityType())
                            && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_104.getCode(), d.getActivityType())
                            && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_2.getCode(), d.getActivityType())
                            && ObjectUtils.notEqual(ActivityTypeEnum.TYPE_21.getCode(), d.getActivityType())
                    ).mapToLong(t -> t.getActivityApportionAmount() * apportionGoods.getGoodsQuantity()).sum();
                }
                //折扣为：总折扣金额-已折扣金额
                discountPrice = totalDiscountAmount - Integer.parseInt(value[1]);
            }
        }
        cartGoodsDetailDto.setTotalDiscountAmount(discountPrice.intValue());
        cartGoodsDetailDto.setSalePrice(originalPrice - discountPrice / cartGoodsDetailDto.getQty());
    }

    private void setActivityDiscounts(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList, ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto, Map<String, String> duplicateGoodsMap) {
        List<ActivityDiscountsDto> activityDiscountsDtoList = new ArrayList<>();
        int goodsTotalQty = apportionGoodsList.stream().mapToInt(apportionGoods -> apportionGoods.getGoodsQuantity()).sum();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGoods : apportionGoodsList) {
            /**
             * 1. 商品券：cartGoodsDetailDto.couponCode非空，保留ApportionGoods#ApportionDetails#apportionType中32的
             * 2. 普通商品：cartGoodsDetailDto.couponCode空，去掉32的
             */
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails> apportionDetails = apportionGoods.getApportionDetails().stream()
                    .filter(detail -> !detail.getActivityType().equals(ActivityTypeEnum.TYPE_32.getCode())
                    && !detail.getActivityType().equals(ActivityTypeEnum.TYPE_37.getCode())
                            && !detail.getActivityType().equals(ActivityTypeEnum.TYPE_38.getCode()) && !detail.getActivityType().equals(ActivityTypeEnum.TYPE_104.getCode())
                            && !detail.getActivityType().equals(ActivityTypeEnum.TYPE_2.getCode()) && !detail.getActivityType().equals(ActivityTypeEnum.TYPE_21.getCode())).collect(Collectors.toList());
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails detail : apportionDetails) {
                List<ActivityDiscountsDto> currentDiscount = activityDiscountsDtoList.stream().filter(discount -> ObjectUtils.equals(discount.getActivityCode(), detail.getActivityCode())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(currentDiscount)) {
                    currentDiscount.get(0).setDiscountAmount(currentDiscount.get(0).getDiscountAmount() + detail.getActivityApportionAmount().intValue() * apportionGoods.getGoodsQuantity() * cartGoodsDetailDto.getQty() / goodsTotalQty);
                } else {
                    ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                    activityDiscountsDto.setActivityCode(detail.getActivityCode());
                    activityDiscountsDto.setActivityName(detail.getActivityName());
                    activityDiscountsDto.setActivityType(detail.getActivityType());
                    activityDiscountsDto.setDiscountAmount(detail.getActivityApportionAmount().intValue() * apportionGoods.getGoodsQuantity() * cartGoodsDetailDto.getQty() / goodsTotalQty);
                    activityDiscountsDtoList.add(activityDiscountsDto);
                }
            }
        }
        cartGoodsDetailDto.setActivityDiscountsDtos(activityDiscountsDtoList);
    }
}
