package com.liquidnet.service.sweet.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.dto.vo.AdamAddressesVo;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.PagedResult;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.candy.vo.CandyCouponPreviewVo;
import com.liquidnet.service.feign.adam.api.FeignAdamBaseClient;
import com.liquidnet.service.feign.candy.api.FeignCandyBaseClient;
import com.liquidnet.service.feign.stone.api.FeignStoneIntegralClient;
import com.liquidnet.service.stone.dto.StoneScoreListDto;
import com.liquidnet.service.sweet.constant.StatusConst;
import com.liquidnet.service.sweet.dto.vo.*;
import com.liquidnet.service.sweet.entity.SweetIntegralActivityDraw;
import com.liquidnet.service.sweet.mapper.SweetIntegralActivityDrawMapper;
import com.liquidnet.service.sweet.param.SweetStoneIntegralParam;
import com.liquidnet.service.sweet.service.ISweetIntegralActivityDrawService;
import com.liquidnet.service.sweet.utils.QueueUtils;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import com.liquidnet.service.sweet.utils.SweetNewObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 积分活动抽奖记录表 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-10-26
 */
@Slf4j
@Service
public class SweetIntegralActivityDrawServiceImpl extends ServiceImpl<SweetIntegralActivityDrawMapper, SweetIntegralActivityDraw> implements ISweetIntegralActivityDrawService {

    @Autowired
    private RedisDataUtils redisDataUtils;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private QueueUtils queueUtils;

    @Autowired
    private FeignStoneIntegralClient feignStoneIntegralClient;
    @Autowired
    private FeignAdamBaseClient feignAdamBaseClient;
    @Autowired
    private FeignCandyBaseClient feignCandyBaseClient;

