package cn.freemud.service.impl.calculate.promotion;

import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.calculate.CalculationSharingDiscountResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.CalculationGoodsType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.ItemService;
import cn.freemud.service.impl.AssortmentSdkService;
import com.alibaba.fastjson.JSON;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: cn.freemud.service.impl.calculate.promotion AdditionSharingService
 * @Description: 加价购商品
 * @author: pengfei.liu
 * @date: 2020/11/26
 * @Copyright: www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
@Slf4j
public class BuyOneGiveOneSendService {

    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    public void giftResponse(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsList
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , ActivityQueryDto activityQueryDto
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        if(discountResult == null){
            return;
        }

        //  过略出来买一赠一寄杯活动，没有直接返回
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Discount> discounts = discountResult.getDiscounts();
        if(null == discounts || discounts.isEmpty()){
            return;
        }
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.Discount> buyOneGiveOneSendDiscounts = discounts
                .stream()
                .filter(discount -> ObjectUtils.equals(discount.getType(),ActivityTypeEnum.TYPE_63.getCode()))
                .collect(Collectors.toList());
        if(null == buyOneGiveOneSendDiscounts || buyOneGiveOneSendDiscounts.isEmpty()){
            return;
        }

        if (discountResult == null || CollectionUtils.isEmpty(discountResult.getGoods())) {
            return;
        }
        String menuType = shoppingCartInfoRequestVo == null ? null : shoppingCartInfoRequestVo.getMenuType();
        // 构建赠品detail
        List<ProductBeanDTO> beanDTOList = this.drawGiftInfo(discountResult, activityQueryDto, menuType);
        this.setCartGoods(discountResult, cartGoodsList, beanDTOList);

        // 设置用户可以选择的寄送商品券码
        this.buildSendGoods(discountResult,shoppingCartGoodsResponseVo);
    }

    /**
     * 抽取赠品
     * goodsId->goods
     *
     * @param discountResult
     * @return
     */
    private List<String> getProductIdsForGift(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult) {

        List<String> gifts = new ArrayList<>();
        if (CollectionUtils.isEmpty(discountResult.getGoods())) {
            return gifts;
        }
        gifts = discountResult.getGoods()
                .stream()
                .filter(d -> CalculationGoodsType.TYPE_1.getType().equals(d.getCartGoodType()))
                .map(CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods::getGoodsId)
                .collect(Collectors.toList());
        return gifts;
    }

