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

import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
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.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.impl.AssortmentSdkService;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
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.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 AssortmentSdkService assortmentSdkService;
    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    @Autowired
    private ActiveFactory activeFactory;

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

        if (discountResult == null || CollectionUtils.isEmpty(discountResult.getGoods())) {
            return;
        }
        String menuType = shoppingCartInfoRequestVo == null ? null : shoppingCartInfoRequestVo.getMenuType();
        List<ProductBeanDTO> beanDTOList = this.drawGiftInfo(discountResult, activityQueryDto, menuType);
        this.setCartGoods(discountResult, cartGoodsList, beanDTOList,shoppingCartInfoRequestVo, partnerId, 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<ProductBeanDTO> drawGiftInfo(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(CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsLists
            , List<ProductBeanDTO> products
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , String partnerId
            , 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,flag);

        cartGoodsLists.addAll(cartGoodsList);
    }

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

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

        List<ShoppingCartGoodsDto.CartGoodsDetailDto> manyCartGoodsDetailDto = new ArrayList<>();
        if (CollectionUtils.isEmpty(products)) cartGoodsDetailDtoList.addAll(manyCartGoodsDetailDto);

        else {
            Map<String, Goods> discountForGift = this.getDiscountForGift(discountResult);
            for (ProductBeanDTO product : products) {
                String k = product.getPid();
                Goods goods = discountForGift.get(k);
                GoodsDiscount discount = this.discountInfo(goods);
                ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = new ShoppingCartGoodsDto.CartGoodsDetailDto();
                cartGoodsDetailDto.setOriginalGoodsUid(goods.getOriginalGoodsUid());
                cartGoodsDetailDto.setCartGoodsUid(goods.getCartGoodsUid());
                cartGoodsDetailDto.setTaxId(product.getTaxId());
                cartGoodsDetailDto.setTax(product.getTax());
                cartGoodsDetailDto.setSpuId(product.getPid());
                cartGoodsDetailDto.setSpuName(product.getName());
                cartGoodsDetailDto.setSkuId(goods.getGoodsId());
                cartGoodsDetailDto.setSkuName(product.getName());
                cartGoodsDetailDto.setIsSendGoods(ObjectUtils.equals(1, goods.getCartGoodType()));
                cartGoodsDetailDto.setSalePrice(product.getOriginalPrice());
                cartGoodsDetailDto.setPicture(product.getPicture());
                cartGoodsDetailDto.setQty(goods.getGoodsQuantity());
                cartGoodsDetailDto.setActivityType(discount.getType());
                cartGoodsDetailDto.setNodeId(discount.getActivityCode());
                cartGoodsDetailDto.setCategoryName(product.getCategoryName());
                cartGoodsDetailDto.setStockLimit(ObjectUtils.equals(1, product.getStockLimit()));
                cartGoodsDetailDto.setProductCode(product.getCustomerCode());
                cartGoodsDetailDto.setCustomerCode(product.getCustomerCode());
                cartGoodsDetailDto.setWeight(product.getWeight());
                cartGoodsDetailDto.setUnit(product.getUnit());
                cartGoodsDetailDto.setActivityDiscountsDtos(new ArrayList<>());
                cartGoodsDetailDto.setClassificationId(product.getCategory());
                cartGoodsDetailDto.setClassificationName(product.getCategoryName());
                cartGoodsDetailDto.setOriginalPrice(product.getOriginalPrice());
                cartGoodsDetailDto.setTotalDiscountAmount(goods.getDiscountAmount().intValue());
                List<ActivityDiscountsDto> activityDto = new ArrayList<>();

                ActivityDiscountsDto dto = new ActivityDiscountsDto();
                dto.setActivityCode(discount.getActivityCode());
                dto.setActivityName(discount.getActivityName());
                dto.setActivityType(discount.getType());
                dto.setDiscountAmount(discount.getDiscount().intValue());
                dto.setActualActivityGoodsNumber(discount.getActualGoodsNumber());
                activityDto.add(dto);
                cartGoodsDetailDto.setActivityDiscountsDtos(activityDto);
                cartGoodsDetailDto.setOriginalProductType(product.getType());
                manyCartGoodsDetailDto.add(cartGoodsDetailDto);
            }
            cartGoodsDetailDtoList.addAll(manyCartGoodsDetailDto);
        }
    }

    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;
    }
}