    @Override
    public ResponseDto<IntegralActivityPrizeApiVo> create(String integralActivityId) {
        Map tokenClaims = CurrentUtil.getTokenClaims();
        String userId = StringUtils.defaultString((String.valueOf(tokenClaims.get(CurrentUtil.TOKEN_SUB))), "");
        // 加锁
        boolean isLock = redisDataUtils.setIntegralDrawLock(userId);
        if (!isLock) {
            return ResponseDto.failure("您的手速太快啦～");
        } else {
            try {
                String nickname = StringUtils.defaultString((String.valueOf(tokenClaims.get("nickname"))), "");

                IntegralActivityVo integralActivity = redisDataUtils.getIntegralActivityInfo(integralActivityId);
                if (integralActivity.getIsOnline() == 1) {
                    return ResponseDto.failure("该活动已下线");
                }
                if (integralActivity.getTimeType() == 2) {
                    LocalDateTime startTime = integralActivity.getStartTime();
                    LocalDateTime endTime = integralActivity.getEndTime();
                    LocalDateTime nowTime = LocalDateTime.now();
                    if (nowTime.isAfter(endTime)) { // 已结束
                        return ResponseDto.failure("该活动已结束");
                    }
                    if (startTime.isAfter(nowTime)) { // 未开始
                        return ResponseDto.failure("该活动未开始");
                    }
                }

                // 判断用户积分是否>=integralActivity.setActivityNum();
                ResponseDto<StoneScoreListDto> userInfoRes = feignStoneIntegralClient.stoneUserInfo();
                if (!userInfoRes.getCode().equals("0")) {
                    log.error("获取用户积分数据失败 userInfoRes:{}", userInfoRes);
                    return ResponseDto.failure("获取用户积分数据失败");
                } else {
                    StoneScoreListDto userInfoData = userInfoRes.getData();
                    if (userInfoData.getStatus() == 2) {
                        return ResponseDto.failure("您的积分账户已被冻结！");
                    } else {
                        BigDecimal scoreRest = userInfoData.getScoreRest();
                        if (scoreRest.compareTo(BigDecimal.valueOf(integralActivity.getActivityNum())) == -1) {
                            return ResponseDto.failure(ErrorMapping.get("90082"));
                        }
                    }
                }

                // 如果库存没了就从列表剔出 列表为空就都没有库存了
                ArrayList<IntegralActivityPrizeVo> activityPrizeVoArrayList = SweetNewObjectUtil.getIntegralActivityPrizeVoArrayList();
                // 黑名单只中券 不记录次数
                List<String> drawBlack = redisDataUtils.getIntegralActivityDrawBlack();
                boolean isBlack = false;
                if (drawBlack.contains(userId)) {
                    isBlack = true;
                }
                // 概率计算
                boolean lotteryDraw = this.lotteryDraw(integralActivityId, userId);
                if (lotteryDraw && !isBlack) { // 实物
                    List<IntegralActivityPrizeVo> prizeList = integralActivity.getPrizeList2();
                    for (IntegralActivityPrizeVo info : prizeList) {
                        int integralActivityPrizeNum = redisDataUtils.getIntegralActivityPrizeNum(integralActivityId, info.getPrizeId());
                        if (integralActivityPrizeNum > 0) {
                            activityPrizeVoArrayList.add(info);
                        }
                    }
                }

                if (isBlack || !lotteryDraw || CollectionUtils.isEmpty(activityPrizeVoArrayList)) {// 没中实物、实物库存没了、是黑名单中用户 中券
                    List<IntegralActivityPrizeVo> prizeList = integralActivity.getPrizeList1();
                    for (IntegralActivityPrizeVo info : prizeList) {
                        if (info.getIsInfinite() == 1) {
                            int integralActivityPrizeNum = redisDataUtils.getIntegralActivityPrizeNum(integralActivityId, info.getPrizeId());
                            if (integralActivityPrizeNum == -1 || integralActivityPrizeNum > 0) {
                                activityPrizeVoArrayList.add(info);
                            }
                        } else {
                            activityPrizeVoArrayList.add(info);
                        }
                    }
                    if (CollectionUtils.isEmpty(activityPrizeVoArrayList)) {
                        return ResponseDto.failure("活动太火爆了，奖品已经没有库存啦～");
                    }
                }

                IntegralActivityPrizeVo integralActivityPrizeVo = this.lotteryDraw1(activityPrizeVoArrayList);

                // 减库存 顺便判断库存是否够 无限库存不判断
                if (integralActivityPrizeVo.getIsInfinite() == 1) {
                    long activityPrizeNum = redisDataUtils.decrIntegralActivityPrizeNum(integralActivityId, integralActivityPrizeVo.getPrizeId(), 1);
                    log.info("奖品库存情况 activityPrizeNum:{}", activityPrizeNum);
                    if (activityPrizeNum < 0) {// 库存不够了
                        long prizeNum = redisDataUtils.incrIntegralActivityPrizeNum(integralActivityId, integralActivityPrizeVo.getPrizeId(), 1);
                        log.info("奖品库存情况回滚后 prizeNum:{}", prizeNum);
                        return ResponseDto.failure("活动太火爆了，奖品已经没有库存了！");
                    }
                }

                // 减积分
                SweetStoneIntegralParam integralParamDe = SweetStoneIntegralParam.getNew();
                integralParamDe.setType(2);
                integralParamDe.setUid(userId);
                integralParamDe.setScore(integralActivity.getActivityNum());
                integralParamDe.setContent(integralActivity.getActivityTitle());
                queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_STONE_INTEGRAL.getKey(),
                        JsonUtils.toJson(integralParamDe));
                // 抽奖入库
                String drawId = IDGenerator.nextSnowId();
                IntegralActivityDrawVo integralActivityDrawVo = IntegralActivityDrawVo.getNew();
                integralActivityDrawVo.setDrawId(drawId);
                integralActivityDrawVo.setIntegralActivityId(integralActivityId);
                integralActivityDrawVo.setActivityNum(integralActivity.getActivityNum());
                integralActivityDrawVo.setPrizeId(integralActivityPrizeVo.getPrizeId());
                integralActivityDrawVo.setPrizeTitle(integralActivityPrizeVo.getPrizeTitle());
                integralActivityDrawVo.setPrizeType(integralActivityPrizeVo.getPrizeType());
                integralActivityDrawVo.setPrizeTypeNum(integralActivityPrizeVo.getPrizeTypeNum());
                integralActivityDrawVo.setUserId(userId);
                integralActivityDrawVo.setNickname(nickname);
                LocalDateTime nowTime = LocalDateTime.now();
                integralActivityDrawVo.setCreatedAt(nowTime);
                Integer receivingStatus = 1;
                Integer prizeType = integralActivityPrizeVo.getPrizeType();
                if (prizeType == StatusConst.PRIZE_TYPE1) {// 中奖积分
                    SweetStoneIntegralParam integralParamIn = SweetStoneIntegralParam.getNew();
                    integralParamIn.setType(1);
                    integralParamIn.setUid(userId);
                    integralParamIn.setScore(integralActivityPrizeVo.getPrizeTypeNum());
                    integralParamIn.setContent(integralActivity.getActivityTitle());
                    queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_STONE_INTEGRAL.getKey(),
                            JsonUtils.toJson(integralParamIn));
                    receivingStatus = 2;
                }
                if (prizeType == StatusConst.PRIZE_TYPE2) {// 中奖券 优惠券默认未领取状态
                    /*receivingStatus = 2;
                    redisDataUtils.setSendCoupon(drawId,0);*/
                    receivingStatus = 3;
                }
                integralActivityDrawVo.setReceivingStatus(receivingStatus);
                // redis
                redisDataUtils.setIntegralActivityDraw(integralActivityDrawVo);
                if (prizeType == StatusConst.PRIZE_TYPE3 || prizeType == StatusConst.PRIZE_TYPE4 || prizeType == StatusConst.PRIZE_TYPE5) { // 中实物减实物总库存
                    redisDataUtils.decrIntegralActivityTotalPrizeNum(integralActivityId);
                }
                // mongo
                mongoTemplate.insert(integralActivityDrawVo, IntegralActivityDrawVo.class.getSimpleName());


                // mysql 抽奖记录
                LinkedList<String> sqls = CollectionUtil.linkedListString();
                LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
                sqls.add(SqlMapping.get("sweet_integral_activity_draw.insert"));
                sqlsDataA.add(new Object[]{
                        drawId, integralActivityId, integralActivity.getActivityNum(),
                        integralActivityPrizeVo.getPrizeId(), integralActivityPrizeVo.getPrizeTitle(), integralActivityPrizeVo.getPrizeType(),
                        integralActivityPrizeVo.getPrizeTypeNum(),
                        userId, nickname,
                        receivingStatus
                });
                queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_INTEGRAL_ACTIVITY_DRAW.getKey(),
                        SqlMapping.gets(sqls, sqlsDataA));
                IntegralActivityPrizeApiVo activityPrizeApiVo = IntegralActivityPrizeApiVo.getNew().copy(integralActivityPrizeVo);
                activityPrizeApiVo.setDrawId(drawId);

