package cn.freemud.service.impl;

import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.UserLoginInfoDto;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.ShareDiscountActivityDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.IPromotionService;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.google.common.collect.Lists;
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.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 * 单品买M赠N
 * @version V1.0
 * @Title: BuySendPromotionService
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: jiaxin.liu
 * @date: 2019/4/18 10:59
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class BuySendPromotionService implements IPromotionService {

    private final static Integer SEND_NUMBER = 1;

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

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        shoppingCartGoodsResponseVo.setBuyOneGetActivity(new ActivityTip());
        if (calculationDiscountResult == null) {
            return;
        }
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivityList = calculationDiscountResult.getSendGoods();
        if (CollectionUtils.isEmpty(sendActivityList)) {
            return;
        }
        //ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity sendActivity = getSendActivity(sendActivityList, ActivityTypeEnum.TYPE_61);
        //if (sendActivity == null) {
        //    return;
        //}
        //Todo 获取多个赠品list
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivityLists = getSendActivityList(ActivityTypeEnum.TYPE_61, sendActivityList);

        //Todo 获取多个赠品list
        if (sendActivityLists.size() == 0) {
            return;
        }

        //List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsList = sendActivity.getSendGoods();
        //if (CollectionUtils.isEmpty(sendGoodsList)) {
        //    return;
        //}
        //Integer maxNum = sendActivity.getMaxNum();
        //List<String> activitySpuIds = sendGoodsList.stream().map(each -> each.getCategory()).collect(Collectors.toList());
        //Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsMap = getSendGoodsMap(sendGoodsList);
        //Todo
        List<String> activitySpuIds = new ArrayList<>();
        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsMap = new HashMap<>();
        //Map<String, Integer> maxNums = new HashMap<>();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity activityList : sendActivityLists) {
            for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods sendGood : activityList.getSendGoods()) {
                sendGoodsMap.put(sendGood.getGoodsId(), sendGood);
                //maxNums.put(sendGood.getGoodsId(), activityList.getMaxNum());
                activitySpuIds.add(sendGood.getGoodsId());
            }
        }
        activitySpuIds = activitySpuIds.stream().distinct().collect(Collectors.toList());
        List<CartGoods> newCartGoodsList = new ArrayList<>();
        for (CartGoods cartGood : cartGoodsList) {
            /*if (cartGoodsList.stream().filter(c -> c.getSkuId().equals(cartGood.getSkuId())).count() >= 2){
                break;
            }*/
            if (StringUtils.isNotBlank(cartGood.getSkuId())) {
                // 多规格
                putNewCartGoodsList(sendGoodsMap, cartGood, newCartGoodsList, true);
            } else {
                // 单品
                putNewCartGoodsList(sendGoodsMap, cartGood, newCartGoodsList, false);
            }
        }
        //更新商品详情信息
        updateSendGooodsInfo(newCartGoodsList,activityQueryDto,shoppingCartInfoRequestVo);
        //价格从低到高筛选出maxNum个,并将价格设置为0
        newCartGoodsList.sort(Comparator.comparing(CartGoods::getOriginalPrice));
        // 优惠商品总包装费
        Long givePackAmount = 0L;
        // 优惠商品原总价格
        Long giveTotalAmount = 0L;
        /*
        for (CartGoods cartGoods : newCartGoodsList) {
            cartGoods.setAmount(0L);
            if (maxNum <= 0) {
                break;
            }
            if (maxNum >= cartGoods.getQty()) {
                maxNum = maxNum - cartGoods.getQty();
            } else {
                cartGoods.setQty(maxNum);
                maxNum = 0;
            }
            givePackAmount = givePackAmount + cartGoods.getPackPrice() * cartGoods.getQty();
            giveTotalAmount = giveTotalAmount + cartGoods.getOriginalPrice() * cartGoods.getQty();
            cartGoods.setOriginalAmount(cartGoods.getOriginalPrice() * cartGoods.getQty());
            cartGoodsList.add(cartGoods);
        }
        */
        for (CartGoods cartGoods : newCartGoodsList) {
            //Integer max = maxNums.get(cartGoods.getGoodsId());
            ////if (max <= 0) continue;
            //if (max < cartGoods.getQty()) {
            //    cartGoods.setQty(max);
            //}
            givePackAmount = givePackAmount + cartGoods.getPackPrice() * cartGoods.getQty();
            giveTotalAmount = giveTotalAmount + cartGoods.getOriginalPrice() * cartGoods.getQty();
            cartGoods.setOriginalAmount(cartGoods.getOriginalPrice() * cartGoods.getQty());
            cartGoodsList.add(cartGoods);
        }
        Integer activityCartQty = cartGoodsList.stream().filter(each -> Objects.equals(each.getActivityType(), ActivityTypeEnum.TYPE_61.getCode())).mapToInt(each -> each.getQty()).sum();
        ActivityTip activityTip = new ActivityTip();
        activityTip.setActivityType(ActivityTypeEnum.TYPE_61.getCode());
        //activityTip.setActivityQty(sendActivity.getMaxNum());
        activityTip.setActivityCartQty(activityCartQty);
        activityTip.setActivitySpuIds(activitySpuIds);
        // 当maxNum>=minNum，在加入买一赠一商品时提示“您参加的买赠优惠最多赠送N件哦～”
        shoppingCartGoodsResponseVo.setBuyOneGetActivity(activityTip);
        Long packAmount = Objects.isNull(shoppingCartGoodsResponseVo.getNewPackAmount()) ? 0L : shoppingCartGoodsResponseVo.getNewPackAmount();
        shoppingCartGoodsResponseVo.setNewPackAmount(givePackAmount + packAmount);
        Long originalTotalAmount = Objects.isNull(shoppingCartGoodsResponseVo.getOriginalTotalAmount()) ? 0L : shoppingCartGoodsResponseVo.getOriginalTotalAmount();
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(originalTotalAmount + giveTotalAmount);
        Long totalDiscountAmount = Objects.isNull(shoppingCartGoodsResponseVo.getTotalDiscountAmount()) ? 0L : shoppingCartGoodsResponseVo.getTotalDiscountAmount();
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(totalDiscountAmount + giveTotalAmount);
    }

    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (calculationDiscountResult == null) {
            return;
        }
        //添加促销活动
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendGoods1 = calculationDiscountResult.getSendGoods() == null ? new ArrayList<>() : calculationDiscountResult.getSendGoods().stream().filter(t -> ObjectUtils.equals(ActivityTypeEnum.TYPE_6.getCode(), t.getActivityType()) || ObjectUtils.equals(ActivityTypeEnum.TYPE_61.getCode(), t.getActivityType())).collect(Collectors.toList());
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsDto.getActivityDiscountsDtos();
        if (CollectionUtils.isNotEmpty(sendGoods1)) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity sendActivity = sendGoods1.get(0);
            Integer discountAmount = shoppingCartGoodsDto.getProducts().stream().filter(product -> ObjectUtils.equals(product.getActivityType(), sendActivity.getActivityType())).mapToInt(ShoppingCartGoodsDto.CartGoodsDetailDto::getTotalDiscountAmount).sum();
            //设置优惠活动
            ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
            activityDiscountsDto.setActivityCode(sendActivity.getActivityCode());
            activityDiscountsDto.setActivityName(sendActivity.getActivityName());
            activityDiscountsDto.setActivityType(sendActivity.getActivityType());
            activityDiscountsDto.setDiscountAmount(0 - discountAmount);
            activityDiscountsDtos.add(activityDiscountsDto);

            // 设置商品行优惠明细
            List<ShoppingCartGoodsDto.CartGoodsDetailDto> buyAndSendProducts = shoppingCartGoodsDto.getProducts().stream().filter(product -> ObjectUtils.equals(product.getActivityType(), sendActivity.getActivityType())).collect(Collectors.toList());
            for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto : buyAndSendProducts) {
                List<ActivityDiscountsDto> activityDiscountsDtoList = cartGoodsDetailDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : cartGoodsDetailDto.getActivityDiscountsDtos();
                ActivityDiscountsDto ProductActivityDiscountsDto = new ActivityDiscountsDto();
                ProductActivityDiscountsDto.setActivityCode(sendActivity.getActivityCode());
                ProductActivityDiscountsDto.setActivityName(sendActivity.getActivityName());
                ProductActivityDiscountsDto.setActivityType(sendActivity.getActivityType());
                ProductActivityDiscountsDto.setDiscountAmount(cartGoodsDetailDto.getTotalDiscountAmount());
                activityDiscountsDtoList.add(ProductActivityDiscountsDto);
                cartGoodsDetailDto.setActivityDiscountsDtos(activityDiscountsDtoList);
            }
        }
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
    }

    /**
     * 获取指定促销类型的SendActivity
     *
     * @param sendActivityList
     * @param type
     * @return
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity getSendActivity
    (List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivityList, ActivityTypeEnum
            type) {
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity sendActivity : sendActivityList) {
            if (Objects.equals(sendActivity.getActivityType(), type.getCode())) {
                return sendActivity;
            }
        }
        return null;
    }

    /**
     * 获取指定促销类型的SendActivity
     *
     * @param sendActivityList
     * @param type
     * @return
     */
    private List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> getSendActivityList(ActivityTypeEnum type,
                                                                                                                    List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> sendActivityList) {
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity> collect = sendActivityList.stream().filter(c -> c.getActivityType().equals(type.getCode())).collect(Collectors.toList());
        return collect;
    }

    /**
     * 筛选出spu商品中价格最低的商品，Key=spuId
     *
     * @param sendGoodsList
     * @return
     */
    private Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> getSendGoodsMap
    (List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsList) {
        Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> goodsMap;
        goodsMap = sendGoodsList.stream().collect(Collectors.toMap(ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods::getCategory, Function.identity(), (k1, k2) -> k1));
        for (Map.Entry<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> entry : goodsMap.entrySet()) {
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sends = sendGoodsList.stream().filter(each -> each.getCategory().equals(entry.getKey())).collect(Collectors.toList());
            sends.sort(Comparator.comparing(each -> each.getNowPrice()));
            goodsMap.put(entry.getKey(), sends.get(0));
        }
        return goodsMap;
    }

    /**
     * 将赠品存入新的List
     *
     * @param sendGoodsMap
     * @param cartGood
     * @param manyOrSingle true-多规格，false-单品
     */
    private void putNewCartGoodsList(Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods> sendGoodsMap, CartGoods
            cartGood, List<CartGoods> newCartGoodsList, boolean manyOrSingle) {
        if (sendGoodsMap.get(cartGood.getGoodsId()) == null) {
            return;
        }
        if (manyOrSingle) {
            // 多规格
            if (!Objects.equals(sendGoodsMap.get(cartGood.getSkuId()).getGoodsId(), cartGood.getSkuId())) {
                return;
            }
        } else {
            // 单品
            List<String> spuIds = newCartGoodsList.stream().map(CartGoods::getSpuId).collect(Collectors.toList());
            if (spuIds.contains(cartGood.getSpuId())) {
                return;
            }
        }
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult.SendActivity.SendGoods sendGoods = sendGoodsMap.get(cartGood.getGoodsId());
        CartGoods cartGoods = shoppingCartConvertAdapter.convent2CartGoods(cartGood, sendGoods.getNowPrice());
        cartGoods.setClassificationId(cartGood.getClassificationId());
        cartGoods.setClassificationName(cartGood.getClassificationName());
        cartGoods.setQty(sendGoods.getSendNumber() > 0 ? sendGoods.getSendNumber() : SEND_NUMBER);
        newCartGoodsList.add(cartGoods);

    }


    /**
     * 更新赠品信息
     * 例如：weight、unit字段
     * @param newCartGoodsList
     */
    private void updateSendGooodsInfo(List<CartGoods> newCartGoodsList,ActivityQueryDto activityQueryDto,ShoppingCartInfoRequestVo shoppingCartInfoRequestVo){
        List<String> goodsIds = newCartGoodsList.stream().map(CartGoods::getGoodsId).collect(Collectors.toList());
        List<ProductBeanDTO> productBeanList = assortmentSdkService.getProductsInfoSdk(activityQueryDto.getPartnerId()
                , activityQueryDto.getStoreId(), goodsIds, shoppingCartInfoRequestVo==null?null:shoppingCartInfoRequestVo.getMenuType() ,shoppingCartBaseService);
        if (CollectionUtils.isEmpty(productBeanList)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GIFTS_PRODUCT_NOT_EXIST);
        }

        for (CartGoods cartGoods :newCartGoodsList) {
            Optional<ProductBeanDTO> productBeanDTO = productBeanList.stream().filter(productBean -> ObjectUtils.equals(productBean.getPid(), cartGoods.getGoodsId())).findFirst();
            if (!productBeanDTO.isPresent()) {
                continue;
            }
            cartGoods.setUnit(productBeanDTO.get().getUnit());
            cartGoods.setWeight(productBeanDTO.get().getWeight());
        }
    }
}
