package com.hzs.bonus.bonus.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.hzs.bonus.base.service.ICuMemberService;
import com.hzs.bonus.bonus.service.ICuMemberBonusService;
import com.hzs.bonus.bonus.service.ICuMemberShareDetailService;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.bonus.BdBonusDeduct;
import com.hzs.common.domain.bonus.BdBonusService;
import com.hzs.common.domain.bonus.risk.CuMemberRiskControl;
import com.hzs.common.domain.member.base.CuAwardsControl;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.bonus.*;
import com.hzs.common.domain.member.detail.CuMemberAssess;
import com.hzs.common.domain.member.ext.CuBonusExpandExt;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.common.domain.system.config.BdBonusItems;
import com.hzs.common.domain.system.config.BdGrade;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.dto.*;
import com.hzs.system.sys.dto.BdCurrencyDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 计算首购的奖金处理类
 */
@Component
public class BonusSettleFirstPurchaseHandle extends BonusSettleHandle {

    @DubboReference
    IGradeServiceApi gradeServiceApi;

    @Autowired
    private ICuMemberBonusService cuMemberBonusService;
    @Autowired
    private ICuMemberShareDetailService cuMemberShareDetailService;
    @Autowired
    private ICuMemberService cuMemberService;

    /**
     * 计算直推奖
     *
     * @param settleTableName      结算表
     * @param bonusConfigDTO       参数
     * @param systemConfigMap      系统参数
     * @param firPurchaseOrderList 首单
     */
    List<CuMemberBonusPush> calculateRecommendBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, BonusConfigDTO bonusConfigDTO,
                                                    Map<String, String> systemConfigMap, List<SaOrderExt> firPurchaseOrderList, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, Map<String, BdAwards> awardsMap) {
        // 查询 各个国家 3单循环 4单循环的配置值
        // 获得会员的轮、次，按照订单时间进行
        // 根据订单获取轮次，要回写
        List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryMemberSettleBySaOrder(settleTableName, firPurchaseOrderList);
        getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
        // 推荐奖明细
        List<CuMemberBonusPush> cuMemberBonusPushList = new ArrayList<>();
        Set<Integer> pkCountrySet = firPurchaseOrderList.stream().distinct().map(SaOrderExt::getPkCountry).collect(Collectors.toSet());
        Map<Integer, List<GradeDTO>> gradeDtoMap = gradeServiceApi.queryCountryGradeConfigByCondition(pkCountrySet).getData();
        // 等级对应的业绩
        for (SaOrderExt saOrderExt : firPurchaseOrderList) {
            List<GradeDTO> gradeList = gradeDtoMap.get(saOrderExt.getPkCountry());
            CuMemberBonusPush cuMemberBonusPush = calculatePushBonusOne(cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, cuMemberBonusMap, saOrderExt, awardsMap, gradeList);
            if (cuMemberBonusPush != null) {
                cuMemberBonusPushList.add(cuMemberBonusPush);
            }
        }
        return cuMemberBonusPushList;
    }

    private BigDecimal computePushRangeBonus(CuMemberSettleExt targetMemberSettleExt, BigDecimal siVipBonus,
                                             BigDecimal vipBonus, BigDecimal youBonus) {
        BigDecimal pretaxIncome;
        if (targetMemberSettleExt.getGradeValue() == EGrade.S_VIP.getValue()) {
            pretaxIncome = siVipBonus;
        } else if (targetMemberSettleExt.getGradeValue() == EGrade.VIP.getValue()) {
            pretaxIncome = vipBonus;
        } else {
            pretaxIncome = youBonus;
        }
        return pretaxIncome;
    }


    /**
     * 计算某条订单的推荐奖金
     */
    CuMemberBonusPush calculatePushBonusOne(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, Map<String, String> systemConfigMap, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, SaOrderExt saOrderExt, Map<String, BdAwards> awardsMap, List<GradeDTO> gradeList) {
        CuMemberSettleExt sourceSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
        if (sourceSettleExt == null) {
            return null;
        }
        // 统计注册、升级金额和业绩
        setCuMemberAchieve(saOrderExt, cuMemberSettleExtMap, bonusConfigDTO);
        // 验证订单类型，订单类型是 三方订单的 直推从分享种获取
        // 获取轮次
        CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkReference());
        if (targetMemberSettleExt == null) {
            return null;
        }
        // 死点没有奖金
        if (ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() || EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
            return null;
        }
        if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.DIRECT_INCOME.getValue())) {
            return null;
        }
        CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
        // 直推奖金明细
        int pkBonusItem = getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.DIRECT_INCOME.getValue());
        CuMemberBonusPush cuMemberBonusPush = getCuMemberBonusPush(saOrderExt, targetMemberSettleExt, cuMemberBonus, pkBonusItem);
        // 扣项
        if (Objects.equals(EOrderType.UPGRADE_ORDER.getValue(), saOrderExt.getOrderType())) {
            String value = systemConfigMap.get(targetMemberSettleExt.getPkSettleCountry() + EnumsKeyConstants.BONUS_UPGRADE_TYPE);
            // 只计算固定值，不进入三单
            if (Objects.equals(EUpgradeIncomeType.FIXED_VALUE.getValue(), value)) {
                // 分比例跟固定值
                BonusDifferenceDTO bonusDifferenceDTO = bonusConfigDTO.getBonusDifferenceDtoMap().get(targetMemberSettleExt.getPkSettleCountry());
                // 不算轮次
                cuMemberBonusPush.setCalType(bonusDifferenceDTO.getCalType());
                cuMemberBonusPush.setRound(-1);
                cuMemberBonusPush.setSecond(0);
                // 值
                if (ECalType.VALUE.getValue() == bonusDifferenceDTO.getCalType()) {
                    cuMemberBonusPush.setCalValue(BigDecimal.ZERO);
                    cuMemberBonusPush.setPretaxIncome(bonusDifferenceDTO.getRewardValue());
                } else {
                    cuMemberBonusPush.setCalValue(bonusDifferenceDTO.getRewardValue());
                    cuMemberBonusPush.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrderExt.getOrderAchieve(), bonusDifferenceDTO.getRewardValue()));
                }
                setBonusPushIncome(cuMemberSettleExtMap, bonusConfigDTO, saOrderExt, cuMemberBonus, cuMemberBonusPush);
                return cuMemberBonusPush;
            }
        }
        Map<String, BonusDirectLoopDTO> bonusDirectLoopDtoMap = bonusConfigDTO.getBonusDirectLoopDtoMap();
        Map<String, BonusDirectDTO> bonusDirectDtoMap = bonusConfigDTO.getBonusDirectDtoMap();
        // 根据会员等级获取，等级对应的参数
        // 判断轮次是否满足循环最后一个，最后一个需要重置，增加轮次，获取循环方式
        String recommendType = systemConfigMap.get(targetMemberSettleExt.getPkSettleCountry() + EnumsKeyConstants.BONUS_RECOMMEND_TYPE);
        // 固定值 验证是否推荐的是固定值
        String memberCountryKey = getMemberCountryKey(awardsMap, sourceSettleExt, new HashMap<>());
        BonusDirectDTO bonusDirectDTO = bonusDirectDtoMap.get(memberCountryKey);
        // 现在已经是第三单，取三单最小
        // 验证是不是固定值，固定值直接取比例或者值
        if (bonusDirectDTO != null && ECalType.VALUE.getValue() == bonusDirectDTO.getCalType()) {
            cuMemberBonusPush.setCalType(bonusDirectDTO.getCalType());
//            cuMemberBonusPush.setRound(-1);
//            cuMemberBonusPush.setSecond(0);
            // 值
            cuMemberBonusPush.setCalValue(BigDecimal.ZERO);
            cuMemberBonusPush.setPretaxIncome(bonusDirectDTO.getBonusValue());
//            setBonusPushIncome(cuMemberSettleExtMap, bonusConfigDTO, saOrderExt, cuMemberBonus, cuMemberBonusPush);
//            return cuMemberBonusPush;
        } else {
            // 三单循环
            BonusDirectLoopDTO bonusDirectLoopDTO = bonusDirectLoopDtoMap.get(targetMemberSettleExt.getPkSettleCountry().toString() + recommendType + targetMemberSettleExt.getPkGrade());
            if (bonusDirectLoopDTO == null) {
                if (bonusDirectDTO != null) {
                    cuMemberBonusPush.setCalValue(bonusDirectDTO.getBonusValue());
                } else {
                    return null;
                }
            } else if (targetMemberSettleExt.getSecond() == 1) {
                cuMemberBonusPush.setCalValue(bonusDirectLoopDTO.getFirstOrder());
            } else if (targetMemberSettleExt.getSecond() == 2) {
                cuMemberBonusPush.setCalValue(bonusDirectLoopDTO.getSecondOrder());
            } else if (targetMemberSettleExt.getSecond() == 3) {
                cuMemberBonusPush.setCalValue(bonusDirectLoopDTO.getThirdOrder());
            } else {
                cuMemberBonusPush.setCalValue(bonusDirectLoopDTO.getFourthOrder());
            }
            // 直接计算奖金 业绩 * 计算值，判断是否有扣项
            // 获取等级对应的业绩
            BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
            // 获得升级方式
            String value = systemConfigMap.get(targetMemberSettleExt.getPkSettleCountry() + ESystemConfig.UPGRADE_WAY.getKey());
            if (Objects.equals(Integer.toString(EUpgradeWay.COVER.getValue()), value) && CollectionUtil.isNotEmpty(gradeList)) {
                for (GradeDTO gradeDTO : gradeList) {
                    if (validateGradeByAchieve(saOrderExt.getOrderAmount(), saOrderExt.getOrderAchieve(), gradeDTO)) {
                        orderAchieve = gradeDTO.getStartValue();
                        break;
                    }
                }
            }
            cuMemberBonusPush.setCalAchieve(orderAchieve);
            cuMemberBonusPush.setPretaxIncome(ComputeUtil.computeBonusMultiply(orderAchieve, cuMemberBonusPush.getCalValue()));
        }
        boolean roundEnd = Objects.equals(ERecommendType.THREE_LOOP.getValue(), recommendType) && targetMemberSettleExt.getSecond() == 3;
        if (!roundEnd) {
            roundEnd = Objects.equals(ERecommendType.FOUR_LOOP.getValue(), recommendType) && targetMemberSettleExt.getSecond() == 4;
        }
        // 记录最小值，前面的值>后面的值
        if (ComputeUtil.compareValue(targetMemberSettleExt.getMinAchieve(), cuMemberBonusPush.getCalAchieve()) ||
                ComputeUtil.compareEqual(targetMemberSettleExt.getMinAchieve(), BigDecimal.ZERO)) {
            targetMemberSettleExt.setMinAchieve(cuMemberBonusPush.getCalAchieve());
        }
        if (roundEnd) {
            cuMemberBonusPush.setCalAchieve(targetMemberSettleExt.getMinAchieve());
            cuMemberBonusPush.setPretaxIncome(ComputeUtil.computeBonusMultiply(targetMemberSettleExt.getMinAchieve(), cuMemberBonusPush.getCalValue()));
            reductionMemberSettle(targetMemberSettleExt);
        }
        setBonusPushIncome(cuMemberSettleExtMap, bonusConfigDTO, saOrderExt, cuMemberBonus, cuMemberBonusPush);
        targetMemberSettleExt.setSecond(targetMemberSettleExt.getSecond() + 1);
        return cuMemberBonusPush;
    }

    private Boolean validateGradeByAchieve(BigDecimal settleOrderAmount, BigDecimal settleOrderPv, GradeDTO gradeDTO) {
        BigDecimal compareValue;
        if (null == gradeDTO.getCensusValue() || EStatisticalValue.ACHIEVEMENT.getValue() == gradeDTO.getCensusValue()) {
            compareValue = settleOrderPv;
        } else {
            compareValue = settleOrderAmount;
        }
        BigDecimal startValue = gradeDTO.getStartValue();
        if (compareValue.compareTo(startValue) >= 0) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    void setBonusPushIncome(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, SaOrderExt saOrderExt, CuMemberBonus cuMemberBonus, CuMemberBonusPush cuMemberBonusPush) {
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusPush, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
        recommendRemark(saOrderExt, cuMemberBonusPush, cuMemberSettleExtMap);
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusPush.getIncomeStatus()) {
            cuMemberBonus.setDirectIncome(ComputeUtil.computeAdd(cuMemberBonus.getDirectIncome(), cuMemberBonusPush.getPretaxIncome()));
            setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusPush);
        }
    }

    CuMemberBonusPush getCuMemberBonusPush(SaOrderExt saOrderExt, CuMemberSettleExt cuMemberSettleExt, CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusPush cuMemberBonusPush = CuMemberBonusPush.builder()
                .pkOrder(saOrderExt.getPkId())
                .pkBonus(cuMemberBonus.getPkId())
                .pkBonusItems(pkBonusItems)
                // 正常还是烧伤
                .incomeStatus(cuMemberSettleExt.getIncomeStatus())
                .calType(ECalType.RATIO.getValue())
                .calAchieve(saOrderExt.getOrderAchieve())
                .pretaxIncome(BigDecimal.ZERO)
                .incomeTax(BigDecimal.ZERO)
                .realIncome(BigDecimal.ZERO)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .round(cuMemberSettleExt.getRound())
                .second(cuMemberSettleExt.getSecond())
                .build();
        cuMemberBonusPush.setPkCountry(cuMemberSettleExt.getPkSettleCountry());
        cuMemberBonusPush.setPkCreator(MagicNumberConstants.PK_ADMIN);
        if (EExpireStatus.TERMINATED.getValue() == cuMemberSettleExt.getExpireStatus()) {
            cuMemberBonusPush.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
        }
        return cuMemberBonusPush;
    }

    /**
     * @param settleTableName      结算表
     * @param period               期间
     * @param bonusConfigDTO       参数
     * @param firPurchaseOrderList 首单
     * @param cuMemberBonusMap     所有计算出来的奖金汇总
     * @Description: 计算拓展收益
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/10 14:17
     */
    List<CuMemberBonusExpand> calculateExpandBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleDate, String settleTableName, BonusConfigDTO bonusConfigDTO,
                                                   Map<String, String> systemConfigMap, List<SaOrderExt> firPurchaseOrderList,
                                                   Integer period, Map<Long, CuMemberBonus> weekMemberBonusMap, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                   Map<Long, CuMemberRiskControl> riskControlMap, Map<Long, CuBonusExpandExt> cuBonusExpandExtMap) {
        // 根据开始期间、结束期间查询
        List<CuMemberBonusExpand> cuMemberBonusExpandList = new ArrayList<>();
        // 获取所有订单的上级，根据订单往上一步步计算
        Map<Long, List<CuMemberSettleExt>> memberSettleMap = cuMemberTreeService.batchQueryCuMemberSettlePlaceParent(settleTableName, firPurchaseOrderList);
        // 获取复购考核结果
        List<CuMemberSettleExt> queryMemberList = new ArrayList<>();
        memberSettleMap.forEach((key, value) -> queryMemberList.addAll(value));
        Map<Long, CuMemberAssess> cuMemberAssessMap = getLongCuMemberAssessMap(settleDate, queryMemberList);
        for (SaOrderExt saOrderExt : firPurchaseOrderList) {
            // 所有需要计算的父节点，只计算新增
            List<CuMemberSettleExt> cuMemberSettleExtList = memberSettleMap.get(saOrderExt.getPkId());
            BigDecimal addTouch = BigDecimal.ZERO;
            BigDecimal expandRatio = BigDecimal.ZERO;
            int expandNumber = 0;
            for (int i = cuMemberSettleExtList.size() - 1; i >= 0; i--) {
                CuMemberSettleExt cuMemberSettleExt = cuMemberSettleExtList.get(i);
                if (cuBonusExpandExtMap.containsKey(cuMemberSettleExt.getPkMember())) {
                    addTouch = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getAddTouch();
                    expandRatio = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getExpandRatio();
                    expandNumber = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getExpandNumber();
                    break;
                }
            }
            List<CuMemberBonusExpand> expandList = calculateExpandBonusOne(riskControlMap, cuMemberAssessMap, settleTableName, cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, cuMemberSettleExtList, saOrderExt, true, addTouch, expandRatio, expandNumber);
            if (expandList.size() > 0) {
                cuMemberBonusExpandList.addAll(expandList);
            }
        }
        // 根据订单往上穿业绩，只计算新增
        return cuMemberBonusExpandList;
    }

    /**
     * 计算量奖
     */
    List<CuMemberBonusExpand> calculateExpandBonusOne(Map<Long, CuMemberRiskControl> riskControlMap, Map<Long, CuMemberAssess> cuMemberAssessMap, String settleTableName, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, Map<String, String> systemConfigMap,
                                                      Integer period, Map<Long, CuMemberBonus> weekMemberBonusMap, Map<Long, CuMemberBonus> cuMemberBonusMap, List<CuMemberSettleExt> cuMemberSettleExtList, SaOrderExt saOrderExt, boolean flag, BigDecimal addTouch, BigDecimal expandRatio, Integer expandNumber) {
        List<CuMemberBonusExpand> cuMemberBonusExpandList = new ArrayList<>();
        if (CollectionUtil.isEmpty(cuMemberSettleExtList)) {
            return cuMemberBonusExpandList;
        }
        Map<Integer, BonusExpandDTO> bdBonusExpandMap = bonusConfigDTO.getBonusExpandMap();
        // 先计算新增，根据新增计算碰次
        // 先进行初始化所有的安置人，存储需要修改的值,cuMemberSettleExtMap最终修改的
        if (flag) {
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
        }
        // 先准备值，准备好值后，开始计算，计算碰次
        int touchNum = 0;
//        boolean flag = Boolean.TRUE;
        for (CuMemberSettleExt cuMemberSettleExt : cuMemberSettleExtList) {
//            if(MagicNumberConstants.ACHIEVE_SETTLE_MEMBER.equals(cuMemberSettleExt.getMemberCode())){
//                if(cuMemberTreeService.queryCuMemberUnderUmbrella(settleTableName, saOrderExt.getPkMember())) {
//                    flag = Boolean.FALSE;
//                }
//            }
            // 数据已经准备好了，肯定有值，map中是实际的值，先计算新增，然后根据新增结算计算碰次，list是为了存储碰次的顺序
            CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberSettleExt.getPkPlaceParent());
            if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                    EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus() ||
                    EGrade.START_UP.getValue() == targetMemberSettleExt.getGradeValue()) {
                continue;
            }
            // 验证是否计算奖金
            BdGrade bdGrade = getGradeExpand(bonusConfigDTO, targetMemberSettleExt);
            if (bdGrade.getFirstCalculate() != null && EYesNo.NO.getIntValue() == bdGrade.getFirstCalculate()) {
                continue;
            }
            // 嗨粉、海粉没有量奖
            if (EPlaceDept.LEFT_DEPT.getValue() == cuMemberSettleExt.getPlaceDept()) {
                // 左区
                // K值设置
                if (riskControlMap.containsKey(targetMemberSettleExt.getPkMember())) {
                    CuMemberRiskControl cuMemberRiskControl = riskControlMap.get(targetMemberSettleExt.getPkMember());
                    targetMemberSettleExt.setANewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getANewAmount(), ComputeUtil.computeBonusMultiply(convertLocalCurrency(saOrderExt, bonusConfigDTO), cuMemberRiskControl.getAchieveRatio())));
                    targetMemberSettleExt.setANewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getANewPv(), ComputeUtil.computeBonusMultiply(saOrderExt.getUploadAchieve(), cuMemberRiskControl.getAchieveRatio())));
                    targetMemberSettleExt.setABalance(ComputeUtil.computeAdd(targetMemberSettleExt.getABalance(), ComputeUtil.computeBonusMultiply(saOrderExt.getUploadAchieve(), cuMemberRiskControl.getAchieveRatio())));
                } else {
                    targetMemberSettleExt.setANewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getANewAmount(), convertLocalCurrency(saOrderExt, bonusConfigDTO)));
                    targetMemberSettleExt.setANewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getANewPv(), saOrderExt.getUploadAchieve()));
                    targetMemberSettleExt.setABalance(ComputeUtil.computeAdd(targetMemberSettleExt.getABalance(), saOrderExt.getUploadAchieve()));
                }
                targetMemberSettleExt.setRABalance(ComputeUtil.computeAdd(targetMemberSettleExt.getRABalance(), saOrderExt.getUploadAchieve()));
