package cn.freemud.service.impl;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.entities.dto.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.CheckSpqInfoResponseDto;
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.*;
import cn.freemud.service.CouponService;
import cn.freemud.service.IPromotionService;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: CouponPromotionService
 * @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 CouponPromotionService implements IPromotionService {
    @Autowired
    private CouponService couponService;

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        // 用户选择了查询优惠券信息
        if (couponPromotionVO != null && ObjectUtils.equals(CouponFlag.YES.getCode(), couponPromotionVO.getFlg())) {
            List<CartGoods> tmpCartGoods = cartGoodsList.parallelStream().filter(k -> k.getCartGoodsUid()
                    .startsWith(CommonsConstant.COUPON_PREFIX)).collect(Collectors.toList());
            // 是否存在商品券
            boolean hasGoodssCoupon = CollectionUtils.isNotEmpty(tmpCartGoods);
            // 构建可用不可用优惠券
            ActivityClassifyCouponBean activityClassifyCouponBean = couponService.availableCoupon(cartGoodsList,
                    couponPromotionVO.getPartnerId(),
                    couponPromotionVO.getUserId(),
                    couponPromotionVO.getStoreId(),
                    couponPromotionVO.getCouponCode(),
                    hasGoodssCoupon,
                    couponPromotionVO.getOrderType(),
                    0,
                    shoppingCartInfoRequestVo.getAppId() );
            if (Objects.equals(activityClassifyCouponBean, null)) {
                // 构建一个空得订单券信息
                activityClassifyCouponBean = createEmptyActivityCouponBean();
            }
            shoppingCartGoodsResponseVo.setAvailableCoupon(activityClassifyCouponBean);
        } else {
            // 构建一个空得订单券信息
            ActivityClassifyCouponBean activityClassifyCouponBean = createEmptyActivityCouponBean();
            shoppingCartGoodsResponseVo.setAvailableCoupon(activityClassifyCouponBean);
        }

        // 当couponCode不为空时，需计算优惠价格
        long couponDiscount = 0;
        if (couponPromotionVO != null && StringUtils.isNotEmpty(couponPromotionVO.getCouponCode())
                && calculationDiscountResult != null) {
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults> couponResultsList = calculationDiscountResult.getCouponDiscounts();
            if (CollectionUtils.isNotEmpty(couponResultsList)) {
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponResults : couponResultsList) {
                    couponDiscount = couponDiscount + (couponResults.getDiscountAmount() == null ? 0 : couponResults.getDiscountAmount());
                }
            }
        }
        shoppingCartGoodsResponseVo.setCouponDiscount(couponDiscount);
        //循环购物车商品券
        for (CartGoods cartGoods : cartGoodsList) {
            if (cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)) {
                String spqId = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
                // 计算优惠信息时，已将券校验过，放在map中
                Map<String, CheckSpqInfoResponseDto> validCouponMap = calculationDiscountResult == null ? new HashMap<>() : calculationDiscountResult.getValidCouponMap();
                if (MapUtils.isNotEmpty(validCouponMap)) {
                    CheckSpqInfoResponseDto checkSpqInfoResponseDto = validCouponMap.get(spqId);
                    if (checkSpqInfoResponseDto != null) {
                        cartGoods.setOriginalPrice(checkSpqInfoResponseDto.getPrice());
                        cartGoods.setSpuId(checkSpqInfoResponseDto.getSpuId());
                        cartGoods.setSkuId(StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId());
                        cartGoods.setQty(1);
                        cartGoods.setCouponCode(checkSpqInfoResponseDto.getCouponCode());
                        cartGoods.setSpuName(checkSpqInfoResponseDto.getSpuName());
                        cartGoods.setSpecProductId(checkSpqInfoResponseDto.getDefaultSpecId());
                        cartGoods.setSubName(checkSpqInfoResponseDto.getDefaultSpecName());
                        cartGoods.setExtra(checkSpqInfoResponseDto.getExtras());
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods discountGoods = calculationDiscountResult.getGoods()
                                    .stream()
                                    .filter(d -> cartGoods.getCartGoodsUid().equals(d.getCartGoodsUid()))
                                    .findFirst()
                                    .orElse(null);
                            if (discountGoods != null) {
                                cartGoods.setAmount(discountGoods.getRealAmount());
                            } else {
                                cartGoods.setAmount(checkSpqInfoResponseDto.getPrice());
                            }
                        }
                        cartGoods.setOriginalAmount(checkSpqInfoResponseDto.getPrice());
                    }
                }
            }
        }
    }


    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults> couponDiscounts = calculationDiscountResult == null ? new ArrayList<>() : calculationDiscountResult.getCouponDiscounts();
        List<ActivityDiscountsDto> activityDiscountsDtos = shoppingCartGoodsDto.getActivityDiscountsDtos() == null ? new ArrayList<>() : shoppingCartGoodsDto.getActivityDiscountsDtos();

        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoods : shoppingCartGoodsDto.getProducts()) {
            if (StringUtils.isNotEmpty(cartGoods.getCouponCode())) {
                for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount : couponDiscounts) {
                    ActivityDiscountsDto activityDiscountsDto = getActivityDiscountDto(calculationDiscountResult.getApportionGoods(), couponDiscount);
                    if (activityDiscountsDto != null) {
                        ActivityDiscountsDto activityDiscountsDto1 = new ActivityDiscountsDto();
                        BeanUtils.copyProperties(activityDiscountsDto, activityDiscountsDto1);
                        activityDiscountsDto1.setDiscountAmount(-activityDiscountsDto.getDiscountAmount());

                        cartGoods.setTotalDiscountAmount(-activityDiscountsDto.getDiscountAmount());
                        cartGoods.setSalePrice(0L);
                        cartGoods.setActivityDiscountsDtos(Arrays.asList(activityDiscountsDto1));
                    }
                }
            }
        }

        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount : couponDiscounts) {
            ActivityDiscountsDto activityDiscountsDto = getActivityDiscountDto(calculationDiscountResult.getApportionGoods(), couponDiscount);
            if (activityDiscountsDto != null) {
                activityDiscountsDtos.add(activityDiscountsDto);
            }
        }
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
    }

    private ActivityDiscountsDto getActivityDiscountDto(List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoods, ActivityCalculationDiscountResponseDto.CalculationDiscountResult.CouponResults couponDiscount) {
        String couponCode = couponDiscount.getCouponCode();
        for (ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods apportionGood : apportionGoods) {
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails> list = apportionGood.getApportionDetails().stream().filter(detail -> ObjectUtils.equals(couponCode, detail.getActivityCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(list)) {
                ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods.ApportionDetails apportionDetails = list.get(0);
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(apportionDetails.getActivityCode());
                activityDiscountsDto.setActivityName(apportionDetails.getActivityName());
                activityDiscountsDto.setActivityType(this.convent2ActivityType(apportionDetails.getActivityType()));
                activityDiscountsDto.setDiscountAmount(0 - couponDiscount.getDiscountAmount());
                return activityDiscountsDto;
            }
        }
        return null;
    }


    public ActivityClassifyCouponBean createEmptyActivityCouponBean() {
        ActivityClassifyCouponBean activityClassifyCouponBean = new ActivityClassifyCouponBean();
        activityClassifyCouponBean.setCouponNum(0);
        activityClassifyCouponBean.setDisableCouponNum(0);
        activityClassifyCouponBean.setUsableCouponNum(0);
        activityClassifyCouponBean.setDisableCoupons(Lists.newArrayList());
        activityClassifyCouponBean.setUsableCoupons(Lists.newArrayList());
        return activityClassifyCouponBean;
    }

    private Integer convent2ActivityType(Integer type) {
        Integer Hg = 33;
        if (type != null && Hg.equals(type)) {
            type = 32;
        }
        return type;
    }
}