                // 参与次数
                if (!isBlack) {
                    redisDataUtils.decrIntegralActivityEstimatedNum(integralActivityId, 1);
                }
                return ResponseDto.success(activityPrizeApiVo);
            } catch (Exception e) {
                log.error("积分抽奖异常 e:{}", e);
                return ResponseDto.failure("操作失败，请稍后重试！");
            } finally {
                // 执行完毕。释放锁
                redisDataUtils.delIntegralDrawLock(userId);
            }
        }
    }

    @Override
    public ResponseDto<PagedResult<IntegralActivityDrawVo>> drawList(String integralActivityId, Integer pageNum) {
        Integer pageSize = 20;
        String currentUid = CurrentUtil.getCurrentUid();
        PagedResult<IntegralActivityDrawVo> sweetIntegralActivityDrawPagedResult = SweetNewObjectUtil.getSweetIntegralActivityDrawVoPagedResult();
        //条件
        Query query = Query.query(
                Criteria.where("integralActivityId").is(integralActivityId).and("userId").is(currentUid)
        );
        long count = mongoTemplate.count(query, IntegralActivityDrawVo.class, IntegralActivityDrawVo.class.getSimpleName());
        LinkedList<IntegralActivityDrawVo> integralActivityDrawList = redisDataUtils.getIntegralActivityDrawList(currentUid, integralActivityId);
        if (null == integralActivityDrawList || pageNum > 1) {
            // 排序 分页
            Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Direction.DESC, "createdAt"));
            query.with(pageable);
            List<IntegralActivityDrawVo> integralActivityDrawVos = mongoTemplate.find(query, IntegralActivityDrawVo.class, IntegralActivityDrawVo.class.getSimpleName());
            // mongo
            for (IntegralActivityDrawVo drawVo : integralActivityDrawVos) {
                IntegralActivityDrawVo drawInfo = redisDataUtils.getIntegralActivityDrawInfo(drawVo.getDrawId());
                drawVo.setReceivingStatus(drawInfo.getReceivingStatus());
                drawVo.setRelationId(drawInfo.getRelationId());
            }
            sweetIntegralActivityDrawPagedResult.setList(integralActivityDrawVos).setTotal(count, pageSize).setPageSize(pageSize).setCurrentPage(pageNum);
            if (null == integralActivityDrawList) {
                redisDataUtils.setIntegralActivityDrawList(currentUid, integralActivityId, integralActivityDrawVos);
            }
        } else {
            sweetIntegralActivityDrawPagedResult.setList(integralActivityDrawList).setTotal(count, pageSize).setPageSize(pageSize).setCurrentPage(pageNum);
        }
        return ResponseDto.success(sweetIntegralActivityDrawPagedResult);
    }

    @Override
    public ResponseDto<List<IntegralActivityDrawVo>> winPrizeUser(String integralActivityId) {
        List<IntegralActivityDrawVo> integralActivityDrawAll = redisDataUtils.getIntegralActivityDrawAll(integralActivityId);
        return ResponseDto.success(integralActivityDrawAll);
    }

    @Override
    public ResponseDto perfectAddress(String drawId, String receivingAddressesId) {
        // 更新缓存
        IntegralActivityDrawVo drawVo = redisDataUtils.getIntegralActivityDrawInfo(drawId);
        drawVo.setReceivingAddressesId(receivingAddressesId);
        // 获取地址数据
        ResponseDto<AdamAddressesVo> queryAddresses = feignAdamBaseClient.queryAddresses(receivingAddressesId, drawVo.getUserId());
        if (!queryAddresses.getCode().equals("0")) {
            return ResponseDto.failure("获取地址信息失败");
        }
        AdamAddressesVo addressesData = queryAddresses.getData();
        String receivingPhone = addressesData.getPhone();
        String receivingName = addressesData.getName();
        String receivingProvince = addressesData.getProvince();
        String receivingCity = addressesData.getCity();
        String receivingCounty = addressesData.getCounty();
        String receivingAddress = addressesData.getAddress();

        drawVo.setReceivingName(receivingName);
        drawVo.setReceivingPhone(receivingPhone);
        drawVo.setReceivingProvince(receivingProvince);
        drawVo.setReceivingCity(receivingCity);
        drawVo.setReceivingCounty(receivingCounty);
        drawVo.setReceivingAddress(receivingAddress);
        drawVo.setReceivingAddressesId(receivingAddressesId);
        LocalDateTime nowTime = LocalDateTime.now();
        drawVo.setUpdatedAt(nowTime);
        redisDataUtils.setIntegralActivityDrawInfo(drawId, drawVo);

        mongoTemplate.getCollection(IntegralActivityDrawVo.class.getSimpleName()).updateOne(
                Query.query(Criteria.where("drawId").is(drawId)).getQueryObject(),
                new Document("$set", new Document("receivingAddressesId", receivingAddressesId)
                        .append("receivingName", receivingName)
                        .append("receivingPhone", receivingPhone)
                        .append("receivingProvince", receivingProvince)
                        .append("receivingCity", receivingCity)
                        .append("receivingCounty", receivingCounty)
                        .append("receivingAddress", receivingAddress)
                        .append("updatedAt", nowTime))
        );

        redisDataUtils.delIntegralActivityDrawList(drawVo.getUserId(), drawVo.getIntegralActivityId());

        // mysql
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("sweet_integral_activity_draw.update"));
        sqlsDataA.add(new Object[]{
                receivingAddressesId, receivingName, receivingPhone, receivingAddress, receivingProvince, receivingCity, receivingCounty, nowTime, drawId
        });
        queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_INTEGRAL_ACTIVITY_DRAW.getKey(),
                SqlMapping.gets(sqls, sqlsDataA));

        return ResponseDto.success();
    }

    @Override
    public ResponseDto<IntegralActivityDrawVo> detail(String drawId) {
        IntegralActivityDrawVo drawVo = redisDataUtils.getIntegralActivityDrawInfo(drawId);
        IntegralActivityVo integralActivityInfo = redisDataUtils.getIntegralActivityInfo(drawVo.getIntegralActivityId());
        drawVo.setExpressFeeType(integralActivityInfo.getExpressFeeType());
        return ResponseDto.success(drawVo);
    }

    @Override
    public ResponseDto collectCoupon(String couponId, String drawId) {
        IntegralActivityDrawVo drawVo = redisDataUtils.getIntegralActivityDrawInfo(drawId);
        Map tokenClaims = CurrentUtil.getTokenClaims();
        String mobile = StringUtils.defaultString((String.valueOf(tokenClaims.get(CurrentUtil.TOKEN_MOBILE))), "");
        String uid = StringUtils.defaultString((String.valueOf(tokenClaims.get(CurrentUtil.TOKEN_SUB))), "");
//        if (null != drawVo && (drawVo.getReceivingStatus() == 1 || drawVo.getReceivingStatus() == 2 && redisDataUtils.isSendCoupon(drawId)) && drawVo.getUserId().equals(uid)) {
        // 是否有必要判断中奖类型 和 券id是否在配置中
        if (null != drawVo && drawVo.getReceivingStatus() != 2 && drawVo.getUserId().equals(uid)) {
            // 发放券
            LocalDateTime nowTime = LocalDateTime.now();
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            sqls.add(SqlMapping.get("sweet_integral_activity_draw.get_coupon"));
            sqlsDataA.add(new Object[]{
                    IDGenerator.nextTimeId2(), couponId,
                    1, mobile, nowTime, "INTEGRAL_DRAW", nowTime
            });
            queueUtils.sendMsgByRedis(MQConst.StoneQueue.STONE_ORDER_COUPON.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA));
            // 更改发放状态
            LinkedList<String> sqlsB = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            sqlsB.add(SqlMapping.get("sweet_integral_activity_draw.updateStatus"));
            sqlsDataB.add(new Object[]{
                    2, couponId, nowTime, drawId
            });
            queueUtils.sendMsgByRedis(MQConst.SweetQueue.SWEET_INTEGRAL_ACTIVITY_DRAW.getKey(),
                    SqlMapping.gets(sqlsB, sqlsDataB));
            // 更新缓存
            redisDataUtils.updateIntegralActivityDrawInfo(drawId, couponId);

//            redisDataUtils.setSendCoupon(drawId,1);
//            mongoTemplate.getCollection(IntegralActivityDrawVo.class.getSimpleName()).updateOne(
//                    Query.query(Criteria.where("drawId").is(drawId)).getQueryObject(),
//                    new Document("$set", new Document("receivingStatus", 2)
//                            .append("relationId", couponId)
//                            .append("updatedAt", LocalDateTime.now())
//                    )
//            );

            redisDataUtils.delIntegralActivityDrawList(uid, drawVo.getIntegralActivityId());
        }
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<List<CandyCouponPreviewVo>> couponList(String prizeId, String integralActivityId) {
        IntegralActivityVo integralActivity = redisDataUtils.getIntegralActivityInfo(integralActivityId);
        List<IntegralActivityPrizeVo> prizeList1 = integralActivity.getPrizeList1();
        List<IntegralActivityPrizeRelationVo> relationList = new ArrayList<>();
        for (IntegralActivityPrizeVo prize : prizeList1) {
            if (prize.getPrizeId().equals(prizeId)) {
                relationList = prize.getPrizeRelationList();
                break;
            }
        }
        List<CandyCouponPreviewVo> couponBasicVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(relationList)) {
            try {
                List<String> couponIds = relationList.stream().map(IntegralActivityPrizeRelationVo -> IntegralActivityPrizeRelationVo.getCouponId()).collect(Collectors.toList());
                ResponseDto<List<CandyCouponPreviewVo>> responseDto = feignCandyBaseClient.couponListById(StringUtils.join(couponIds.toArray(), ","));
                couponBasicVos = responseDto.getData();
            } catch (Exception e) {
                log.error("获取券详情失败 e:{}", e);
            }
        }
        return ResponseDto.success(couponBasicVos);
    }

    /**
     * 抽奖方法 计算中哪一个
     */
    private static IntegralActivityPrizeVo lotteryDraw1(List<IntegralActivityPrizeVo> prizeList) {
        if (prizeList == null || prizeList.isEmpty()) {
            return null;
        }

        int size = prizeList.size();

        // 计算总概率，这样可以保证不一定总概率是1
        BigDecimal sumRate = BigDecimal.ZERO;
        for (IntegralActivityPrizeVo prize : prizeList) {
            sumRate = sumRate.add(prize.getWinningProbability());
        }

        // 计算每个物品在总概率的基础下的概率情况
        List<BigDecimal> sortOrignalRates = new ArrayList<>(size);
        BigDecimal tempSumRate = BigDecimal.ZERO;
        for (IntegralActivityPrizeVo prize : prizeList) {
            tempSumRate = tempSumRate.add(prize.getWinningProbability());
            sortOrignalRates.add(tempSumRate.divide(sumRate, 4, BigDecimal.ROUND_HALF_UP));
        }

        // 根据区块值来获取抽取到的物品索引
        double nextDouble = Math.random();
        BigDecimal nextDoubleNew = BigDecimal.valueOf(nextDouble);
        sortOrignalRates.add(nextDoubleNew);
        Collections.sort(sortOrignalRates);

        int index = sortOrignalRates.indexOf(nextDoubleNew);

        IntegralActivityPrizeVo integralActivityPrizeVo = prizeList.get(index);
        return integralActivityPrizeVo;
    }

    /**
     * 抽奖方法 计算中哪个奖池的奖品
     */
    /*private boolean lotteryDraw(String integralActivityId, String uid) {
        // 随机数
        double random = Math.random() * 100;
        BigDecimal randomBig = BigDecimal.valueOf(random);
        // 剩余总库存 添加编辑的时候冗余的总库存省去计算
        int prizeNum = redisDataUtils.getIntegralActivityTotalPrizeNum(integralActivityId);
        BigDecimal prizeNumBig = BigDecimal.valueOf(prizeNum);
        // 概率
        int estimatedNum = redisDataUtils.getIntegralActivityEstimatedNum(integralActivityId);
        if (estimatedNum <= 0) { // 此时百分百记录中实物
            return true;
        }
        BigDecimal estimatedNumBig = BigDecimal.valueOf(estimatedNum);
        // 会员概率*2
        try {
            ResponseDto<Boolean> isMemberDto = feignAdamBaseClient.isMember(uid);
            Boolean isMember = isMemberDto.getData();
            if (isMember) {
                estimatedNumBig = estimatedNumBig.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP);
            }
        } catch (Exception e) {
            log.error("获取用户是否是会员失败 [uid:{}, e:{}]", uid, e);
        }
        BigDecimal multiply = prizeNumBig.divide(estimatedNumBig, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
        // 对比大小
        if (multiply.compareTo(randomBig) >= 0) {
            return true; // 大于等于随机数中实物
        } else {
            return false;
        }
    }*/

    /**
     * 抽奖方法 计算中哪个奖池的奖品
     */
    private boolean lotteryDraw(String integralActivityId, String uid) {
        int estimatedNum = redisDataUtils.getIntegralActivityEstimatedNum(integralActivityId);
        if (estimatedNum <= 0) { // 此时百分百中实物
            return true;
        }
        // 剩余总库存 添加编辑的时候冗余的总库存省去计算
        int prizeNum = redisDataUtils.getIntegralActivityTotalPrizeNum(integralActivityId);
        BigDecimal prizeNumBig = BigDecimal.valueOf(prizeNum);
        // 概率
        BigDecimal estimatedNumBig = BigDecimal.valueOf(estimatedNum);
        // 会员、白名单概率*2
        try {
            List<String> drawWhite = redisDataUtils.getIntegralActivityDrawWhite();
            if (drawWhite.contains(uid)) {
                estimatedNumBig = estimatedNumBig.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP);
            } else {
                ResponseDto<Boolean> isMemberDto = feignAdamBaseClient.isMember(uid);
                Boolean isMember = isMemberDto.getData();
                if (isMember) {
                    estimatedNumBig = estimatedNumBig.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP);
                }
            }
        } catch (Exception e) {
            log.error("获取用户是否是会员失败 [uid:{}, e:{}]", uid, e);
        }
        // 随机数
        double random = Math.random();
        BigDecimal randomBig = BigDecimal.valueOf(random);
        BigDecimal randomBigNew = randomBig.multiply(estimatedNumBig);
        // 对比大小
        if (randomBigNew.compareTo(prizeNumBig) <= 0) {
            return true; // 0 - 剩余预估人数的随机数 <= 实物剩余总库存 中实物
        } else {
            return false;
        }
    }

    /*public static void main(String[] args) {

        List<SweetIntegralActivityPrizeVo> gifts = new ArrayList<>();
        SweetIntegralActivityPrizeVo aNew = SweetIntegralActivityPrizeVo.getNew();
        SweetIntegralActivityPrizeVo aNew2 = SweetIntegralActivityPrizeVo.getNew();
        SweetIntegralActivityPrizeVo aNew3 = SweetIntegralActivityPrizeVo.getNew();
        aNew.setWinningProbability(BigDecimal.valueOf(0.4));
        aNew.setPrizeTitle("一等奖");
        aNew.setPrizeId("111");
        aNew2.setWinningProbability(BigDecimal.valueOf(0.5));
        aNew2.setPrizeTitle("二等奖");
        aNew2.setPrizeId("222");
        aNew3.setWinningProbability(BigDecimal.valueOf(0.1));
        aNew3.setPrizeTitle("三等奖");
        aNew3.setPrizeId("333");
        gifts.add(aNew);
        gifts.add(aNew2);
        gifts.add(aNew3);

        // 统计
        Map<Integer, Integer> count = new HashMap<>();

        // 测试次数
        double num = 1000000;
        for (int i = 0; i < num; i++) {
            SweetIntegralActivityPrizeVo orignalIndex = lottery(gifts);
            Integer integer = count.get(Integer.valueOf(orignalIndex.getPrizeId()));
            count.put(Integer.valueOf(orignalIndex.getPrizeId()), integer == null ? 1 : integer + 1);
        }

        for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
            System.out.println(entry.getKey() + ", 命中次数=" + entry.getValue() + ", 实际概率="
                    + entry.getValue() / num);
        }
    }*/

}