//                }
            } else {
                // 右区
                if (riskControlMap.containsKey(targetMemberSettleExt.getPkMember())) {
                    CuMemberRiskControl cuMemberRiskControl = riskControlMap.get(targetMemberSettleExt.getPkMember());
                    targetMemberSettleExt.setBNewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewAmount(), ComputeUtil.computeBonusMultiply(convertLocalCurrency(saOrderExt, bonusConfigDTO), cuMemberRiskControl.getAchieveRatio())));
                    targetMemberSettleExt.setBNewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewPv(), ComputeUtil.computeBonusMultiply(saOrderExt.getUploadAchieve(), cuMemberRiskControl.getAchieveRatio())));
                    targetMemberSettleExt.setBBalance(ComputeUtil.computeAdd(targetMemberSettleExt.getBBalance(), ComputeUtil.computeBonusMultiply(saOrderExt.getUploadAchieve(), cuMemberRiskControl.getAchieveRatio())));
                } else {
                    targetMemberSettleExt.setBNewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewAmount(), convertLocalCurrency(saOrderExt, bonusConfigDTO)));
                    targetMemberSettleExt.setBNewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewPv(), saOrderExt.getUploadAchieve()));
                    targetMemberSettleExt.setBBalance(ComputeUtil.computeAdd(targetMemberSettleExt.getBBalance(), saOrderExt.getUploadAchieve()));
                }
                targetMemberSettleExt.setRBBalance(ComputeUtil.computeAdd(targetMemberSettleExt.getRBBalance(), saOrderExt.getUploadAchieve()));
