package cn.freemud.service.impl;

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.calculate.*;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.AvailableCouponQueryFlagEnum;
import cn.freemud.enums.GoodsTypeEnum;
import cn.freemud.service.CouponService;
import cn.freemud.service.IPromotionService;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
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.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;

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    @Override
    public void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto,
                                                CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList,
                                                ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, UserLoginInfoDto userLoginInfoDto,
                                                ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        // 用户选择了查询优惠券信息
        if (couponPromotionVO != null && ObjectUtils.equals(AvailableCouponQueryFlagEnum.YES.getCode(), couponPromotionVO.getAvailableCouponQueryFlag())) {
            List<CartGoods> tmpCartGoods = cartGoodsList.parallelStream().filter(k -> (k.getCartGoodsUid()
                    .startsWith(CommonsConstant.COUPON_PREFIX) || StringUtils.isNotBlank(k.getCouponCode()))).collect(Collectors.toList());
            // 是否存在商品券
            String chooseCouponCode = "";
            boolean hasGoodssCoupon = CollectionUtils.isNotEmpty(tmpCartGoods);
            if (StringUtils.isBlank(couponPromotionVO.getUnChooseCouponCode()) && hasGoodssCoupon){
                chooseCouponCode = tmpCartGoods.get(0).getGoodsId().substring(CommonsConstant.COUPON_PREFIX.length());
            } else {
                chooseCouponCode = couponPromotionVO.getUnChooseCouponCode();
            }
            // 构建可用不可用优惠券
            ActivityClassifyCouponBean activityClassifyCouponBean = couponService.availableCoupon(cartGoodsList,
                    couponPromotionVO.getPartnerId(),
                    couponPromotionVO.getUserId(),
                    couponPromotionVO.getStoreId(),
                    couponPromotionVO,
                    hasGoodssCoupon,
                    couponPromotionVO.getOrderType(),
                    0,
                    shoppingCartInfoRequestVo.getAppId(),shoppingCartInfoRequestVo.getMenuType(), chooseCouponCode);
            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()) || CollectionUtils.isNotEmpty(couponPromotionVO.getCouponCodes()))
                && calculationDiscountResult !=null) {
            List<CouponResults> couponResultsList = calculationDiscountResult.getCouponDiscounts();
            if (CollectionUtils.isNotEmpty(couponResultsList)) {
                for (CouponResults couponResults : couponResultsList) {
                    //前端计算小计拿商品现价累计减couponDiscount，商品券换购券现价已排除
                    if(ActivityTypeEnum.TYPE_33.getCode()== couponResults.getActivityType()
                            || ActivityTypeEnum.TYPE_32.getCode()== couponResults.getActivityType()
                            || Objects.equals(ActivityTypeEnum.TYPE_330.getCode(), couponResults.getActivityType())){
                        continue;
                    }
                    couponDiscount = couponDiscount + (couponResults.getDiscountAmount() == null ? 0 : couponResults.getDiscountAmount());
                }
            }
            if (CollectionUtils.isNotEmpty(calculationDiscountResult.getCouponDiscounts())
                    && CollectionUtils.isNotEmpty(shoppingCartInfoRequestVo.getCouponCodes())) {
                //选中优惠券赋值
                List<ChooseCouponVo> couponCodes = new ArrayList<>();
                for (ChooseCouponVo chooseCouponVo : shoppingCartInfoRequestVo.getCouponCodes()){
                    for (CouponResults discount : calculationDiscountResult.getCouponDiscounts()){
                        if(chooseCouponVo.getCouponCode().equals(discount.getCouponCode())){
                            // fisherman 加入券的金额
                            chooseCouponVo.setDiscountAmount(discount.getDiscountAmount());
                            couponCodes.add(chooseCouponVo);
                            break;
                        }
                    }
                }
                shoppingCartGoodsResponseVo.setCouponCodes(couponCodes);
            }
        }
        shoppingCartGoodsResponseVo.setCouponDiscount(couponDiscount);

        Map<String, CheckSpqInfoResponseDto> validCouponMap = calculationDiscountResult == null ? new HashMap<>() : calculationDiscountResult.getValidCouponMap();
        Map<String, List<String>> spqIdToCartUuid = calculationDiscountResult == null ? new HashMap<>() : calculationDiscountResult.getSpqIdToCartUuid();
        if (MapUtils.isNotEmpty(validCouponMap) && MapUtils.isNotEmpty(spqIdToCartUuid) && calculationDiscountResult != null){
            List<String> activityCodeList = calculationDiscountResult.getCouponDiscounts().stream().map(p -> p.getCouponCode()).collect(Collectors.toList());
            for (String spqId : validCouponMap.keySet()) {
                CheckSpqInfoResponseDto sqpInfo = validCouponMap.get(spqId);
                if (!activityCodeList.contains(sqpInfo.getCouponCode())){ // 表示商品券不够启用金额
                    List<String> uuidList = spqIdToCartUuid.get(sqpInfo.getCouponCode());
                    if (CollectionUtils.isNotEmpty(uuidList)){
                        List<CartGoods> newCartList = cartGoodsList.stream().filter(p -> !uuidList.contains(p.getCartGoodsUid())).collect(Collectors.toList());
                        assortmentSdkService.setShoppingCart(activityQueryDto.getPartnerId(), activityQueryDto.getStoreId(), userLoginInfoDto.getMemberId(), newCartList, null, null, this.shoppingCartBaseService,activityQueryDto.getBizType());
                        cartGoodsList = newCartList;
                        CheckSpqInfoResponseDto checkSpqInfoResponseDto = validCouponMap.get(spqId);
                        shoppingCartGoodsResponseVo.setChanged(true);
                        shoppingCartGoodsResponseVo.setToastMsg("当前购物车金额低于【" + checkSpqInfoResponseDto.getCouponName() + "】优惠券起用金额门槛，券已自动移除购物车");
                    }
                }
            }
        }


        //循环购物车商品券
        for (CartGoods cartGoods : cartGoodsList) {
            String couponCode = cartGoods.getCouponCode();
            boolean useCoupon = true; // 优惠券放在coupon字段而不是uuid中
            if (cartGoods.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)){
                couponCode = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
                useCoupon = false;
            }
            if (StringUtils.isNotBlank(couponCode)) {
                List<String> validCouponCodeLis = new ArrayList<>();
                if (couponPromotionVO != null && !ObjectUtils.equals(AvailableCouponQueryFlagEnum.NO.getCode(), couponPromotionVO.getAvailableCouponQueryFlag())){
                    validCouponCodeLis = shoppingCartGoodsResponseVo.getAvailableCoupon().getUsableCoupons().stream().map(ActivityCouponBean::getCouponCode).collect(Collectors.toList());
                } else {
                    couponPromotionVO = new CouponPromotionVO();
                    couponPromotionVO.setUserId(userLoginInfoDto.getMemberId());
                    couponPromotionVO.setStoreId(activityQueryDto.getStoreId());
                    couponPromotionVO.setPartnerId(activityQueryDto.getPartnerId());
                    couponPromotionVO.setOrderType(activityQueryDto.getOrderType());
                }
                // couponService.checkValidCoupon(couponPromotionVO, validCouponCodeLis, spqIdToCartUuid, couponCode, cartGoodsList);

                // 计算优惠信息时，已将券校验过，放在map中
                if (MapUtils.isNotEmpty(validCouponMap)) {
                    CheckSpqInfoResponseDto checkSpqInfoResponseDto = null;
                    if(useCoupon){
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode + cartGoods.getSkuId());
                    } else{
                        checkSpqInfoResponseDto = validCouponMap.get(couponCode);
                    }
                    if (checkSpqInfoResponseDto != null) {
                        cartGoods.setOriginalPrice(checkSpqInfoResponseDto.getPrice());
                        cartGoods.setSpuId(checkSpqInfoResponseDto.getSpuId());
                        cartGoods.setSkuId(StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId());
                        cartGoods.setQty(cartGoods.getQty());
                        cartGoods.setCouponCode(checkSpqInfoResponseDto.getCouponCode());
                        cartGoods.setSpuName(checkSpqInfoResponseDto.getSpuName());
                        List<CartGoods.CartGoodsExtra> extra = cartGoods.getExtra();
                        if (CollectionUtils.isNotEmpty(extra)){
                            List<String> specIdList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeId).collect(Collectors.toList());
                            List<String> specNameList = extra.stream().map(CartGoods.CartGoodsExtra::getAttributeName).collect(Collectors.toList());
                            cartGoods.setSpecProductId(StringUtils.join(specIdList, "/"));
                            cartGoods.setSubName(StringUtils.join(specNameList, "/"));
                        } else {
                            cartGoods.setSpecProductId(checkSpqInfoResponseDto.getDefaultSpecId());
                            cartGoods.setSubName(checkSpqInfoResponseDto.getDefaultSpecName());
                            cartGoods.setExtra(checkSpqInfoResponseDto.getExtras());
                        }
                        if (GoodsTypeEnum.HG_COUPON_GOODS.getGoodsType().equals(cartGoods.getGoodsType())) {
                            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.getQty());
                            }
                        }
                        cartGoods.setOriginalAmount(checkSpqInfoResponseDto.getPrice() * cartGoods.getQty());
                    }
                }
            }
        }
    }


    @Override
    public void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        // 这里存放优惠券的信息  下面用于存放
        List<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 (CouponResults couponDiscount : couponDiscounts) {
                    if(Objects.equals(couponDiscount.getActivityType(),ActivityTypeEnum.TYPE_330.getCode())){
                        List<Goods> collect = calculationDiscountResult.getGoods().stream().filter(goods -> Objects.equals(cartGoods.getCartGoodsUid(), goods.getCartGoodsUid())).collect(Collectors.toList());
                        //商品优惠赋值
                        getActivityDiscountDto2(collect,cartGoods);
                    }else {
                        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));
                        }
                    }
                }
            }
        }
        // fisherman 获取优惠券的信息 存放入 setActivityDiscountsDtos
        for (CouponResults couponDiscount : couponDiscounts) {
            if (ActivityTypeEnum.TYPE_34.getCode().compareTo(couponDiscount.getActivityType()) ==0) {
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(couponDiscount.getCouponCode());
                activityDiscountsDto.setActivityName(couponDiscount.getActivityName());
                activityDiscountsDto.setActivityType(couponDiscount.getActivityType());
                activityDiscountsDto.setDiscountAmount(couponDiscount.getDiscountAmount());
                activityDiscountsDto.setExtendType(couponDiscount.getActivityType());
                activityDiscountsDtos.add(activityDiscountsDto);
                continue;
            }
            ActivityDiscountsDto activityDiscountsDto = getActivityDiscountDto(calculationDiscountResult.getApportionGoods(), couponDiscount);
            if (activityDiscountsDto != null) {
                activityDiscountsDtos.add(activityDiscountsDto);
            }
        }
        // fisherman activityDiscountsDtos 设置 用于存放 settlement表
        shoppingCartGoodsDto.setActivityDiscountsDtos(activityDiscountsDtos);
    }

    private ActivityDiscountsDto getActivityDiscountDto(List<ApportionGoods> apportionGoods, CouponResults couponDiscount) {
        String couponCode = couponDiscount.getCouponCode();
        for (ApportionGoods apportionGood : apportionGoods) {
            List<ApportionDetails> list = apportionGood.getApportionDetails().stream().filter(detail -> ObjectUtils.equals(couponCode, detail.getActivityCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(list)) {
                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;
    }

    private ActivityDiscountsDto getActivityDiscountDto2(List<Goods> goods, ShoppingCartGoodsDto.CartGoodsDetailDto cartGoods) {
        if(CollectionUtils.isNotEmpty(goods)){
            Goods goods1 = goods.get(0);
            List<GoodsDiscount> discounts = goods1.getDiscounts();
            if(CollectionUtils.isNotEmpty(discounts) && Objects.equals(discounts.get(0).getType(),ActivityTypeEnum.TYPE_330.getCode())){
                ActivityDiscountsDto activityDiscountsDto = new ActivityDiscountsDto();
                activityDiscountsDto.setActivityCode(discounts.get(0).getActivityCode());
                activityDiscountsDto.setActivityName(discounts.get(0).getActivityName());
                activityDiscountsDto.setActivityType(this.convent2ActivityType(discounts.get(0).getType()));
                activityDiscountsDto.setDiscountAmount(0 - discounts.get(0).getDiscount().intValue());
                activityDiscountsDto.setActualActivityGoodsNumber(discounts.get(0).getActualGoodsNumber());
                activityDiscountsDto.setCartGoodsUid(goods1.getCartGoodsUid());

                //商品优惠赋值
                cartGoods.setTotalDiscountAmount(-goods1.getDiscountAmount().intValue());
                cartGoods.setSalePrice(goods1.getNowPrice());
                cartGoods.setActivityDiscountsDtos(Arrays.asList(activityDiscountsDto));
                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;
        }
        Integer buyMsendN = 330;
        if (type != null && buyMsendN.equals(type)) {
            type = 32;
        }
        return type;
    }
}
