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

import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.activity.ActivityDiscountsDto;
import cn.freemud.entities.dto.calculate.*;
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.handle.GetActivityMsgHandle;
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.ordercenter.enums.ProductTypeEnum;
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 com.freemud.sdk.api.assortment.shoppingcart.util.ShoppingSdkLogUtil;
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: family
 * @date: 2020/9/14
 * @Copyright: www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Service
public class AdditionSharingService {

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private GetActivityMsgHandle getActivityMsgHandle;


    public void additionResponse(CalculationDiscountResult discountResult
            , List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo
            , ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {

        if (shoppingCartInfoRequestVo == null
                || CollectionUtils.isEmpty(shoppingCartInfoRequestVo.getSendGoods())
                || discountResult == null
                || CollectionUtils.isEmpty(discountResult.getSendGoods())) {
            return;
        }

        //检查是否有加价购商品
        List<SendActivity> sendGoods = discountResult.getSendGoods()
                .stream()
                .filter(s -> ActivityTypeEnum.TYPE_81.getCode().equals(s.getActivityType()))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(sendGoods)) {
            return;
        }
        List<CreateOrderVo.PremiumExchangeActivity.Product> additionalProducts = this.buildPremiumExchangeActivityProduct(shoppingCartInfoRequestVo);
        List<SendActivity> additionalActivityList = discountResult.getSendGoods();
        ResponseResult checkResult = checkAdditionalGoods(additionalProducts, additionalActivityList);
        if (!ObjectUtils.equals(ResponseResult.SUCCESS, checkResult)) {
            throw new ServiceException(checkResult);
        }


        Long totalDiscountPrice = 0L;
        Long totalNowPrice = 0L;
        // goodsId->qty
        Map<String, Integer> map = shoppingCartInfoRequestVo.getSendGoods()
                .stream()
                .collect(Collectors.toMap(ShoppingCartInfoRequestVo.SendGoods::getGoodsId, ShoppingCartInfoRequestVo.SendGoods::getQty));

        //goodsId -> originalPrice
        Map<String, Long> OriginalPrice = sendGoods.get(0)
                .getSendGoods()
                .stream()
                .collect(Collectors.toMap(SendGoods::getGoodsId, SendGoods::getOriginalPrice));

        //goodsId->nowPrice
        Map<String, Long> newPrice = sendGoods.get(0)
                .getSendGoods()
                .stream()
                .collect(Collectors.toMap(SendGoods::getGoodsId, SendGoods::getNowPrice));

        for (String str : map.keySet()) {
            Integer qty = map.get(str);
            if (OriginalPrice.get(str) != null && OriginalPrice.get(str) != 0) {
                totalDiscountPrice += qty * (OriginalPrice.get(str) - newPrice.get(str));
                totalNowPrice      += qty * newPrice.get(str);
            }
        }
        shoppingCartGoodsResponseVo.setTotalAmount(discountResult.getTotalAmount() + totalNowPrice);
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(shoppingCartGoodsResponseVo.getTotalDiscountAmount() + totalDiscountPrice);
    }