//                }
            }
            // 判断左右区是否有值，左右区有值有碰次
            if (ComputeUtil.compareValue(targetMemberSettleExt.getABalance()) && ComputeUtil.compareValue(targetMemberSettleExt.getBBalance())) {
                // 国内量奖修改为考核不通过的不占用4-N，不算奖金
                // 验证是否验证考核
//                if(bdGrade.getFirstAssess() != null && EAssessmentType.REPURCHASE_ASSESS.getValue() == bdGrade.getFirstAssess()){
//                    if (Objects.equals(CountryConstants.CHINA_COUNTRY, targetMemberSettleExt.getPkSettleCountry()) && !cuMemberAssessMap.containsKey(targetMemberSettleExt.getPkMember()) &&
//                            EYesNo.YES.getIntValue() != targetMemberSettleExt.getPurchaseStatus()) {
//                        BigDecimal minAchieve = ComputeUtil.obtainMinAchieve(targetMemberSettleExt.getABalance(), targetMemberSettleExt.getBBalance());
//                        targetMemberSettleExt.setABalance(ComputeUtil.computeSubtractAbs(targetMemberSettleExt.getABalance(), minAchieve));
//                        targetMemberSettleExt.setBBalance(ComputeUtil.computeSubtractAbs(targetMemberSettleExt.getBBalance(), minAchieve));
//                    }else{
//                        touchNum++;
//                    }
//                } else {
//                    touchNum++;
//                }
                touchNum++;
            }
            // 判断左右区是否有值，左右区有值有碰次
            if (ComputeUtil.compareValue(targetMemberSettleExt.getRABalance()) && ComputeUtil.compareValue(targetMemberSettleExt.getRBBalance())) {
                BigDecimal minAchieve = ComputeUtil.obtainMinAchieve(targetMemberSettleExt.getRABalance(), targetMemberSettleExt.getRBBalance());
                targetMemberSettleExt.setRABalance(ComputeUtil.computeSubtractAbs(targetMemberSettleExt.getRABalance(), minAchieve));
                targetMemberSettleExt.setRBBalance(ComputeUtil.computeSubtractAbs(targetMemberSettleExt.getRBBalance(), minAchieve));
            }
        }
        // 有碰次，计算拓展奖
        if (touchNum > 0) {
            // 判断是否>3 是否需要启动4-N，4-N的参数按照伞上各安置人结算国家进行获取
            // 先计算前3碰
            int startTouch = touchNum;
            // 后面碰次
            int endTouch = 0;
            BonusExpandDTO bdBonusExpand = bdBonusExpandMap.get(saOrderExt.getPkCountry());
            int realExpandNumber = expandNumber > 0 ? expandNumber : bdBonusExpand.getExpandNumber();
            if (touchNum > realExpandNumber) {
                startTouch = realExpandNumber;
                endTouch = touchNum - startTouch;
            }
            // 正常的拓展奖计算
            // 计算拓展奖
            for (int i = 1; i <= startTouch; i++) {
                for (CuMemberSettleExt sourceMemberSettleExt : cuMemberSettleExtList) {
                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(sourceMemberSettleExt.getPkPlaceParent());
                    if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                            EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
                        continue;
                    }
                    if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.EXPANSION_INCOME.getValue())) {
                        continue;
                    }
                    // 判断左右区是否有值，找到有值的就是有碰次，碰完左区或右区肯定有变为0的
                    if (ComputeUtil.compareValue(targetMemberSettleExt.getABalance()) && ComputeUtil.compareValue(targetMemberSettleExt.getBBalance())) {
                        // 根据会员等级获取对应的配置
                        BdGrade bdGrade = getGradeExpand(bonusConfigDTO, targetMemberSettleExt);
                        BigDecimal countryExpandRatio = bdGrade.getExpandRatio();
                        calculateExpandBonusByAchieve(riskControlMap, period, weekMemberBonusMap, cuMemberBonusMap, bonusConfigDTO, systemConfigMap, cuMemberBonusExpandList, saOrderExt, touchNum, i, sourceMemberSettleExt, targetMemberSettleExt, bdGrade, countryExpandRatio, BigDecimal.ZERO, cuMemberAssessMap);
                        break;
                    }
                }
            }
            // 4-N计算
            if (endTouch > 0) {
                // 获得每一碰的比例, 找到剩下的碰次的国家
                for (int i = 1; i <= endTouch; i++) {
                    for (CuMemberSettleExt sourceMemberSettleExt : cuMemberSettleExtList) {
                        CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(sourceMemberSettleExt.getPkPlaceParent());
                        if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                                EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
                            continue;
                        }
                        if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.EXPANSION_INCOME.getValue())) {
                            continue;
                        }
                        // 判断左右区是否有值，找到有值的就是有碰次，碰完左区或右区肯定有变为0的
                        if (ComputeUtil.compareValue(targetMemberSettleExt.getABalance()) && ComputeUtil.compareValue(targetMemberSettleExt.getBBalance())) {
                            // 根据会员等级获取对应的配置
                            BdGrade bdGrade = getGradeExpand(bonusConfigDTO, targetMemberSettleExt);
                            // 获取国家4-n的配置
                            BigDecimal countryExpandRatio = getCountryExpand(bonusConfigDTO, targetMemberSettleExt, endTouch, bdGrade, addTouch, expandRatio);
                            calculateExpandBonusByAchieve(riskControlMap, period, weekMemberBonusMap, cuMemberBonusMap, bonusConfigDTO, systemConfigMap, cuMemberBonusExpandList, saOrderExt, touchNum, i + startTouch, sourceMemberSettleExt, targetMemberSettleExt, bdGrade, countryExpandRatio, addTouch, cuMemberAssessMap);
                            break;
                        }
                    }
                }
                // 将增加的碰次放入烧伤
                if (ComputeUtil.compareValue(addTouch)) {
                    CuMemberSettleExt sourceMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(2L);
                    BdGrade bdGrade = getGradeExpand(bonusConfigDTO, targetMemberSettleExt);
                    BigDecimal countryExpandRatio = getCountryExpand(bonusConfigDTO, targetMemberSettleExt, endTouch, bdGrade, addTouch, expandRatio);
                    countryExpandRatio = ComputeUtil.computeMultiply(countryExpandRatio, addTouch);
                    CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
                    Integer pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.EXPANSION_INCOME.getValue());
                    CuMemberBonusExpand cuMemberBonusExpand = getCuMemberBonusExpand(saOrderExt, touchNum, touchNum, targetMemberSettleExt, countryExpandRatio, cuMemberBonus, saOrderExt.getOrderAchieve(), pkBonusItems, addTouch);
                    expandRemark(saOrderExt, cuMemberBonusExpand, sourceMemberSettleExt, targetMemberSettleExt);
                    cuMemberBonusExpand.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
                    BigDecimal maxIncome = ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getCalAchieve(), bdGrade.getExpandRatio());
                    BigDecimal actualIncome = ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getCalAchieve(), countryExpandRatio);
                    packageCuMemberBonusExpand(cuMemberBonusExpand, cuMemberBonus, bdGrade.getExpandCapping(), maxIncome, actualIncome);
                    setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusExpand, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                    if (ComputeUtil.compareValue(addTouch)) {
                        cuMemberBonusExpand.setRemark(cuMemberBonusExpand.getRemark() + "增加碰次：" + addTouch + "。");
                    }
                    cuMemberBonusExpandList.add(cuMemberBonusExpand);
                }
            }
        }
        return cuMemberBonusExpandList;
    }

    /**
     * @param settleTableName         结算表
     * @param period                  期间
     * @param settleDateStr           结算日期
     * @param bonusConfigDTO          参数
     * @param firPurchaseOrderList    订单列表
     * @param cuMemberBonusExpandList 量奖明细
     * @param cuMemberBonusMap        所有计算出来的奖金汇总
     * @Description: 计算辅导收益
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/10 14:17
     */
    List<CuMemberBonusCoach> calculateCoachBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleDateStr, BonusConfigDTO bonusConfigDTO,
                                                 List<SaOrderExt> firPurchaseOrderList, List<CuMemberBonusExpand> cuMemberBonusExpandList, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                 Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuMemberRiskControl> riskControlMap) {
        Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(firPurchaseOrderList.size()));
        firPurchaseOrderList.forEach(saOrderExt ->
                saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt));
        return calculateCoachBonusOne(cuMemberSettleExtMap, settleTableName, settleDateStr, bonusConfigDTO, cuMemberBonusExpandList, period, cuMemberBonusMap, saOrderExtMap, cuAwardsControlMap, riskControlMap);
    }

    /**
     * @Description: 计算领导奖
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2023/2/8 17:16
     */
    List<CuMemberBonusCoach> calculateCoachBonusOne(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleDateStr, BonusConfigDTO bonusConfigDTO, List<CuMemberBonusExpand> cuMemberBonusExpandList, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                    Map<Long, SaOrderExt> saOrderExtMap, Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuMemberRiskControl> riskControlMap) {
        List<CuMemberBonusCoach> cuMemberBonusCoachList = new ArrayList<>();
        if (cuMemberBonusExpandList.size() > 0) {
            Set<Long> expandMemberSet = getMemberExpandBonus(cuMemberBonusMap, cuMemberBonusExpandList);
            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryCuMemberSettleParent(settleTableName, expandMemberSet);
            // 初始化父类网体的值
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            List<CuMemberSettleExt> queryMemberList = getQueryMemberSettleExtList(cuMemberSettleExtMap, cuMemberSettleExtList);
            // 获取复购考核结果
            Map<Long, CuMemberAssess> cuMemberAssessMap = getLongCuMemberAssessMap(settleDateStr, queryMemberList);
            // 开始计算辅导奖，往上找10代血缘，判断血缘的奖衔是否>= 5的倍数
            Map<Long, CuMemberSettleExt> bonusIdSettleMap = getMemberExpandBonus(cuMemberSettleExtMap);
            for (CuMemberBonusExpand cuMemberBonusExpand : cuMemberBonusExpandList) {
                // 国内没有领导奖
                if (cuMemberBonusExpand.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)) {
                    continue;
                }
                List<CuMemberBonusCoach> coachBonusList = calculateBonusCoach(cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExtMap, cuMemberAssessMap, bonusIdSettleMap, cuMemberBonusExpand, cuAwardsControlMap, riskControlMap);
                if (coachBonusList.size() > 0) {
                    cuMemberBonusCoachList.addAll(coachBonusList);
                }
            }
        }
        return cuMemberBonusCoachList;
    }

    /**
     * @Description: 计算领导奖
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2023/2/8 17:16
     */
    private List<CuMemberBonusCoach> calculateBonusCoach(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, Map<Long, SaOrderExt> saOrderExtMap, Map<Long, CuMemberAssess> cuMemberAssessMap, Map<Long, CuMemberSettleExt> bonusIdSettleMap,
                                                         CuMemberBonusExpand cuMemberBonusExpand, Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuMemberRiskControl> riskControlMap) {
        CuMemberSettleExt sourceMemberSettleExt = bonusIdSettleMap.get(cuMemberBonusExpand.getPkBonus());
        Long pkMember = cuMemberSettleExtMap.get(cuMemberBonusExpand.getPkBonus()).getPkParent();
        // 获得量奖的人往上找10代血缘
        // 用于回写血缘总共多少代
        List<CuMemberBonusCoach> backMemberBonusCoachList = new ArrayList<>();
        int coachGeneration = 0;
        for (int i = MagicNumberConstants.BLOOD_GENERATION_START; i <= MagicNumberConstants.BLOOD_GENERATION_END; i++) {
            CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(pkMember);
            if (targetMemberSettleExt == null) {
                break;
            }
            pkMember = targetMemberSettleExt.getPkParent();
            if (ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                    EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
                continue;
            }
            if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.COACHING_INCOME.getValue())) {
                continue;
            }
            SaOrderExt saOrderExt = saOrderExtMap.get(cuMemberBonusExpand.getPkOrder());
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
            BdAwards awardsCouch = getBdAwards(bonusConfigDTO, targetMemberSettleExt, cuAwardsControlMap);
            // 判断是否有奖金
            if (awardsCouch.getAwardsValue() >= MagicNumberConstants.BLOOD_GENERATION_SERIES * i) {
                BdAwards coachAward = bonusConfigDTO.getAwardsValueMap().get(targetMemberSettleExt.getPkSettleCountry().toString() + ERangeType.AWARDS.getValue() + MagicNumberConstants.BLOOD_GENERATION_SERIES * i);
                BigDecimal awardCalRadio = BigDecimal.ZERO;
                if (coachAward != null) {
                    awardCalRadio = coachAward.getCoachRatio();
                }
                // 判断会员状态
                CuMemberBonusCoach cuMemberBonusCoach = getCuMemberBonusCoach(bonusConfigDTO, cuMemberBonusExpand, i, targetMemberSettleExt, awardCalRadio);
                // 正常状态的辅导奖需要判断复购考核，复购考核不通过的状态变为烧伤
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusCoach.getIncomeStatus() &&
                        EYesNo.NO.getIntValue() == targetMemberSettleExt.getPurchaseStatus()) {
                    // 需要复购考核的
                    CuMemberAssess cuMemberAssess = cuMemberAssessMap.get(targetMemberSettleExt.getPkMember());
                    if (cuMemberAssess == null) {
                        cuMemberBonusCoach.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
                    }
                }
                // K值设置
                if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
                    Integer generation = riskControlMap.get(cuMemberBonus.getPkMember()).getCoachGeneration();
                    if (generation < i) {
                        cuMemberBonusCoach.setIncomeStatus(EBonusIncomeStatus.RISK_CONTROL.getValue());
                    }
                }
                // 判断考核状态，是否考核通过
                // 收益占比
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusCoach, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                coachRemark(saOrderExt, cuMemberBonusCoach, sourceMemberSettleExt, targetMemberSettleExt);
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusCoach.getIncomeStatus()) {
                    cuMemberBonus.setCoachIncome(ComputeUtil.computeAdd(cuMemberBonus.getCoachIncome(), cuMemberBonusCoach.getPretaxIncome()));
                    setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusCoach);
                }
                backMemberBonusCoachList.add(cuMemberBonusCoach);
            }
            coachGeneration = i;
        }
        return handleCoachRemark(backMemberBonusCoachList, coachGeneration);
    }

    /**
     * 判断是否是服务中心，服务中心算主任
     *
     * @param bonusConfigDTO        奖金参数设置
     * @param targetMemberSettleExt 父级
     */
    private BdAwards getBdAwards(BonusConfigDTO bonusConfigDTO, CuMemberSettleExt targetMemberSettleExt, Map<Long, CuAwardsControl> cuAwardsControlMap) {
        return getAwardsCouch(bonusConfigDTO, targetMemberSettleExt, cuAwardsControlMap);
//        BdAwards awardsCouch = getAwardsCouch(bonusConfigDTO, targetMemberSettleExt, cuAwardsControlMap);
        // 判断是否有奖衔，没有奖衔判断是否是服务中心，服务中心算主任
//        if (EAwards.MEMBER.getValue() == awardsCouch.getAwardsValue() && ERegistrationAuthority.SERVICE.getValue() == targetMemberSettleExt.getRegisterAuthority()) {
//            awardsCouch.setAwardsValue(EAwards.HEADER.getValue());
//            // 获取主任对应的比例
//            BdAwards directorAwardsCouch = getDirectorAwardsCouch(bonusConfigDTO, targetMemberSettleExt);
//            // 塞一个临时奖衔，下次就不用在计算一次了
//            if(directorAwardsCouch != null) {
//                targetMemberSettleExt.setPkAwards(directorAwardsCouch.getPkId());
//                awardsCouch.setCoachRatio(directorAwardsCouch.getCoachRatio());
//                awardsCouch.setGlobalIntegral(directorAwardsCouch.getGlobalIntegral());
//                awardsCouch.setCarAwardPoints(directorAwardsCouch.getCarAwardPoints());
//                awardsCouch.setAbonusRatio(directorAwardsCouch.getAbonusRatio());
//                return directorAwardsCouch;
//            }
//        }
//        return awardsCouch;
    }

    private CuMemberBonusCoach getCuMemberBonusCoach(BonusConfigDTO bonusConfigDTO, CuMemberBonusExpand cuMemberBonusExpand,
                                                     int i, CuMemberSettleExt targetMemberSettleExt, BigDecimal awardCalRadio) {
        CuMemberBonusCoach cuMemberBonusCoach = CuMemberBonusCoach.builder()
                .pkBonus(targetMemberSettleExt.getPkMember())
                .pkOrder(cuMemberBonusExpand.getPkOrder())
                .pkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.COACHING_INCOME.getValue()))
                .calType(ECalType.RATIO.getValue())
                .incomeStatus(cuMemberBonusExpand.getIncomeStatus())
                .calAchieve(cuMemberBonusExpand.getPretaxIncome())
                .currentGeneration(i)
                // 计算比例
                .calValue(awardCalRadio)
                .incomeTax(BigDecimal.ZERO)
                .realIncome(BigDecimal.ZERO)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .pretaxIncome(ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getPretaxIncome(), awardCalRadio))
                .coachNoCapping(ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getExpandNoCapping(), awardCalRadio))
                .coachCapping(ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getExpandCapping(), awardCalRadio))
                .coachNormalHalf(ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getExpandNormalHalf(), awardCalRadio))
                .coachNormalReal(ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getExpandNormalReal(), awardCalRadio))
                .build();
        cuMemberBonusCoach.setPkCountry(targetMemberSettleExt.getPkSettleCountry());
        cuMemberBonusCoach.setPkCreator(MagicNumberConstants.PK_ADMIN);
        if (EExpireStatus.TERMINATED.getValue() == targetMemberSettleExt.getExpireStatus()) {
            cuMemberBonusCoach.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
        }
        return cuMemberBonusCoach;
    }

    /**
     * @param backMemberBonusCoachList 临时记录辅导奖列表
     * @param i                        第几代
     * @Description: 处理拓展表备注
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/17 18:02
     */
    private List<CuMemberBonusCoach> handleCoachRemark(List<CuMemberBonusCoach> backMemberBonusCoachList, int i) {
        List<CuMemberBonusCoach> cuMemberBonusCoachList = new ArrayList<>();
        for (CuMemberBonusCoach cuMemberBonusCoach : backMemberBonusCoachList) {
            cuMemberBonusCoach.setCoachGeneration(i);
            cuMemberBonusCoach.setRemark(cuMemberBonusCoach.getRemark().replace("#", cuMemberBonusCoach.getCoachGeneration().toString()));
            cuMemberBonusCoachList.add(cuMemberBonusCoach);
        }
        return cuMemberBonusCoachList;
    }

    /**
     * 计算报单服务费
     *
     * @param settleTableName      结算表
     * @param period               期间
     * @param bonusConfigDTO       参数
     * @param firPurchaseOrderList 订单列表
     * @param cuMemberBonusMap     所有计算出来的奖金汇总
     */
    List<CuMemberBonusDetail> calculateServiceBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleDate, String settleTableName, BonusConfigDTO bonusConfigDTO,
                                                    List<SaOrderExt> firPurchaseOrderList, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        // 先过滤数据，验证报单人是否在网体列表中，不在需要从数据库中查询
        Set<Long> serviceMemberSet = new HashSet<>();
        firPurchaseOrderList.forEach(saOrderExt -> {
            CuMemberSettleExt cuMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
            if (cuMemberSettleExt != null && cuMemberSettleExt.getPkCenterCode() != null) {
                serviceMemberSet.add(cuMemberSettleExt.getPkCenterCode());
            }
        });
        Map<Long, CuMemberAssess> cuMemberAssessMap = packageMemberSettleByPkMemberSet(cuMemberSettleExtMap, settleDate, settleTableName, serviceMemberSet);
        // 计算报单服务费
        for (SaOrderExt saOrderExt : firPurchaseOrderList) {
            // 只有注册订单有报单服务费
            if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
                CuMemberBonusDetail cuMemberBonusDetail = calculateServiceBonusOne(settleDate, cuMemberAssessMap, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt);
                if (cuMemberBonusDetail != null) {
                    cuMemberBonusDetailList.add(cuMemberBonusDetail);
                }
            }
        }
        // 查询会员
        return cuMemberBonusDetailList;
    }

    /**
     * 计算服务中心奖
     */
    CuMemberBonusDetail calculateServiceBonusOne(String settleDate, Map<Long, CuMemberAssess> cuMemberAssessMap, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, SaOrderExt saOrderExt) {
        CuMemberSettleExt sourceMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
        if (sourceMemberSettleExt == null || sourceMemberSettleExt.getPkCenterCode() == null) {
            return null;
        }
        CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(sourceMemberSettleExt.getPkCenterCode());
        if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus() ||
                ERegistrationAuthority.SERVICE.getValue() != targetMemberSettleExt.getRegisterAuthority()) {
            return null;
        }
        // 验证是否有奖金
        if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.SERVICE_SUBSIDIES.getValue())) {
            return null;
        }
        CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
        BdBonusService bdBonusService = bonusConfigDTO.getBonusServiceMap().get(targetMemberSettleExt.getPkSettleCountry().toString() + EServiceType.SUBSIDY.getValue());
