package com.fzm.mall.server.front.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fzm.mall.server.front.goods.model.MarketingCoupon;
import com.fzm.mall.server.front.goods.mapper.MarketingCouponMapper;
import com.fzm.mall.server.front.goods.model.MarketingCouponCategory;
import com.fzm.mall.server.front.goods.model.MarketingCouponSku;
import com.fzm.mall.server.front.goods.model.vo.CouponVo;
import com.fzm.mall.server.front.goods.model.vo.PageVoWithOne;
import com.fzm.mall.server.front.goods.model.vo.SkuVo;
import com.fzm.mall.server.front.goods.model.vo.UserCouponVo;
import com.fzm.mall.server.front.goods.service.IMarketingCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.mall.server.front.goods.service.ISkuService;
import com.fzm.mall.server.front.goods.service.ISpuService;
import com.fzm.mall.server.front.order.model.vo.OrderSkuVo;
import com.fzm.mall.server.front.user.model.Coupon;
import com.fzm.mall.server.front.user.service.ICouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * <p>
 * 商品优惠券 服务实现类
 * </p>
 *
 * @author fzm
 * @since 2021-03-09
 */
@Service
public class MarketingCouponServiceImpl extends ServiceImpl<MarketingCouponMapper, MarketingCoupon> implements IMarketingCouponService {

    @Autowired
    private MarketingCouponMapper marketingCouponMapper;

    @Autowired
    private ICouponService iCouponService;

    @Autowired
    private ISpuService iSpuService;

    @Autowired
    private ISkuService iSkuService;

    //平台-商户号
    public static final String PLATFORM_MERCHANT_ID = "e3ac4b4a4e65460dbd9f1ec6cbd7a900";



    @Override
    public List<MarketingCoupon> getByGoodsId(String goodsId,Integer type) {
        return  marketingCouponMapper.getByGoodsId(goodsId,type);
    }

    @Override
    public BigDecimal getPrice(String couponId, BigDecimal amount, Integer size, Integer type) {
        MarketingCoupon byCouponId = marketingCouponMapper.getByCouponId(couponId, type);
        if(byCouponId == null){
            return  BigDecimal.ZERO;
        }else{
            if(byCouponId.getType() == 1){
                if(amount.compareTo(byCouponId.getConditionVal())!=-1){
                    return byCouponId.getCouponVal();
                }
            }else if(byCouponId.getType()==2){
                if(amount.compareTo(byCouponId.getConditionVal())!=-1){
                    return byCouponId.getCouponVal();
                }else{
                    return  amount;
                }
            }else if(byCouponId.getType()==3){
                if(amount.compareTo(byCouponId.getConditionVal())!=-1){
                    return (amount.multiply(byCouponId.getCouponVal()).setScale(2,BigDecimal.ROUND_DOWN));
                }
            }else if(byCouponId.getType()==3){
                return (amount.multiply(byCouponId.getCouponVal()).setScale(2,BigDecimal.ROUND_DOWN));
            }
        }
        return  BigDecimal.ZERO;
    }

    @Override
    @Transactional
    public boolean checkEffective(String uid, String couponId,Integer type) {
        Long time = System.currentTimeMillis();
        boolean result = check(uid,couponId,type,time);
        if(!result){
            return  false;
        }
        return true;
    }

    @Override
    public MarketingCoupon getByCouponId(String couponId, Integer type) {
        return marketingCouponMapper.getByCouponId(couponId,type);
    }

    @Override
    public String getGoodsId(String couponId) {
        return marketingCouponMapper.getGoodsId(couponId);
    }

