package com.seamew.lottery.domain.strategy.service.algorithm.impl;

import com.seamew.lottery.common.Constants;
import com.seamew.lottery.domain.strategy.annotation.StrategyMode;
import com.seamew.lottery.domain.strategy.model.vo.AwardRateInfo;
import com.seamew.lottery.domain.strategy.service.algorithm.BaseAlgorithm;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: seamew
 * @Title: EntiretyRateRandomDrawAlgorithm
 * @CreateTime: 2023年02月13日 16:00:00
 * @Description: 必中奖策略抽奖，排掉已经中奖的概率，重新计算中奖范围
 * @Version: 1.0
 */
@Component
@StrategyMode(strategyMode = Constants.StrategyMode.ENTIRETY)
public class EntiretyRateRandomDrawAlgorithm extends BaseAlgorithm {
    @Override
    public String randomDraw(Long strategyId, List<String> excludeAwardIds) {

        BigDecimal differenceDenominator = BigDecimal.ZERO;

        // 排除掉不在抽奖范围的奖品ID集合
        List<AwardRateInfo> differenceAwardRateList = new ArrayList<>();
        List<AwardRateInfo> awardRateIntervalValList = awardRateInfoMap.get(strategyId);
        for (AwardRateInfo awardRateInfo : awardRateIntervalValList) {
            String awardId = awardRateInfo.getAwardId();
            if (excludeAwardIds.contains(awardId)) {
                continue;
            }
            differenceAwardRateList.add(awardRateInfo);
            differenceDenominator = differenceDenominator.add(awardRateInfo.getAwardRate());
        }

        // 前置判断
        if (differenceAwardRateList.size() == 0) return "";
        if (differenceAwardRateList.size() == 1) return differenceAwardRateList.get(0).getAwardId();

        // 获取随机概率值
        int randomVal = generateSecureRandomIntCode(100);

        // 循环获取奖品
        String awardId = "";
        int cursorVal = 0;
        for (AwardRateInfo awardRateInfo : differenceAwardRateList) {
            int rateVal = awardRateInfo
                    .getAwardRate()
                    .divide(differenceDenominator, 2, RoundingMode.UP)
                    .multiply(new BigDecimal(100))
                    .intValue();
            if (randomVal <= (cursorVal + rateVal)) {
                awardId = awardRateInfo.getAwardId();
                break;
            }
            cursorVal += rateVal;
        }

        // 返回中奖结果
        return awardId;
    }
}