//        if (bdBonusService.getAssessmentType() != null && EAssessmentType.REPURCHASE_ASSESS.getValue() == bdBonusService.getAssessmentType()) {
//            // 复购考核不通过，不存在报单服务费
//            boolean flag = cuMemberAssessMap == null || !cuMemberAssessMap.containsKey(targetMemberSettleExt.getPkMember());
//            if (Objects.equals(CountryConstants.CHINA_COUNTRY, targetMemberSettleExt.getPkSettleCountry()) && flag) {
//                return null;
//            }
//        }
        // 服务补贴奖金明细
        CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrderExt, targetMemberSettleExt, cuMemberBonus);
        BigDecimal serviceRadio = bdBonusService.getServiceRadio();
        // 计算比例
        cuMemberBonusDetail.setCalValue(serviceRadio);
        cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.SERVICE_SUBSIDIES.getValue()));
        cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrderExt.getOrderAchieve(), serviceRadio));
        // 收益占比
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
        serviceRemark(saOrderExt, cuMemberBonusDetail, sourceMemberSettleExt, targetMemberSettleExt);
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()
                && EYesNo.NO.getIntValue() == targetMemberSettleExt.getPurchaseStatus()) {
            // 需要复购考核的
            if (cuMemberAssessMap == null || !cuMemberAssessMap.containsKey(targetMemberSettleExt.getPkMember())) {
                cuMemberBonusDetail.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
            }
        }
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
            cuMemberBonus.setServiceIncome(ComputeUtil.computeAdd(cuMemberBonus.getServiceIncome(), cuMemberBonusDetail.getPretaxIncome()));
            setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
        }
        return cuMemberBonusDetail;
    }

    /**
     * @param settleTableName  结算表
     * @param period           期间
     * @param cuMemberBonusMap 所有计算出来的奖金汇总
     * @Description: 计算报单服务费
     * 车奖 全球分红  有奖衔的会员，复购考核通过的，根据对应奖衔可拿代数配置拿下面代数的（推荐+拓展+领导+分红）奖金合计为基数的相应代数的比率（配置值）
     * 跟领导奖一样的算法，不算启动卡
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2022/11/17 14:14
     */
    List<CuMemberBonusDetail> calculateGlobalCarBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, String settleTableName, String settleDateStr,
                                                      Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 查询存在车奖、全球积分的国家
        List<Integer> bonusValueList = new ArrayList<>();
