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

import cn.freemud.entities.dto.UserLoginInfoDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.calculate.CalculationDiscountResult;
import cn.freemud.entities.dto.calculate.Goods;
import cn.freemud.entities.dto.calculate.GoodsDiscount;
import cn.freemud.entities.dto.product.info.ProductBean;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CartGoods;
import cn.freemud.entities.vo.ShoppingCartInfoRequestVo;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.CalculationGoodsType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.active.ActiveFactory;
import cn.freemud.service.active.ActiveService;
import cn.freemud.service.cache.GiftCacheManager;
import cn.freemud.service.impl.BuyAndGiftsPromotionService;
import cn.freemud.service.impl.calculate.CalculationCommonService;
import cn.freemud.service.product.ProductInfoManager;
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.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 GiftSharingService
 * @Description: 赠品处理
 * @author: family
 * @date: 2020/9/9
 * @Copyright: www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class GiftSharingService {

    @Autowired
    private BuyAndGiftsPromotionService buyAndGiftsPromotionService;
    @Autowired
    private GiftCacheManager giftCacheManager;
    @Autowired
    private ProductInfoManager productInfoManager;
    @Autowired
    private CalculationCommonService calculationCommonService;
    @Autowired
    private ActiveFactory activeFactory;

    public void giftResponse(CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsList
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , ActivityQueryDto activityQueryDto
            , String partnerId
            , String storeId
            , String userId
            , Integer flag) {

        if (discountResult == null || CollectionUtils.isEmpty(discountResult.getGoods())) {
            return;
        }
        String menuType = shoppingCartInfoRequestVo == null ? null : shoppingCartInfoRequestVo.getMenuType();
        List<ProductBean> beanDTOList = this.drawGiftInfo(discountResult, activityQueryDto, menuType);
        this.setCartGoods(discountResult, cartGoodsList, beanDTOList,shoppingCartInfoRequestVo, partnerId, storeId, userId, flag);
    }

    /**
     * 抽取赠品
     * goodsId->goods
     *
     * @param discountResult
     * @return
     */
    private List<String> getProductIdsForGift(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(Goods::getGoodsId)
                .collect(Collectors.toList());
        return gifts;
    }

    public Map<String, Goods> getDiscountForGift(CalculationDiscountResult discountResult) {

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

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

        List<ProductBean> productBeanList = new ArrayList<>();
        List<String> gifts = this.getProductIdsForGift(discountResult);

        if (CollectionUtils.isEmpty(gifts)) return productBeanList;
        productBeanList = productInfoManager.getProductsInfo(activityQueryDto.getPartnerId(), activityQueryDto.getStoreId(), menuType, true, gifts);
        if (CollectionUtils.isEmpty(productBeanList)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GIFTS_PRODUCT_NOT_EXIST);
        }
        return productBeanList;
    }

    /**
     * 响应购物车行
     */
    public void setCartGoods(CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsLists
            , List<ProductBean> products
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , String partnerId
            , String storeId
            , String userId
            , Integer flag) {

        if (CollectionUtils.isEmpty(products)) return;

        //Map<String, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> discountForGift = this.getDiscountForGift(discountResult);

        List<CartGoods> cartGoodsList = new ArrayList<>();
        ActiveService activeService = activeFactory.getGifAddCartService(partnerId);
        activeService.gifAddCart(cartGoodsLists,cartGoodsList, products,shoppingCartInfoRequestVo,discountResult,partnerId, storeId, userId, flag);

        cartGoodsLists.addAll(cartGoodsList);
    }

    /**
     * 赠品均摊
     *
     * @param discountResult
     * @param activityQueryDto
     * @param menuType
     */
    public void equally(CalculationDiscountResult discountResult
            , List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtoList
            , ActivityQueryDto activityQueryDto
            , String menuType
            , UserLoginInfoDto userLoginInfoDto) {
        if (discountResult == null || CollectionUtils.isEmpty(discountResult.getGoods())) {
            return;
        }
        List<ProductBean> beanDTOList = this.drawGiftInfo(discountResult, activityQueryDto, menuType);
        this.doCartGoodsDetailDto(discountResult, cartGoodsDetailDtoList, activityQueryDto, beanDTOList, userLoginInfoDto);
    }

    /**
     * 均摊
     *
     * @param discountResult
     * @param products
     * @return
     */
    private void doCartGoodsDetailDto(CalculationDiscountResult discountResult
            , List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtoList
            ,ActivityQueryDto activityQueryDto
            , List<ProductBean> products
            , UserLoginInfoDto userLoginInfoDto) {

        if (CollectionUtils.isNotEmpty(products)) {
            List<CartGoods> list = new ArrayList<>();
            Map<String, Goods> discountForGift = this.getDiscountForGift(discountResult);
            for (ProductBean product : products) {
                Goods goods = discountForGift.get(product.getPid());
                GoodsDiscount discount = this.discountInfo(goods);
                ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = new ShoppingCartGoodsDto.CartGoodsDetailDto();
                CartGoods cartGood = new CartGoods();
                cartGood.setGoodsId(goods.getGoodsId());
                cartGood.setGoodsType(1);
                cartGood.setSpuId(Objects.equals(product.getIsSkuProduct(), 1) ? product.getSpecProductId() : 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.setActivityCode(discount.getActivityCode());
                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());
                list.addAll(buyAndGiftsPromotionService.setGiftExtra(cartGood, product, null));
            }
            // 因为有涉及到用户选择的属性，存入redis
            list = giftCacheManager.resetGiftCache(list, null, activityQueryDto.getPartnerId(), activityQueryDto.getStoreId(), userLoginInfoDto.getMemberId());
            List<ShoppingCartGoodsDto.CartGoodsDetailDto> detail = new ArrayList<>();
            list.forEach(c -> {
                Goods goods = discountForGift.get(c.getGoodsId());
                ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = calculationCommonService.convertCartGoods2DetailGoodsList(goods, c, activityQueryDto.getPartnerId());
                cartGoodsDetailDtoList.add(cartGoodsDetailDto);
            });
        }
    }

    public GoodsDiscount discountInfo(Goods goods) {
        GoodsDiscount discount = goods.getDiscounts()
                .stream()
                .filter(g -> ActivityTypeEnum.TYPE_63.getCode().equals(g.getType()) || ActivityTypeEnum.TYPE_62.getCode().equals(g.getType()) || ActivityTypeEnum.TYPE_61.getCode().equals(g.getType()) || ActivityTypeEnum.TYPE_230.getCode().equals(g.getType()))
                .findFirst()
                .get();
        return discount;
    }
}