    @Override
    @Transactional
    public Map<String, BigDecimal> getCoupon(String uid, List<String> goodsIdCouponVos, List<OrderSkuVo> allSkuVo,Integer type) {
        //merchant-money
        Map<String,BigDecimal> merchantCoupon = new HashMap<>();
        //商户集合
        Set<String> merchantId = new HashSet<>();
        //类目集合
        Set<String> categoryId = new HashSet<>();
        //商户-sku
        Map<String, List<String>> merchantSku = new HashMap<>();
        //类目-sku
        Map<String, List<String>> categorySku = new HashMap<>();

        Map<String, List<String>> couponSku = new HashMap<>();
        Map<String,Integer> skuNum = new HashMap<>();
        List<String> skuIds = new ArrayList<>();
        //String couponId = "";
        //CouponVo couponVos = couponService.getAll(couponId,type);
        for (OrderSkuVo orderSkuVo : allSkuVo) {
            skuIds.add(orderSkuVo.getSkuId());
            skuNum.put(orderSkuVo.getSkuId(),orderSkuVo.getNum());
            SkuVo skuVo = iSkuService.getBySkuId(orderSkuVo.getSkuId());
            merchantId.add(skuVo.getMerchantId());
            List<String> merchantSkuList = merchantSku.get(skuVo.getMerchantId());
            if (merchantSkuList == null) {
                merchantSkuList = new ArrayList<>();
            }
            merchantSkuList.add(orderSkuVo.getSkuId());
            merchantSku.put(skuVo.getMerchantId(), merchantSkuList);
            List<String> category = iSpuService.getCategoryId(skuVo.getGoodsId());
            for (String c : category) {
                categoryId.add(c);
                List<String> categorySkuList = categorySku.get(c);
                if (categorySkuList == null) {
                    categorySkuList = new ArrayList<>();
                }
                categorySkuList.add(orderSkuVo.getSkuId());
                categorySku.put(c, categorySkuList);
            }
        }
        for (String string:goodsIdCouponVos) {
            boolean result = checkEffective(uid, string, type);
            if (!result) {
                throw new RuntimeException("存在无效优惠券!!!");
            }
            CouponVo couponVos = iCouponService.getAll(string, type);
            if(couponVos == null){
                throw new RuntimeException("存在无效优惠券!!!");
            }
            if(skuIds.size() == 0){
                throw new RuntimeException("存在无效优惠券!!!");
            }
            //归类
            if(couponVos.getRangeType()==1){
                if(couponVos.getMerchantId().equals(PLATFORM_MERCHANT_ID)){
                    couponSku.put(string,skuIds);
                    skuIds.removeAll(skuIds);
                }else if(merchantId.contains(couponVos.getMerchantId())){
                    couponSku.put(string,merchantSku.get(couponVos.getMerchantId()));
                    skuIds.removeAll(merchantSku.get(couponVos.getMerchantId()));
                }
            }else if(couponVos.getRangeType()==2){
                List<MarketingCouponCategory> marketingCouponCategories = couponVos.getMarketingCouponCategories();
                for (MarketingCouponCategory m:marketingCouponCategories) {
                    if (categoryId.contains(m.getCategoryId())) {
                        if(couponVos.getMerchantId().equals(PLATFORM_MERCHANT_ID)||merchantId.contains(couponVos.getMerchantId())){
                            couponSku.put(string, categorySku.get(m.getCategoryId()));
                            skuIds.removeAll(categorySku.get(m.getCategoryId()));

                        }

                    }
                }
            }else if(couponVos.getRangeType()==3){
                List<MarketingCouponSku> marketingCouponSkus = couponVos.getMarketingCouponSkus();
                for (MarketingCouponSku sku:marketingCouponSkus) {
                    if(skuIds.contains(sku.getSkuId())){
                        List<String> list = couponSku.get(couponVos.getCouponId());
                        if(list==null){
                            list = new ArrayList<>();
                        }
                        list.add(sku.getSkuId());
                        couponSku.put(string,list );
                        skuIds.remove(sku.getSkuId());
                    }
                }
            }
        }
        Set<String> strings = couponSku.keySet();
        for (String s:strings) {
            BigDecimal all = BigDecimal.ZERO;
            List<String> list = couponSku.get(s);
            for (String sku: list) {
                SkuVo skuVo = iSkuService.getBySkuId(sku);
                all = all.add(skuVo.getOriginalPrice().multiply(new BigDecimal(skuNum.get(sku))).setScale(2, RoundingMode.UP));
            }
            MarketingCoupon byCouponId = marketingCouponMapper.getByCouponId(s, type);
            if(byCouponId == null){
                throw new RuntimeException("存在无效优惠券!!!");
            }
            if(all.compareTo(byCouponId.getConditionVal())!=-1){
                BigDecimal allCoupon = byCouponId.getCouponVal();
                for (String sku: list) {
                    SkuVo skuVo = iSkuService.getBySkuId(sku);
                    BigDecimal bigDecimal = merchantCoupon.get(skuVo.getMerchantId());
                    if(bigDecimal == null){
                        bigDecimal = BigDecimal.ZERO;
                    }
                    BigDecimal temp = skuVo.getOriginalPrice().multiply(new BigDecimal(skuNum.get(sku))).setScale(2, RoundingMode.UP);
                    bigDecimal = bigDecimal.add(allCoupon.multiply(temp).divide(all).setScale(2,RoundingMode.DOWN));
                    merchantCoupon.put(skuVo.getMerchantId(),bigDecimal.compareTo(BigDecimal.ZERO)==1?bigDecimal:BigDecimal.ZERO);
                }
            }else{
                throw new RuntimeException("存在无效优惠券!!!");
            }
        }
        return  merchantCoupon;
    }

    @Override
    public List<UserCouponVo> getByMerchantId(String merchantId, Integer type) {
        return  marketingCouponMapper.getByMerchantId(merchantId,System.currentTimeMillis(),type);
    }

    @Override
    public Integer getCount(String merchantId, Integer type) {
        return marketingCouponMapper.getCount(merchantId,System.currentTimeMillis(),type);
    }

    @Transactional
    private boolean check(String uid, String couponId,Integer type,Long time) {

        MarketingCoupon m  = marketingCouponMapper.getByCouponId(couponId,type);
        if(m != null && m.getStatus()==1 && m.getStartTime() <= time && m.getEndTime() >= time){
            int i = iCouponService.updateUserCoupon(uid,couponId);
            if(i==1){
                return  true;
            }

        }
        return  false;
    }
}