//        bonusValueList.add(EBonusItems.GLOBAL_DIVIDEND.getValue());
//        bonusValueList.add(EBonusItems.CAR_BONUS_POINTS.getValue());
        List<BdBonusItems> bdBonusItemsList = bonusItemsServiceApi.queryExistsBonusItems(bonusValueList).getData();
        // 查询出存在车奖跟全球积分的国家
        Set<Integer> country = new HashSet<>();
        if (bdBonusItemsList != null && bdBonusItemsList.size() > 0) {
            bdBonusItemsList.forEach(bdBonusItems -> country.add(bdBonusItems.getPkCountry()));
            // 查询这几个国家的奖金
            List<CuMemberBonus> cuMemberBonusList = cuMemberBonusService.queryExistsPurchaseBonusMember(period, Arrays.asList(country.toArray(new Integer[]{})));
            return calculateGlobalCarBonusOne(cuMemberSettleExtMap, settleTableName, settleDateStr, bonusConfigDTO, cuMemberBonusList, period, cuMemberBonusMap);
        }
        // 查询所有有奖金的人的所有血缘上级，根据国家查询，只查询有该奖金项的国家
        return null;
    }

    /**
     * @Description: 计算全球积分车奖积分
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2023/2/8 17:16
     */
    List<CuMemberBonusDetail> calculateGlobalCarBonusOne(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleDateStr,
                                                         BonusConfigDTO bonusConfigDTO, List<CuMemberBonus> cuMemberBonusList,
                                                         Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        if (cuMemberBonusList != null && cuMemberBonusList.size() > 0) {
            Set<Long> memberSet = new HashSet<>();
            cuMemberBonusList.forEach(cuMemberBonus ->
                    memberSet.add(cuMemberBonus.getPkMember()));
            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryCuMemberSettleParent(settleTableName, memberSet);
            // 获取复购考核结果
            Map<Long, CuMemberAssess> cuMemberAssessMap = getLongCuMemberAssessMap(settleDateStr, cuMemberSettleExtList);
            // 初始化父类网体的值
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            // 开始计算全球积分车奖积分，往上找10代血缘，判断血缘的奖衔是否>= 5的倍数
            for (CuMemberBonus cuMemberBonus : cuMemberBonusList) {
//                List<CuMemberBonusDetail> bonusDetailList = calculateGlobalCarBonusDetail(cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, cuMemberBonus, EBonusItems.GLOBAL_POINTS.getValue(), cuMemberAssessMap);
//                if (bonusDetailList.size() > 0) {
//                    cuMemberBonusDetailList.addAll(bonusDetailList);
//                }
//                List<CuMemberBonusDetail> carBonusDetailList = calculateGlobalCarBonusDetail(cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, cuMemberBonus, EBonusItems.CAR_BONUS_POINTS.getValue(), cuMemberAssessMap);
//                if (carBonusDetailList.size() > 0) {
//                    cuMemberBonusDetailList.addAll(carBonusDetailList);
//                }
            }
        }
        return cuMemberBonusDetailList;
    }

    /**
     * @Description: 计算全球积分车奖积分
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2023/2/8 17:16
     */
    List<CuMemberBonusDetail> calculateGlobalCarBonusDetail(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap,
                                                            BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, CuMemberBonus sourceMemberBonus,
                                                            Integer incomeType, Map<Long, CuMemberAssess> cuMemberAssessMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        CuMemberSettleExt sourceMemberSettleExt = cuMemberSettleExtMap.get(sourceMemberBonus.getPkMember());
        if (sourceMemberSettleExt == null) {
            return cuMemberBonusDetailList;
        }
        Long pkMember = sourceMemberSettleExt.getPkParent();
        // 获得量奖的人往上找10代血缘
        BigDecimal shareBonus = ComputeUtil.computeAddNum(sourceMemberBonus.getDirectIncome(), sourceMemberBonus.getExpandIncome(),
                sourceMemberBonus.getCoachIncome(), sourceMemberBonus.getShareIncome());
        Map<Long, CuAwardsControl> cuAwardsControlMap = new HashMap<>(10);
        Map<String, BdCurrencyDTO> currencyDtoMap = bonusConfigDTO.getCurrencyDtoMap();
        for (int i = MagicNumberConstants.BLOOD_GENERATION_START; i <= MagicNumberConstants.BLOOD_GENERATION_END; i++) {
            CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(pkMember);
            if (targetMemberSettleExt == null) {
                break;
            }
//            if (EBonusItems.GLOBAL_POINTS.getValue() == incomeType) {
//                if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.GLOBAL_POINTS.getValue())) {
//                    continue;
//                }
//            } else {
////                if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.CAR_BONUS_POINTS.getValue())) {
////                    continue;
////                }
//            }
            if (!targetMemberSettleExt.getPkSettleCountry().equals(sourceMemberBonus.getPkCountry())) {
                continue;
            }
            if (ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                    EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
                continue;
            }
            if (validatePkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), incomeType)) {
                continue;
            }
            SaOrder saOrder = SaOrder.builder().pkRate(targetMemberSettleExt.getPkRate()).build();
            saOrder.setPkCountry(targetMemberSettleExt.getPkCountry());
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
            BdAwards awardsCouch = getBdAwards(bonusConfigDTO, targetMemberSettleExt, cuAwardsControlMap);
            // 判断是否有奖金
            if (awardsCouch.getAwardsValue() >= MagicNumberConstants.BLOOD_GENERATION_SERIES * i) {
                BdAwards coachAward = bonusConfigDTO.getAwardsValueMap().get(targetMemberSettleExt.getPkSettleCountry().toString() + ERangeType.AWARDS.getValue() + MagicNumberConstants.BLOOD_GENERATION_SERIES * i);
                BigDecimal globalIntegral = BigDecimal.ZERO;
                BigDecimal carAwardPoints = BigDecimal.ZERO;
                if (coachAward != null) {
                    globalIntegral = coachAward.getGlobalIntegral();
                    carAwardPoints = coachAward.getCarAwardPoints();
                }
                CuMemberBonusDetail cuMemberBonusDetail = CuMemberBonusDetail.builder()
                        .pkBonus(cuMemberBonus.getPkId())
                        .pkOrder(0L)
                        .calType(ECalType.RATIO.getValue())
                        .incomeStatus(targetMemberSettleExt.getIncomeStatus())
                        .pretaxIncome(BigDecimal.ZERO)
                        .incomeTax(BigDecimal.ZERO)
                        .realIncome(BigDecimal.ZERO)
                        .incomeRatio(BigDecimal.ZERO)
                        .incomeDialRatio(BigDecimal.ZERO)
                        .calAchieve(BigDecimal.ZERO)
                        .orderDialRatio(BigDecimal.ZERO)
                        .build();
                cuMemberBonusDetail.setPkCountry(targetMemberSettleExt.getPkSettleCountry());
                cuMemberBonusDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
                // 计算比例
//                String msg = BonusMsgConstants.GLOBAL_INTEGRAL;
//                if (EBonusItems.GLOBAL_POINTS.getValue() == incomeType) {
//                    cuMemberBonusDetail.setCalValue(globalIntegral);
//                } else {
//                    cuMemberBonusDetail.setCalValue(carAwardPoints);
//                    msg = BonusMsgConstants.CAR_AWARD_POINTS;
//                }
                cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), incomeType));
                // 推荐+拓展+领导+分红 * 比例
                cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(shareBonus, cuMemberBonusDetail.getCalValue()));
                // 收益占比
                BigDecimal exchangeRate = BigDecimal.ONE;
                if (currencyDtoMap.containsKey(cuMemberBonus.getPkCountry().toString() + cuMemberBonus.getPkRate())) {
                    exchangeRate = currencyDtoMap.get(cuMemberBonus.getPkCountry().toString() + cuMemberBonus.getPkRate()).getInExchangeRate();
                }
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, shareBonus, exchangeRate);
//                globalShareRemark(cuMemberBonusDetail, msg);
//                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
//                    if (EBonusItems.GLOBAL_POINTS.getValue() == incomeType) {
//                        cuMemberBonus.setGlobalPoints(ComputeUtil.computeAdd(cuMemberBonus.getGlobalPoints(), cuMemberBonusDetail.getPretaxIncome()));
//                    } else {
//                        cuMemberBonus.setCarAwardPoints(ComputeUtil.computeAdd(cuMemberBonus.getCarAwardPoints(), cuMemberBonusDetail.getPretaxIncome()));
//                    }
//                    setBonusDeduct(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
////                    cuMemberBonus.setRealIncomeTotal(ComputeUtil.computeAdd(cuMemberBonus.getRealIncomeTotal(), cuMemberBonusDetail.getRealIncome()));
//                }
                // 判断会员状态
                // 正常状态的辅导奖需要判断复购考核，复购考核不通过的状态变为烧伤
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus() &&
                        EYesNo.NO.getIntValue() == targetMemberSettleExt.getPurchaseStatus()) {
                    // 需要复购考核的
                    CuMemberAssess cuMemberAssess = cuMemberAssessMap.get(targetMemberSettleExt.getPkMember());
                    if (cuMemberAssess == null) {
                        cuMemberBonusDetail.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
                    }
                }
                pkMember = targetMemberSettleExt.getPkParent();
                cuMemberBonusDetailList.add(cuMemberBonusDetail);
            }
        }
        return cuMemberBonusDetailList;
    }

    /**
     * @param settleDateStr 结算日期
     * @param period        期间
     * @Description: 计算报单服务费
     * 车奖 全球分红  有奖衔的会员，复购考核通过的，根据对应奖衔可拿代数配置拿下面代数的（推荐+拓展+领导+分红）奖金合计为基数的相应代数的比率（配置值）
     * 跟领导奖一样的算法，不算启动卡
     * @return: List<CuMemberBonusCoach>
     * @Author: sui q
     * @Date: 2022/11/17 14:14
     */
    List<CuMemberBonusDetail> calculateShareBonus(String settleDateStr, BonusConfigDTO bonusConfigDTO, Integer period,
                                                  Map<Long, CuMemberBonus> cuMemberBonusMap, Map<Long, CuAwardsControl> cuAwardsControlMap) {
        Date settleDate = DateUtils.parseStringToDate(settleDateStr);
        String currentFirstDate = DateUtils.currentMonthFirstDateStr(settleDate);
        String beforeMonthLastDate = DateUtils.beforeDateStr(1, ChronoUnit.DAYS, DateUtils.YYYY_MM_DD, currentFirstDate);
        // 查询上月最后一天
        Integer beforeMonthLastPeriod = getCuMemberSettlePeriodService().getCuMemberSettlePeriodByDate(beforeMonthLastDate).getPkId();
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + beforeMonthLastPeriod;
        String rangeTableName = TableNameConstants.CU_MEMBER_RANGE + beforeMonthLastPeriod;
        // 查询上月第一天
        String beforeMonthFirstDate = DateUtils.beforeMonthFirstDateStr(settleDate);
        Integer beforeMonthFirstPeriod = getCuMemberSettlePeriodService().getCuMemberSettlePeriodByDate(beforeMonthFirstDate).getPkId();
        // 查询上月最后一天会员等级达到奖衔的会员
        Integer assessPeriod = getCuMemberSettlePeriodService().getCuMemberSettlePeriodByDate(currentFirstDate).getPkId();
        String assessTableName = TableNameConstants.CU_MEMBER_ASSESS + DateUtils.getYear(settleDateStr);
        // 获取结算日期的第一天的日期
        // 查询复购考核结果
        List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.queryMemberSettleByAwards(settleTableName, rangeTableName, beforeMonthFirstPeriod, beforeMonthLastPeriod);
        Map<Long, CuMemberAssess> cuMemberAssessMap = getCuMemberAssessService().queryCuMemberAssessByMember(assessTableName, assessPeriod, EAssessmentType.REPURCHASE_ASSESS.getValue(), cuMemberSettleExtList);
//        List<CuMemberAssess> cuMemberAssessList = getCuMemberAssessService().queryCuMemberShareAssess(assessTableName, assessPeriod);

        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        for (CuMemberSettleExt targetMemberSettleExt : cuMemberSettleExtList) {
            SaOrder saOrder = SaOrder.builder().pkId(0L).orderAchieve(BigDecimal.ZERO).build();
            saOrder.setPkCountry(targetMemberSettleExt.getPkSettleCountry());
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
            CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrder, targetMemberSettleExt, cuMemberBonus);
            cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.DIVIDEND_INCOME.getValue()));
            // 获取计算比例，根据奖衔获取
            // 计算比例
            cuMemberBonusDetail.setCalAchieve(targetMemberSettleExt.getRealIncomeTotal());
            cuMemberBonusDetail.setCalValue(targetMemberSettleExt.getAbonusRatio());
            cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(targetMemberSettleExt.getRealIncomeTotal(), targetMemberSettleExt.getAbonusRatio()));
            shareRemark(cuMemberBonusDetail, settleDateStr);
            BdBonusDeduct bdBonusDeduct = bonusConfigDTO.getBonusDeductsMap().get(cuMemberBonusDetail.getPkBonusItems());
            cuMemberBonusDetail.setIncomeTax(BigDecimal.ZERO);
            cuMemberBonusDetail.setRealIncome(ComputeUtil.computeSubtract(cuMemberBonusDetail.getPretaxIncome(), cuMemberBonusDetail.getIncomeTax()));
            cuMemberBonusDetail.setPkCountry(targetMemberSettleExt.getPkSettleCountry());
            cuMemberBonusDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()
                    && EYesNo.NO.getIntValue() == targetMemberSettleExt.getPurchaseStatus()) {
                // 需要复购考核的
                CuMemberAssess cuMemberAssess = cuMemberAssessMap.get(targetMemberSettleExt.getPkMember());
                if (cuMemberAssess == null) {
                    cuMemberBonusDetail.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
                }
            }
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                cuMemberBonus.setShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getShareIncome(), cuMemberBonusDetail.getPretaxIncome()));
                setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
            }
            cuMemberBonusDetailList.add(cuMemberBonusDetail);
        }
        // 查询月初分红考核数据，只查询出有奖衔的且分红考核通过的
        // 查询分红考核的配置