    /**
     * 构建加价购商品校验参数
     *
     * @param shoppingCartInfoRequestVo 入参
     * @return 返回商品
     */
    public List<CreateOrderVo.PremiumExchangeActivity.Product> buildPremiumExchangeActivityProduct(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {

        List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = shoppingCartInfoRequestVo.getSendGoods();
        List<String> goodsIds = sendGoods
                .stream()
                .map(ShoppingCartInfoRequestVo.SendGoods::getGoodsId)
                .collect(Collectors.toList());

        Map<String, ShoppingCartInfoRequestVo.SendGoods> goodQtyMap = sendGoods
                .stream()
                .collect(Collectors.toMap(ShoppingCartInfoRequestVo.SendGoods::getGoodsId, Function.identity(), (k1, k2) -> k1));


        List<ProductBeanDTO> productBeanList = assortmentSdkService.getProductsInfoSdk(shoppingCartInfoRequestVo.getPartnerId()
                , shoppingCartInfoRequestVo.getShopId(), goodsIds,shoppingCartInfoRequestVo.getMenuType(), shoppingCartBaseService);

        if (CollectionUtils.isEmpty(productBeanList)) {
            throw new ServiceException(ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST);
        }

        return productBeanList.stream().map(productBean ->{
            CreateOrderVo.PremiumExchangeActivity.Product product = new CreateOrderVo.PremiumExchangeActivity.Product();
            List<ProductBeanDTO.SkuProductBean> skuList = productBean.getSkuList();
            List<String> skuIds = null;
            if (null!=skuList) {
                skuIds = skuList.stream().map(ProductBeanDTO.SkuProductBean::getSkuId).collect(Collectors.toList());
            }
            if (!CollectionUtils.isEmpty(skuIds)) {
                for (String skuId : skuIds) {
                    ShoppingCartInfoRequestVo.SendGoods sendGood = goodQtyMap.get(skuId);
                    if (null != sendGood) {
                        product.setQty(sendGood.getQty());
                        product.setSpuId(productBean.getPid());
                        product.setSkuId(sendGood.getGoodsId());
                        product.setStatus(productBean.getStatus());
                        break;
                    }
                }
            }
            else {
                ShoppingCartInfoRequestVo.SendGoods sendGood = goodQtyMap.get(productBean.getPid());
                if (null != sendGood) {
                    product.setQty(sendGood.getQty());
                    product.setSpuId(sendGood.getGoodsId());
                    product.setSkuId(sendGood.getGoodsId());
                    product.setStatus(productBean.getStatus());
                }
            }
            return product;
        }).collect(Collectors.toList());
    }



    /**
     * check加价购
     *
     * @param additionalProducts     购物车添加的加价购商品
     * @param additionalActivityList 加价购活动
     * @return
     */
    private ResponseResult checkAdditionalGoods(List<CreateOrderVo.PremiumExchangeActivity.Product> additionalProducts
            , List<SendActivity> additionalActivityList) {
        //无加价购活动
        if (CollectionUtils.isEmpty(additionalActivityList)) {
            return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
        }
        //加价购活动中换购商品为空
        List<SendActivity> additionalActivity = additionalActivityList
                .stream()
                .filter(activity -> ObjectUtils.equals(ActivityTypeEnum.TYPE_81.getCode(), activity.getActivityType()))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(additionalActivity)) {
            return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
        }
        //购物车中总加价购数量>每单可换购总数量
        Integer totalAdditionalProductCount = additionalProducts.stream().mapToInt(CreateOrderVo.PremiumExchangeActivity.Product::getQty).sum();
        if (totalAdditionalProductCount > additionalActivity.get(0).getMaxNum()) {
            return ResponseResult.PREMIUM_EXCHANGE_GOODS_OUT_OF_LIMIT;
        }
        //加价购活动中的换购商品列表Map
        Map<String, SendGoods> sendGoodsMap = additionalActivity.get(0).getSendGoods()
                .stream()
                .collect(Collectors.toMap(SendGoods::getGoodsId, Function.identity(), (k1, k2) -> k1));
        for (CreateOrderVo.PremiumExchangeActivity.Product product : additionalProducts) {
            if (ShoppingCartConstant.OFF_LINE_PRODUCT.equals(product.getStatus()) || ShoppingCartConstant.SOLD_OUT_PRODUCT.equals(product.getStatus())) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
            }
            if (ShoppingCartConstant.NOT_ON_LINE_PRODUCT.equals(product.getStatus())) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_ON_LINE;
            }
            // 购物车中加价购商品不在活动商品列表中 或  每个商品的换购数量>活动限制数量
            SendGoods sendGoods = Objects.isNull(sendGoodsMap.get(product.getSkuId())) ? sendGoodsMap.get(product.getSpuId()) : sendGoodsMap.get(product.getSkuId());
            if (Objects.isNull(sendGoods)) {
                return ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST;
            }
            if (product.getQty() > sendGoods.getSendNumber()) {
                return ResponseResult.PREMIUM_EXCHANGE_GOODS_OUT_OF_LIMIT;
            }
        }
        return ResponseResult.SUCCESS;
    }

    /**
     * xxxxxxoooooooooo
     *
     * @param shoppingCartInfoRequestVo
     * @param discountResult
     * @param premiumExchangeActivity
     */
    public void equally(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo
            , ShoppingCartGoodsDto shoppingCartGoodsDto
            , CalculationDiscountResult discountResult
            , CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {

        if (discountResult == null || CollectionUtils.isEmpty(discountResult.getGoods()) || premiumExchangeActivity == null || CollectionUtils.isEmpty(premiumExchangeActivity.getProducts())) {
            return;
        }
        List<Goods> manyHgs = discountResult.getGoods()
                .stream()
                .filter(d -> CalculationGoodsType.TYPE_2.getType().equals(d.getCartGoodType()))
                .collect(Collectors.toList());


        if (CollectionUtils.isEmpty(manyHgs)) {
            throw new ServiceException(ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST);
        }

        //添加商品行
        List<String> productIds = premiumExchangeActivity.getProducts().stream().map(p -> StringUtils.isEmpty(p.getSkuId()) ? p.getSpuId() : p.getSkuId()).collect(Collectors.toList());
        Map<String, GetProductsVo> getProductsVoMap = itemService.getProducts(productIds, shoppingCartInfoRequestVo.getPartnerId(), shoppingCartInfoRequestVo.getShopId(), BusinessTypeEnum.getByType(shoppingCartInfoRequestVo.getMenuType()).getCode());
        if (getProductsVoMap.isEmpty()) {
            throw new ServiceException(ResponseResult.PREMIUM_EXCHANGE_ACTIVITY_NOT_EXIST);
        }
        // 获取计算返回的价格
        Long originalTotalAmount = shoppingCartGoodsResponseVo.getOriginalTotalAmount();
        //Long totalAmount = shoppingCartGoodsDto.getTotalAmount();
        //Long totalDiscountAmount = shoppingCartGoodsDto.getTotalDiscountAmount();
        //加价换购活动总优惠
        for (CreateOrderVo.PremiumExchangeActivity.Product product : premiumExchangeActivity.getProducts()) {

            String goodsId = StringUtils.isEmpty(product.getSkuId()) ? product.getSpuId() : product.getSkuId();
            GetProductsVo getProductsVo = getProductsVoMap.get(goodsId);
            if (null == getProductsVo) {
                continue;
            }
            Goods hgGood = manyHgs.stream().filter(d -> goodsId.equals(d.getGoodsId())).findFirst().orElse(null);
            if (hgGood == null) {
                continue;
            }
            ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = this.getCartGoodsDetailDto(product, getProductsVo, goodsId, hgGood);
            // fisherman 结算页 如果是虚拟商品 需要设置 到 extinfo里面注意 新算价
            if (cartGoodsDetailDto.getProductType().compareTo(ProductTypeEnum.VIRTUAL_PRODUCT.getCode()) == 0) {
                List<CouponMsg> couponData = getActivityMsgHandle.getCouponData(getProductsVo.getProductBindingCouponTypes(), shoppingCartInfoRequestVo.getPartnerId());
                if (CollectionUtils.isNotEmpty(couponData)) {
                    cartGoodsDetailDto.setExtInfo(JSON.toJSONString(couponData));
                }
            }
            shoppingCartGoodsDto.getProducts().add(cartGoodsDetailDto);
            //2.计算优惠价格
            originalTotalAmount += getProductsVo.getFinalPrice();
            //totalDiscountAmount += cartGoodsDetailDto.getTotalDiscountAmount();
            //currenttotalDiscountAmount += cartGoodsDetailDto.getTotalDiscountAmount();
            // 3.设置商品行优惠明细
            GoodsDiscount sendActivity = hgGood.getDiscounts().get(0);
            ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
            activityDiscountsDto.setActivityCode(sendActivity.getActivityCode());
            activityDiscountsDto.setActivityName(sendActivity.getActivityName());
            activityDiscountsDto.setActivityType(ActivityTypeEnum.TYPE_81.getCode());
            activityDiscountsDto.setDiscountAmount(cartGoodsDetailDto.getTotalDiscountAmount());
            List<ActivityDiscountsDto> activityDiscountsDtoList = new ArrayList<>();
            activityDiscountsDtoList.add(activityDiscountsDto);
            cartGoodsDetailDto.setActivityDiscountsDtos(activityDiscountsDtoList);
        }
        shoppingCartGoodsDto.setOriginalTotalAmount(originalTotalAmount);
    }

    public ShoppingCartGoodsDto.CartGoodsDetailDto getCartGoodsDetailDto(CreateOrderVo.PremiumExchangeActivity.Product product
            , GetProductsVo getProductsVo
            , String goodsId
            , Goods hgGood) {

        ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto = new ShoppingCartGoodsDto.CartGoodsDetailDto();
        cartGoodsDetailDto.setOriginalPrice(hgGood.getOriginalPrice());
        cartGoodsDetailDto.setOriginalProductType(getProductsVo.getType());
        cartGoodsDetailDto.setTotalDiscountAmount(hgGood.getDiscountAmount().intValue());
        cartGoodsDetailDto.setSpuId(product.getSpuId());
        cartGoodsDetailDto.setSkuId(goodsId);
        cartGoodsDetailDto.setQty(product.getQty());
        cartGoodsDetailDto.setSpuName(getProductsVo != null ? getProductsVo.getSpuName() : "");
        cartGoodsDetailDto.setSkuName(product.getSkuName());
        cartGoodsDetailDto.setPicture(getProductsVo != null ? getProductsVo.getSpuPicture() : "");
        cartGoodsDetailDto.setActivityType(ActivityTypeEnum.TYPE_81.getCode());
        cartGoodsDetailDto.setClassificationId(getProductsVo.getCategory());
        cartGoodsDetailDto.setClassificationName(getProductsVo.getCategoryName());
        cartGoodsDetailDto.setProductType(getProductsVo.getType());
        cartGoodsDetailDto.setStockLimit(ObjectUtils.equals(1, getProductsVo.getStockLimit()));
        List<ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra> cartGoodsExtraList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(product.getAttributes())) {
            for (CreateOrderVo.PremiumExchangeActivity.Product.Attribute attribute : product.getAttributes()) {
                ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra cartGoodsExtra = new ShoppingCartGoodsDto.CartGoodsDetailDto.CartGoodsExtra();
                cartGoodsExtra.setAttributeId(attribute.getAttributeId());
                cartGoodsExtra.setAttributeName(attribute.getAttributeValue());
                cartGoodsExtraList.add(cartGoodsExtra);
            }
        }
        cartGoodsDetailDto.setExtraList(cartGoodsExtraList);
        return cartGoodsDetailDto;
    }
}