    /**
     * 转换参加促销的商品为Map<goodsId,Goods>
     *
     * @param discountResult
     * @return
     */
    public Map<String, CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods> getDiscountForGift(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult) {

        Map<String, CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods> gifts = discountResult.getGoods()
                .stream()
                .filter(d -> CalculationGoodsType.TYPE_1.getType().equals(d.getCartGoodType()))
                .collect(Collectors.toMap(CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        return gifts;
    }

    /**
     * 赠品detail
     *
     * @param discountResult
     * @param activityQueryDto
     * @param menuType
     */
    private List<ProductBeanDTO> drawGiftInfo(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , ActivityQueryDto activityQueryDto, String menuType) {

        List<ProductBeanDTO> productBeanList = new ArrayList<>();
        // 抽取赠品
        List<String> gifts = this.getProductIdsForGift(discountResult);

        if (CollectionUtils.isEmpty(gifts)) return productBeanList;

        productBeanList = assortmentSdkService.getProductsInfoSdk(activityQueryDto.getPartnerId()
                , activityQueryDto.getStoreId(), gifts, menuType, shoppingCartBaseService);
        if (CollectionUtils.isEmpty(productBeanList)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GIFTS_PRODUCT_NOT_EXIST);
        }
        return productBeanList;
    }

    /**
     * 响应购物车行
     */
    public void setCartGoods(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsLists
            , List<ProductBeanDTO> products) {

        if (CollectionUtils.isEmpty(products)) return;

        // 转换参加促销的商品为Map<goodsId,Goods>
        Map<String, CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods> discountForGift = this.getDiscountForGift(discountResult);

        List<CartGoods> cartGoodsList = new ArrayList<>();
        for (ProductBeanDTO product : products) {
            String k = product.getPid();
            CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods goods = discountForGift.get(k);
            CalculationSharingDiscountResponseDto.CalculationDiscountResult.Goods.GoodsDiscount discount = goods.getDiscounts()
                    .stream()
                    .filter(g -> ActivityTypeEnum.TYPE_63.getCode().equals(g.getType()))
                    .findFirst()
                    .get();
            CartGoods cartGood = new CartGoods();
            cartGood.setGoodsId(goods.getGoodsId());
            cartGood.setGoodsType(1);
            cartGood.setSpuId(goods.getGoodsId());
            cartGood.setSkuId(goods.getGoodsId());
            cartGood.setOriginalPrice(product.getFinalPrice());
            cartGood.setPackPrice(product.getPackPrice());
            cartGood.setOriginalAmount(goods.getOriginalPrice() * goods.getGoodsQuantity());
            cartGood.setAmount(goods.getRealAmount());
            cartGood.setName(product.getName());
            cartGood.setSpuName(product.getName());
            cartGood.setCategoryName(product.getName());
            cartGood.setPic(product.getPicture());
            cartGood.setSkuName(product.getName());
            cartGood.setActivityType(discount.getType());
            cartGood.setStockLimit(ObjectUtils.equals(1, product.getStockLimit()));
            cartGood.setCustomerCode(product.getCustomerCode());
            cartGood.setUnit(product.getUnit());
            cartGood.setWeight(product.getWeight());
            cartGood.setQty(goods.getGoodsQuantity());
            cartGood.setClassificationId(product.getCategory());
            cartGood.setClassificationName(product.getCategoryName());
            // nodeId标识activeCode,用于计算均摊时每个商品在每个活动上均摊金额
            cartGood.setNodeId(discount.getActivityCode());
            cartGoodsList.add(cartGood);
        }
        cartGoodsLists.addAll(cartGoodsList);
    }

    /**
     * 抽取赠品
     * goodsId->goods
     *
     * @param discountResult
     * @return
     */
    private void buildSendGoods(CalculationSharingDiscountResponseDto.CalculationDiscountResult discountResult,ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        // 赠送、换购商品信息集合
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.SendActivity> sendGoods = discountResult.getSendGoods();
        if(sendGoods == null || sendGoods.isEmpty()){
            return;
        }

        // 抽取买一赠一寄件活动送的商品
        List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.SendActivity> buyOneGiveOneSendGoods = sendGoods
                                                                                                        .stream()
                                                                                                        .filter(sendGood -> ObjectUtils.equals(sendGood.getActivityType(),ActivityTypeEnum.TYPE_63.getCode()))
                                                                                                        .collect(Collectors.toList());

        if(null == buyOneGiveOneSendGoods || buyOneGiveOneSendGoods.isEmpty()){
            return;
        }

        List<ShoppingCartGoodsResponseVo.chooseGood> chooseGoods = shoppingCartGoodsResponseVo.getChooseGoods() == null ? new ArrayList<>() : shoppingCartGoodsResponseVo.getChooseGoods();
        buyOneGiveOneSendGoods.forEach(sendActivity ->{

            // 这个是真正的送的券
            List<CalculationSharingDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> innerSendGoods = sendActivity.getSendGoods();
            if(innerSendGoods == null || innerSendGoods.isEmpty()){
                return;
            }

            innerSendGoods.forEach(innerSendGood -> {
                ShoppingCartGoodsResponseVo.chooseGood  chooseGood = new ShoppingCartGoodsResponseVo.chooseGood();
                chooseGood.setActiveType(sendActivity.getActivityType());
                chooseGood.setCouponCode(innerSendGood.getSendCouponCode());
                chooseGood.setCouponName(innerSendGood.getSendCouponName());
                chooseGood.setSendCoupon(innerSendGood.getSendCoupon());
                chooseGood.setGoodsName(innerSendGood.getGoodsName());
                chooseGoods.add(chooseGood);
            });

        });

        shoppingCartGoodsResponseVo.setChooseGoods(chooseGoods);

    }
}