//        Map<String, CuMemberShareDetail> cuMemberShareDetailMap = cuMemberShareDetailService.queryCuMemberShareBonusByPeriod(assessPeriod);
//        if (CollectionUtil.isNotEmpty(cuMemberAssessList)) {
//            Set<Long> serviceMemberSet = new HashSet<>();
//            cuMemberAssessList.forEach(cuMemberAssess -> serviceMemberSet.add(cuMemberAssess.getPkMember()));
//            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryMemberSettleByMemberPk(settleTableName, serviceMemberSet);
//            // 初始化父类网体的值
//            Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
//            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
//            // 验证国家是否有奖金
//            cuMemberAssessList.forEach(cuMemberAssess -> {
//                if (validatePkBonusItems(bonusConfigDTO, cuMemberAssess.getPkCountry(), EBonusItems.DIVIDEND_INCOME.getValue()) /*|| cuMemberAssess.getPkCountry().equals(CountryConstants.CHINA_COUNTRY)*/) {
//                    return;
//                }
//                CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberAssess.getPkMember());
//                // 处理pk_rate
//                SaOrder saOrder = SaOrder.builder()
//                        .pkId(0L)
//                        .orderAchieve(BigDecimal.ZERO)
//                        .build();
//                saOrder.setPkCountry(targetMemberSettleExt.getPkCountry());
//                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
//                // 分红奖金明细
//                CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrder, targetMemberSettleExt, cuMemberBonus);
//                cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.DIVIDEND_INCOME.getValue()));
//                // 获取计算比例，根据奖衔获取
//                // 计算比例
//                if (cuMemberShareDetailMap.containsKey(targetMemberSettleExt.getPkSettleCountry().toString() + targetMemberSettleExt.getPkAwards())) {
//                    // 获取奖衔
//                    Integer pkAwards = targetMemberSettleExt.getPkAwards();
//                    Long pkMember = targetMemberSettleExt.getPkMember();
//                    if (cuAwardsControlMap.containsKey(pkMember)) {
//                        if (cuAwardsControlMap.get(pkMember).getDividendAward() != null) {
//                            pkAwards = cuAwardsControlMap.get(pkMember).getDividendAward();
//                        }
//                    }
//                    CuMemberShareDetail cuMemberShareDetail = cuMemberShareDetailMap.get(targetMemberSettleExt.getPkSettleCountry().toString() + pkAwards);
//                    if (cuMemberShareDetail == null) {
//                        return;
//                    }
//                    cuMemberBonusDetail.setCalValue(cuMemberShareDetail.getRealShareIncome());
//                } else {
//                    cuMemberBonusDetail.setCalValue(BigDecimal.ZERO);
//                }
//                cuMemberBonusDetail.setPretaxIncome(cuMemberBonusDetail.getCalValue());
//                shareRemark(cuMemberBonusDetail, settleDateStr);
//                BdBonusDeduct bdBonusDeduct = bonusConfigDTO.getBonusDeductsMap().get(cuMemberBonusDetail.getPkBonusItems());
//                BigDecimal incomeTax = BigDecimal.ZERO;
//                if (bdBonusDeduct != null) {
//                    incomeTax = ComputeUtil.computeBonusMultiply(cuMemberBonusDetail.getPretaxIncome(), ComputeUtil.computeAdd(bdBonusDeduct.getPlatformRatio(), bdBonusDeduct.getBackRatio()));
//                }
//                cuMemberBonusDetail.setIncomeTax(incomeTax);
//                cuMemberBonusDetail.setRealIncome(ComputeUtil.computeSubtract(cuMemberBonusDetail.getPretaxIncome(), cuMemberBonusDetail.getIncomeTax()));
//                cuMemberBonusDetail.setPkCountry(targetMemberSettleExt.getPkSettleCountry());
//                cuMemberBonusDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
//                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
//                    cuMemberBonus.setShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getShareIncome(), cuMemberBonusDetail.getPretaxIncome()));
//                    setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
//                }
//                cuMemberBonusDetailList.add(cuMemberBonusDetail);
//            });
//        }
        return cuMemberBonusDetailList;
    }

    /**
     * 计算量碰
     *
     * @param period                  期间
     * @param cuMemberBonusMap        奖金汇总
     * @param cuMemberBonusExpandList 拓展奖奖金明细
     * @param saOrderExt              订单
     * @param touchNum                碰次
     * @param i                       当前碰次
     * @param sourceMemberSettleExt   提供奖金的人
     * @param targetMemberSettleExt   获得奖金的人
     * @param bdGrade                 等级对应的参数
     * @param countryExpandRatio      4-n时计算国家对应的参数
     */
    private void calculateExpandBonusByAchieve(Map<Long, CuMemberRiskControl> riskControlMap, Integer period, Map<Long, CuMemberBonus> weekMemberBonusMap, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                               BonusConfigDTO bonusConfigDTO, Map<String, String> systemConfigMap, List<CuMemberBonusExpand> cuMemberBonusExpandList, SaOrderExt saOrderExt, int touchNum, int i,
                                               CuMemberSettleExt sourceMemberSettleExt, CuMemberSettleExt targetMemberSettleExt, BdGrade bdGrade, BigDecimal countryExpandRatio, BigDecimal addTouch, Map<Long, CuMemberAssess> cuMemberAssessMap) {
        Integer pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.EXPANSION_INCOME.getValue());
        // 验证封顶方式 1=日 2=周，若是周的话需要获取 周奖金
//        BigDecimal weekExpandIncome = BigDecimal.ZERO;
//        if (systemConfigMap.containsKey(targetMemberSettleExt.getPkSettleCountry().toString() + ESystemConfig.EXPAND_CAP_METHOD.getKey())) {
//            String expandCapMethod = systemConfigMap.get(targetMemberSettleExt.getPkSettleCountry() + ESystemConfig.EXPAND_CAP_METHOD.getKey());
//            if (Objects.equals(expandCapMethod, Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue())) &&
//                    weekMemberBonusMap.containsKey(targetMemberSettleExt.getPkMember())) {
//                weekExpandIncome = weekMemberBonusMap.get(targetMemberSettleExt.getPkMember()).getExpandIncome();
//            }
//        }
        BigDecimal gradeExpandRatio = bdGrade.getExpandRatio();
        // 验证受益人等级
        CuMember cuMember = cuMemberService.getMember(targetMemberSettleExt.getMemberCode());
        if (targetMemberSettleExt.getPkSettleCountry().equals(CountryConstants.CHINA_COUNTRY) &&
                cuMember != null && DateUtils.compareDate(DateUtils.parseStringToDate("2024-09-11"), cuMember.getPayTime()) > 0) {
            if (targetMemberSettleExt.getGradeValue() == EGrade.VIP.getValue()) {
                if (ComputeUtil.compareValue(countryExpandRatio, BigDecimal.valueOf(11)) && (i <= 3 || touchNum <= 10)) {
                    countryExpandRatio = BigDecimal.valueOf(13);
                }
            } else if (targetMemberSettleExt.getGradeValue() == EGrade.MAKER.getValue()) {
                if (ComputeUtil.compareValue(countryExpandRatio, BigDecimal.valueOf(10)) && (i <= 3 || touchNum <= 10)) {
                    countryExpandRatio = BigDecimal.valueOf(11);
                }
            }
        }
        // 获取等级封顶值
        CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
        BigDecimal calAchieve = ComputeUtil.obtainMinAchieve(targetMemberSettleExt.getABalance(), targetMemberSettleExt.getBBalance());
        CuMemberBonusExpand cuMemberBonusExpand = getCuMemberBonusExpand(saOrderExt, touchNum, i, targetMemberSettleExt, countryExpandRatio, cuMemberBonus, calAchieve, pkBonusItems, addTouch);
        // 扣减a、b区结余
        targetMemberSettleExt.setABalance(ComputeUtil.computeSubtract(targetMemberSettleExt.getABalance(), calAchieve));
        targetMemberSettleExt.setBBalance(ComputeUtil.computeSubtract(targetMemberSettleExt.getBBalance(), calAchieve));
        // 计算收益 先计算出会员最大的收益
        BigDecimal maxIncome = ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getCalAchieve(), gradeExpandRatio);
        BigDecimal actualIncome = ComputeUtil.computeBonusMultiply(cuMemberBonusExpand.getCalAchieve(), countryExpandRatio);
        // K值设置
        if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
            actualIncome = ComputeUtil.computeBonusMultiply(actualIncome, riskControlMap.get(cuMemberBonus.getPkMember()).getExpandRatio());
            cuMemberBonusExpand.setIncomeStatus(EBonusIncomeStatus.RISK_CONTROL.getValue());
        }
        // 获取等级对应的封顶值
        BigDecimal expandIncome = ComputeUtil.computeAdd(ComputeUtil.computeAdd(cuMemberBonus.getExpandIncome(), actualIncome), cuMemberBonus.getRepurExpandIncome());
        // 判断收益 是否超过封顶值，超过的话变为封顶值
        // 判断是否烧伤，判断原奖金是否>=封顶值,奖金到了就是烧伤
        // 验证会员状态 封停状态跟冻结都正常计算奖金，封停的账号发放的时候奖金发放为0，冻结的账号正常发放，不能登录
        packageCuMemberBonusExpand(cuMemberBonusExpand, cuMemberBonus, bdGrade.getExpandCapping(), maxIncome, actualIncome);
        if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberBonus.getExpandIncome(), cuMemberBonus.getRepurExpandIncome()), bdGrade.getExpandCapping())) {
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusExpand.getIncomeStatus()) {
                cuMemberBonusExpand.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
            }
            expandIncome = ComputeUtil.computeSubtract(bdGrade.getExpandCapping(), ComputeUtil.computeAdd(cuMemberBonus.getExpandIncome(), cuMemberBonus.getRepurExpandIncome()));
        } else if (ComputeUtil.compareGreaterThan(expandIncome, bdGrade.getExpandCapping())) {
            BigDecimal realIncome = ComputeUtil.computeSubtract(bdGrade.getExpandCapping(), ComputeUtil.computeAdd(cuMemberBonus.getExpandIncome(), cuMemberBonus.getRepurExpandIncome()));
            //存在一半烧伤一半正常的值，拆2条
            // 拓展明细表 进行修改
            packageCuMemberBonusExpand(cuMemberBonusExpand, cuMemberBonus, bdGrade.getExpandCapping(), realIncome, realIncome);
            CuMemberBonusExpand fireCuMemberBonusExpand = BeanUtil.copyProperties(cuMemberBonusExpand, CuMemberBonusExpand.class);
            BigDecimal fireIncome = ComputeUtil.computeSubtract(maxIncome, realIncome);
            if (EBonusIncomeStatus.NORMAL.getValue() == fireCuMemberBonusExpand.getIncomeStatus()) {
                fireCuMemberBonusExpand.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
            }
            packageCuMemberBonusExpand(fireCuMemberBonusExpand, cuMemberBonus, bdGrade.getExpandCapping(), fireIncome, fireIncome);
            // 收益占比
            setBonusDetailDeduct(bonusConfigDTO, fireCuMemberBonusExpand, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
            expandRemark(saOrderExt, fireCuMemberBonusExpand, sourceMemberSettleExt, targetMemberSettleExt);
            cuMemberBonusExpandList.add(fireCuMemberBonusExpand);
            // 拓展收益取封顶最大值
            expandIncome = bdGrade.getExpandCapping();
        }
        // 收益占比
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusExpand, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
        expandRemark(saOrderExt, cuMemberBonusExpand, sourceMemberSettleExt, targetMemberSettleExt);
        if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
            cuMemberBonusExpand.setRemark(cuMemberBonusExpand.getRemark() + "K值比例:" + riskControlMap.get(cuMemberBonus.getPkMember()).getExpandRatio() + "。");
        }
        if (ComputeUtil.compareValue(addTouch)) {
            cuMemberBonusExpand.setRemark(cuMemberBonusExpand.getRemark() + "增加碰次：" + addTouch + "。");
        }
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusExpand.getIncomeStatus()
                && EYesNo.NO.getIntValue() == targetMemberSettleExt.getPurchaseStatus()) {
            // 需要复购考核的
            CuMemberAssess cuMemberAssess = cuMemberAssessMap.get(targetMemberSettleExt.getPkMember());
            if (cuMemberAssess == null) {
                cuMemberBonusExpand.setIncomeStatus(EBonusIncomeStatus.FIRE_BURN.getValue());
            }
        }
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusExpand.getIncomeStatus() ||
                EBonusIncomeStatus.RISK_CONTROL.getValue() == cuMemberBonusExpand.getIncomeStatus()) {
            // 判断会员状态，会员状态为封停的话状态修改为停收
            cuMemberBonus.setExpandIncome(ComputeUtil.computeSubtract(expandIncome, cuMemberBonus.getRepurExpandIncome()));
            setFirstPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusExpand);
        }
        cuMemberBonusExpandList.add(cuMemberBonusExpand);
    }

    /**
     * 还原会员结算表，将 轮次 +1 最小值变为0
     *
     * @param cuMemberSettleExt 结算体数据
     */
    private void reductionMemberSettle(CuMemberSettleExt cuMemberSettleExt) {
        cuMemberSettleExt.setMinAchieve(BigDecimal.ZERO);
        cuMemberSettleExt.setSecond(0);
        cuMemberSettleExt.setRound(cuMemberSettleExt.getRound() + 1);
    }
}
