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

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.bonus.achieve.param.MemberAchieveParam;
import com.hzs.bonus.achieve.service.ICuMemberRetailDetailService;
import com.hzs.bonus.achieve.service.ICuMemberRetailRangeService;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.base.service.ICuMemberService;
import com.hzs.bonus.bonus.dto.BonusStageData;
import com.hzs.bonus.bonus.service.ICuMemberBonusStageService;
import com.hzs.bonus.bonus.vo.BonusRecordDetailVO;
import com.hzs.bonus.constant.BonusConstants;
import com.hzs.bonus.detail.service.ICuMemberAwardsService;
import com.hzs.bonus.detail.service.ICuMemberGradeService;
import com.hzs.bonus.order.service.IBonusOrderService;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.constant.RetailConstants;
import com.hzs.common.core.constant.TableNameConstants;
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.member.achieve.CuMemberRetailDetail;
import com.hzs.common.domain.member.achieve.ext.CuMemberRetailRangeExt;
import com.hzs.common.domain.member.bonus.*;
import com.hzs.common.domain.member.detail.*;
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.BdGrade;
import com.hzs.system.config.dto.BonusConfigDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 计算新零售收益
 */
@Slf4j
@Component
public class BonusSettleRangeHandle extends BonusSettleHandle {

    @Autowired
    private ICuMemberRetailDetailService iCuMemberRetailDetailService;
    @Autowired
    private ICuMemberRetailRangeService iCuMemberRetailRangeService;
    @Autowired
    private ICuMemberBonusStageService iCuMemberBonusStageService;
    @Autowired
    private ICuMemberAwardsService iCuMemberAwardsService;
    @Autowired
    private ICuMemberGradeService iCuMemberGradeService;
    @Autowired
    private ICuMemberService iCuMemberService;
    @Autowired
    private IBonusOrderService iBonusOrderService;
    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;

    /**
     * 秒结：
     * 实时计算秒结数据（业绩、奖衔、日奖）
     */
    List<CuMemberBonusRange> calculateCuMemberRetailRangeBonusBySecond(String settleDate, SaOrderExt saOrderExt, BonusConfigDTO bonusConfigDTO,
                                                                       String secondRangeTableName, int beforePeriod, int currentPeriod,
                                                                       Map<Long, CuMemberBonus> cuMemberBonusMap, List<CuMemberBonusDetail> cuMemberBonusDetailList) {
        // 会员级差表
        String rangeTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE + beforePeriod;
        // 更新极差秒接表，用昨天的结算表（血缘伞上）
        iCuMemberRetailRangeService.mergeMemberSecondRetailRangeByRange(rangeTableName, secondRangeTableName, saOrderExt.getPkMember());

        // 按照血缘，查询该会员血缘伞上（昨天日结表累计值 + 今天秒结表新増值）
        List<CuMemberRetailRangeExt> memberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberSecondRangeParent(rangeTableName, secondRangeTableName, saOrderExt.getPkMember());

        // 会员结算map（key：会员ID，value：结算扩展）
        Map<Long, CuMemberRetailRangeExt> memberRangeExtMap = new HashMap<>();

        // 奖衔map（key:奖衔值，value：奖衔对象）
        Map<Integer, BdAwards> retailAwardsMap = new HashMap<>();
        List<BdAwards> awardsList = bonusConfigDTO.getAwardsList();
        awardsList.forEach(bdAwards -> retailAwardsMap.put(bdAwards.getAwardsValue(), bdAwards));

        for (CuMemberRetailRangeExt cuMemberRetailRangeExt : memberRetailRangeExtList) {
            if (!memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
                memberRangeExtMap.put(cuMemberRetailRangeExt.getPkMember(), cuMemberRetailRangeExt);
            }
        }

        // 计算自消费奖衔
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());

        // 订单业绩
        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        // 注册、升级、复购、重消、业绩算个人累计数据（业绩）
        sourceMemberRangeExt.setNewConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getNewConsumePv(), orderAchieve));
        sourceMemberRangeExt.setConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getConsumePv(), orderAchieve));
        sourceMemberRangeExt.setMonthConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getMonthConsumePv(), orderAchieve));
        // 累计业绩，不管激活不激活都处理，兼容不激活判断显示有问题
//        sourceMemberRangeExt.setAllNewConsumePv(sourceMemberRangeExt.getAllNewConsumePv().add(orderAchieve));

        // 会员奖衔升级记录
        List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();

        // 奖金处理
        List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();
        if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()) {
            // 注册，计算奖金： 直推级差收益 + 平级收益
        }

        if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()) {
            // 复购订单
        }

        if (cuMemberAwardsList.size() > 0) {
            // 插入会员奖衔升级记录
            iCuMemberAwardsService.saveBatchCuMemberAwards(cuMemberAwardsList);
            // 更新会员奖衔 -- 当月奖衔、分红奖衔
            iCuMemberService.updateCuMemberRetailRangeByList(cuMemberAwardsList, currentPeriod);
        }

        // 更新秒表结会员数据
        if (memberRetailRangeExtList.size() > 0) {
            iCuMemberRetailRangeService.updateCuMemberSecondRange(secondRangeTableName, memberRangeExtMap);
        }
        return cuMemberBonusRangeList;
    }

    /**
     * 撤单秒结：实时计算撤单数据（业绩、奖衔、日奖）
     */
    void calculateCuMemberBackRetailIncome(SaOrderExt saOrderExt, BonusConfigDTO bonusConfigDTO,
                                           String secondRangeTableName, int beforePeriod, int currentPeriod) {
        // 当天的撤单
        List<CuMemberRetailRangeExt> memberRetailRangeExtList;
        String rangeTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE + beforePeriod;
        // 是否当天
        boolean isSecond = DateUtils.isSameDay(saOrderExt.getPayTime(), DateUtils.currentDate());

        if (isSecond) {
            // 当天撤单
            // 实时网体查询血缘伞上会员，更新秒结表奖衔
            iCuMemberRetailRangeService.mergeMemberRetailGradeByMember(secondRangeTableName, saOrderExt.getPkMember(), EYesNo.YES.getIntValue());
            // 恢复秒结表奖衔
            iCuMemberAwardsService.mergeCuMemberBackAwards(secondRangeTableName, saOrderExt.getPkMember(), currentPeriod);
            // 查询 昨天日结 + 今天秒结 血缘伞上+直推
            memberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberSecondRangeParent(rangeTableName, secondRangeTableName, saOrderExt.getPkMember());
        } else {
            // 非当天撤单
            rangeTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE + currentPeriod;
            List<SaOrderExt> retailOrderList = new ArrayList<>();
            retailOrderList.add(saOrderExt);
            // 实时网体查询血缘上会员，更新订单支付日结表奖衔
            iCuMemberRetailRangeService.mergeMemberRetailGradeByMember(rangeTableName, saOrderExt.getPkMember(), EYesNo.NO.getIntValue());
            // 恢复日结表奖衔
            iCuMemberAwardsService.mergeCuMemberBackAwards(rangeTableName, saOrderExt.getPkMember(), beforePeriod);
            // 查询 订单下单日结 血缘上会员结算数据
            memberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeParent(rangeTableName, retailOrderList);
        }

        // 会员结算map（key：会员ID，value：结算扩展）
        Map<Long, CuMemberRetailRangeExt> memberRangeExtMap = new HashMap<>();

        // 奖衔map（key:奖衔值，value：奖衔对象）
        Map<Integer, BdAwards> retailAwardsMap = new HashMap<>();
        List<BdAwards> awardsList = bonusConfigDTO.getAwardsList();
        awardsList.forEach(bdAwards -> retailAwardsMap.put(bdAwards.getAwardsValue(), bdAwards));

        for (CuMemberRetailRangeExt cuMemberRetailRangeExt : memberRetailRangeExtList) {
            if (!memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
                memberRangeExtMap.put(cuMemberRetailRangeExt.getPkMember(), cuMemberRetailRangeExt);
            }
        }

        // 计算自消费奖衔
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());

        // 订单业绩
        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        // 复购、重消，业绩算个人累计数据（业绩）
        sourceMemberRangeExt.setNewConsumePv(ComputeUtil.computeSubtract(sourceMemberRangeExt.getNewConsumePv(), orderAchieve));
        sourceMemberRangeExt.setConsumePv(ComputeUtil.computeSubtract(sourceMemberRangeExt.getConsumePv(), orderAchieve));
        sourceMemberRangeExt.setMonthConsumePv(ComputeUtil.computeSubtract(sourceMemberRangeExt.getMonthConsumePv(), orderAchieve));
        if (isSecond) {
            // 当天
            // 累计业绩，不管激活不激活都处理，兼容不激活判断显示有问题
//            sourceMemberRangeExt.setAllNewConsumePv(sourceMemberRangeExt.getAllNewConsumePv().subtract(orderAchieve));
        }

        // 会员奖衔map
        Map<String, CuMemberAwards> cuMemberAwardsMap = new HashMap<>();
        // 会员分红奖衔map
        Map<String, CuMemberAwards> cuMemberShareAwardsMap = new HashMap<>();
        // 计算自己奖衔等
        calculateBackGrade(currentPeriod, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap, secondRangeTableName,
                cuMemberAwardsMap, cuMemberShareAwardsMap, sourceMemberRangeExt);
        // 计算团队业绩，计算奖衔
        List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList = calculateRetailBackRangeGradeAwards(currentPeriod, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap,
                secondRangeTableName, cuMemberAwardsMap, cuMemberShareAwardsMap, isSecond);
        cuMemberRetailRangeExtList.add(sourceMemberRangeExt);

        // 当期的所有奖衔升级记录
        List<CuMemberAwards> memberAwardsList = iCuMemberAwardsService.queryCuMemberAwards(cuMemberRetailRangeExtList, currentPeriod);
        if (memberAwardsList.size() > 0) {
            // 当月奖衔升级记录
            List<CuMemberAwards> pkAwardsList = memberAwardsList.stream().filter(tmpData -> tmpData.getAwardType() == EAwardsType.RANGE_TYPE.getValue()).collect(Collectors.toList());
            // 分红奖衔升级记录
            List<CuMemberAwards> pkShareAwardsList = memberAwardsList.stream().filter(tmpData -> tmpData.getAwardType() == EAwardsType.SHARE_TYPE.getValue()).collect(Collectors.toList());

            List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(pkAwardsList)) {
                for (CuMemberAwards cuMemberAwards : pkAwardsList) {
                    String key = cuMemberAwards.getPkMember() + "_" + cuMemberAwards.getNewLevel();
                    if (!cuMemberAwardsMap.containsKey(key)) {
                        CuMemberRetailRangeExt cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberAwards.getPkMember());
                        if (cuMemberAwards.getOldLevel() < cuMemberRetailRangeExt.getPkAwards()) {
                            cuMemberRetailRangeExt.setPkAwards(cuMemberAwards.getOldLevel());
                        }
                        cuMemberAwards.setNewLevel(cuMemberAwards.getOldLevel());
                        cuMemberAwardsList.add(cuMemberAwards);
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(pkShareAwardsList)) {
                for (CuMemberAwards cuMemberAwards : pkShareAwardsList) {
                    String key = cuMemberAwards.getPkMember() + "_" + cuMemberAwards.getNewLevel();
                    if (!cuMemberShareAwardsMap.containsKey(key)) {
                        CuMemberRetailRangeExt cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberAwards.getPkMember());
                        if (cuMemberAwards.getOldLevel() < cuMemberRetailRangeExt.getPkShareAwards()) {
                            cuMemberRetailRangeExt.setPkShareAwards(cuMemberAwards.getOldLevel());
                        }
                        cuMemberAwards.setNewLevel(cuMemberAwards.getOldLevel());
                        cuMemberAwardsList.add(cuMemberAwards);
                    }
                }
            }

            // 处理奖衔
            if (cuMemberAwardsList.size() > 0) {
                // 删除会员奖衔记录
                iCuMemberAwardsService.deleteCuMemberAwards(cuMemberAwardsList, currentPeriod);
                // 更新会员表奖衔数据
                iCuMemberService.updateCuMemberMinAwardsByList(cuMemberAwardsList, currentPeriod);
            }
        }
        // 处理业绩
        if (memberRangeExtMap.size() > 0) {
            if (DateUtils.isSameDay(saOrderExt.getPayTime(), DateUtils.currentDate())) {
                iCuMemberRetailRangeService.updateCuMemberSecondRange(secondRangeTableName, memberRangeExtMap);
            } else {
                iCuMemberRetailRangeService.updateCuMemberRetailRange(rangeTableName, memberRangeExtMap);
            }
        }
    }

    /**
     * 补偿日结明细
     */
    void compensationRetailDetail(Integer period, Integer yesterdayPeriod, String settleDate) {
        if (period == null || yesterdayPeriod == null) {
            // 结算期间
            period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
            String yesterday = DateUtils.beforeDateStr(1, ChronoUnit.DAYS, DateUtils.YYYY_MM_DD, settleDate);
            // 结算期间前一天期间
            yesterdayPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(yesterday).getPkId();
        }

        // 结算明细表
        String rangeDetailTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE_DETAIL + period;
        // 结算明细前一天表
        String yesterdayRangeDetailTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE_DETAIL + yesterdayPeriod;
        // 初始化结算明细数据（昨天数据更新到今天数据）
        iCuMemberRetailRangeService.mergeMemberRetailRangeDetailByYesterday(rangeDetailTableName, yesterdayRangeDetailTableName, false);
    }

    /**
     * 日结：
     * 计算奖金，直推、阶段、级差、平级收益
     */
    void calculateRetailBonusByDay(String settleDate, Map<Long, CuMemberBonus> cuMemberBonusMap, BonusConfigDTO bonusConfigDTO,
                                   BonusRecordDetailVO bonusRecordDetailVO, Integer period, Integer yesterdayPeriod, Boolean isSameMonth) {
        // 结算期间日期
        Date settleStartDate = DateUtils.parseStringToDate(settleDate);
        // 结算期间日期后一天
        Date settleEndDate = DateUtils.afterDate(1, ChronoUnit.DAYS, settleStartDate);

        // 订单（精品、甄选、商城、五折）
        List<SaOrderExt> orderList = iBonusOrderService.listRetailSaOrder(settleStartDate, settleEndDate, null,
                Arrays.asList(EOrderType.RETAIL_REGISTER.getValue(), EOrderType.RETAIL_UPGRADE.getValue(), EOrderType.RETAIL_REPURCHASE.getValue(), EOrderType.DISCOUNT_ORDER.getValue()));

        // 更新当月会员， 将昨天业绩更到到今天，更新当月会员考核结果，有消费的考核通过
        // 结算期间表
        String rangeTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE + period;
        // 结算期间前一天表
        String yesterdayRangeTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE + yesterdayPeriod;
        // 结算明细表
        String rangeDetailTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE_DETAIL + period;
        // 结算明细前一天表
        String yesterdayRangeDetailTableName = TableNameConstants.CU_MEMBER_RETAIL_RANGE_DETAIL + yesterdayPeriod;

        // 初始化结算网体数据（昨天数据更新到今天数据）
        iCuMemberRetailRangeService.mergeMemberRetailRangeByYesterday(rangeTableName, yesterdayRangeTableName, isSameMonth);
        // 初始化结算明细数据（昨天数据更新到今天数据）
        iCuMemberRetailRangeService.mergeMemberRetailRangeDetailByYesterday(rangeDetailTableName, yesterdayRangeDetailTableName, true);
        // 更新会员手动升级
        iCuMemberGradeService.updateCuMemberManualGrade(rangeTableName, period);

        // 升阶段点位列表
        List<CuMemberRetailDetail> stageList = new ArrayList<>();

        if (orderList.size() > 0) {
            // 会员购买升级记录
            Map<Long, CuMemberLevel> memberLevelMap = new HashMap<>();
            List<CuMemberLevel> memberLevelList = iCuMemberGradeService.queryCuMemberLevel(settleStartDate, settleEndDate);
            memberLevelList.forEach(cuMemberLevel -> memberLevelMap.put(cuMemberLevel.getPkOrder(), cuMemberLevel));
            // 等级map（key:等级ID，value:等级对象）
            Map<Integer, BdGrade> gradeIdMap = new HashMap<>();
            List<BdGrade> gradeList = bonusConfigDTO.getGradeList();
            for (BdGrade bdGrade : gradeList) {
                gradeIdMap.put(bdGrade.getPkId(), bdGrade);
            }

            // 奖衔
            Map<Integer, BdAwards> awardsMap = new HashMap<>();
            List<BdAwards> awardsList = bonusConfigDTO.getAwardsList();
            awardsList.forEach(bdAwards -> awardsMap.put(bdAwards.getAwardsValue(), bdAwards));

            // 直推收益、见点收益
            List<CuMemberBonusPush> cuMemberBonusPushList = new ArrayList<>();
            // 领导奖收益、平级奖收益
            List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();
            // 阶段收益
            List<CuMemberBonusStage> cuMemberBonusStageList = new ArrayList<>();
            // 赠品积分
            List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();

            // 更新血缘上个人、团队累计业绩，用于处理奖衔
            Map<Long, MemberAchieveParam> memberAchieveHashMap = new HashMap<>();
            // 订单累计业绩、累计金额
            assortSaOrder(memberAchieveHashMap, orderList);
            // 更新血缘上业绩、金额
            iCuMemberRetailRangeService.updateMemberParentDate(rangeTableName, memberAchieveHashMap);
            // 处理奖衔
            iCuMemberAwardsService.calculateCuMemberAwards(rangeTableName, awardsList, settleStartDate, period);

            // 按照血缘，查询该会员所有伞上会员
            List<CuMemberRetailRangeExt> memberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeParent(rangeTableName, orderList);
            // 会员结算map（key：会员ID，value：结算扩展）
            Map<Long, CuMemberRetailRangeExt> memberRangeExtMap = new HashMap<>();
            // 会员转map
            for (CuMemberRetailRangeExt cuMemberRetailRangeExt : memberRetailRangeExtList) {
                if (!memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
                    memberRangeExtMap.put(cuMemberRetailRangeExt.getPkMember(), cuMemberRetailRangeExt);
                }
            }

            // 只有五折专区需要处理阶段收益
            Set<Long> findMemberDetailSet = orderList.stream().filter(tmpOrder ->
                    EOrderType.RETAIL_REGISTER.getValue() == tmpOrder.getOrderType()
                            || EOrderType.RETAIL_UPGRADE.getValue() == tmpOrder.getOrderType()
                            || EOrderType.RETAIL_REPURCHASE.getValue() == tmpOrder.getOrderType())
                    .map(SaOrderExt::getPkMember).collect(Collectors.toSet());
            // 订单产生的阶段正常情况下只上填三层，这个位置只按每个订单推荐顺序取三级，不需要查全部
            List<Long> findMemberDetailList = this.findParent(memberRangeExtMap, findMemberDetailSet);
            // 查询血缘会员明细数据（一阶段）
            iCuMemberRetailDetailService.listMemberRetailDetail(rangeDetailTableName, memberRangeExtMap, EBonusStage.ONE, EBonusStageStatus.NO, findMemberDetailList);

            for (SaOrderExt saOrderExt : orderList) {
                CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(saOrderExt.getPkMember());
                if (null == sourceMember) {
                    log.warn("订单会员不存在, pkMember: {}", saOrderExt.getPkMember());
                    continue;
                }
                BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
                BigDecimal orderAmount = saOrderExt.getOrderAmount();

                // 自己消费的相关金额、业绩处理
                sourceMember.setNewConsumePv(orderAchieve);
                sourceMember.setMonthConsumePv(sourceMember.getMonthConsumePv().add(orderAchieve));
                sourceMember.setNewConsumeAmount(orderAmount);
                sourceMember.setMonthConsumeAmount(sourceMember.getMonthConsumeAmount().add(orderAmount));
//                // 自己计算奖衔，目前业绩都只往下传，所以此处暂时不需要处理订单会员的奖衔
//                this.calculateAwards(period, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap, cuMemberAwardsList, sourceMember);
                // 累计团队业绩、金额
                this.calculateParentDate(memberRangeExtMap, sourceMember, saOrderExt);

                if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
                    // 精品专区、甄选专区
                    sourceMember.setRegConsumeNewPv(sourceMember.getRegConsumeNewPv().add(orderAchieve));
                    sourceMember.setRegConsumeNewAmount(sourceMember.getRegConsumeNewAmount().add(orderAmount));

                    // 一阶段收益 -- 来源订单金额
                    stageList.addAll(this.calculateStageIncome(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                            memberRangeExtMap, sourceMember, saOrderExt, settleStartDate, rangeTableName, rangeDetailTableName));

                    // 领导级差收益、平级收益 -- 来源PV
                    this.calculateRetailRangeBonus(cuMemberBonusRangeList, memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, period,
                            awardsMap, saOrderExt, sourceMember);

                    // 2025.10.27需求调整，去掉直推收益
//                    // 直推收益 -- 来源订单金额，直推拿业绩的10%
//                    this.calculateDirectIncome(cuMemberBonusPushList, memberRangeExtMap, sourceMember, saOrderExt,
//                            bonusConfigDTO, period, cuMemberBonusMap);

                    // 2025.10.27需求调整，订单满指定PV对应给指定赠品积分
                    this.calculateGiftPoint(memberRangeExtMap, saOrderExt, cuMemberBonusMap, cuMemberBonusDetailList, bonusConfigDTO, period);

                    // 订单存在升级记录
                    if (memberLevelMap.containsKey(saOrderExt.getPkId())) {
                        CuMemberLevel cuMemberLevel = memberLevelMap.get(saOrderExt.getPkId());
                        if (gradeIdMap.containsKey(cuMemberLevel.getNewLevel())) {
                            BdGrade bdGrade = gradeIdMap.get(cuMemberLevel.getNewLevel());
                            if (bdGrade.getGradeValue() > sourceMember.getGradeValue()) {
                                sourceMember.setPkGrade(bdGrade.getPkId());
                                sourceMember.setGradeValue(bdGrade.getGradeValue());
                                sourceMember.setGradeName(bdGrade.getGradeName());
                            }
                        }
                    }

                } else if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()) {
                    // 商城专区
                    sourceMember.setRepConsumeNewPv(sourceMember.getRepConsumeNewPv().add(orderAchieve));
                    sourceMember.setRepConsumeNewAmount(sourceMember.getRepConsumeNewAmount().add(orderAmount));

                    // 一阶段收益 -- 来源订单累计业绩
                    stageList.addAll(this.calculateStageIncome(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                            memberRangeExtMap, sourceMember, saOrderExt, settleStartDate, rangeTableName, rangeDetailTableName));
                    // 见点收益 -- 来源订单业绩，血缘上20代，每代拿业绩的10%
                    this.calculateRepurDirectIncome(cuMemberBonusPushList, memberRangeExtMap, sourceMember, saOrderExt,
                            bonusConfigDTO, period, cuMemberBonusMap);
                    // 领导级差收益、平级收益 -- 来源PV
                    this.calculateRetailRangeBonus(cuMemberBonusRangeList, memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, period,
                            awardsMap, saOrderExt, sourceMember);
                } else if (EOrderType.DISCOUNT_ORDER.getValue() == saOrderExt.getOrderType()) {
                    // 五折专区
                    sourceMember.setRepConsumeNewPv(sourceMember.getRepConsumeNewPv().add(orderAchieve));
                    sourceMember.setRepConsumeNewAmount(sourceMember.getRepConsumeNewAmount().add(orderAmount));

                    // 领导级差收益 -- 来源PV
                    this.calculateRetailRangeBonus(cuMemberBonusRangeList, memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, period,
                            awardsMap, saOrderExt, sourceMember);
                }
            }

            // 处理升二阶段点位
            if (CollectionUtil.isNotEmpty(stageList)) {
                Set<Long> stageMemberList = stageList.stream().map(CuMemberRetailDetail::getPkMember).collect(Collectors.toSet());
                // 查询升阶段点位血缘上所有会员ID
                List<Long> findMemberList = this.findParent(memberRangeExtMap, stageMemberList);
                // 查询血缘会员明细数据（二阶段）
                iCuMemberRetailDetailService.listMemberRetailDetail(rangeDetailTableName, memberRangeExtMap, EBonusStage.TWO, EBonusStageStatus.NO, findMemberList);
                // 二阶段收益
                stageList = this.calculateStageIncomeTwoThree(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                        memberRangeExtMap, settleStartDate, rangeTableName, rangeDetailTableName, EBonusStage.TWO, stageList);
            }

            // 处理升三阶段点位
            if (CollectionUtil.isNotEmpty(stageList)) {
                Set<Long> stageMemberList = stageList.stream().map(CuMemberRetailDetail::getPkMember).collect(Collectors.toSet());
                // 查询升阶段点位血缘上所有会员ID
                List<Long> findMemberList = this.findParent(memberRangeExtMap, stageMemberList);
                // 查询血缘会员明细数据（三阶段）
                iCuMemberRetailDetailService.listMemberRetailDetail(rangeDetailTableName, memberRangeExtMap, EBonusStage.THREE, EBonusStageStatus.NO, findMemberList);
                // 三阶段收益
                this.calculateStageIncomeTwoThree(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                        memberRangeExtMap, settleStartDate, rangeTableName, rangeDetailTableName, EBonusStage.THREE, stageList);
            }

            if (cuMemberBonusPushList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusPushList(cuMemberBonusPushList);
            }
            if (cuMemberBonusRangeList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusRangeList(cuMemberBonusRangeList);
            }
            if (cuMemberBonusStageList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusStageList(cuMemberBonusStageList);
            }
            if (cuMemberBonusDetailList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
            // 更新日结数据
            iCuMemberRetailRangeService.updateCuMemberRetailRange(rangeTableName, memberRangeExtMap);
            // 更新日结明细数据
            iCuMemberRetailRangeService.updateCuMemberRetailDetail(rangeDetailTableName, memberRangeExtMap);
        }
    }

    /**
     * 处理查询阶段会员（订单会员往上推荐查3级），降低初始查询数据过多问题
     */
    private Set<Long> handleStageMember(List<SaOrderExt> orderList, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap) {
        Set<Long> findMemberList = new HashSet<>();
        for (SaOrderExt saOrderExt : orderList) {
            if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()
                    || EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()) {
                long pkParent = saOrderExt.getPkReference();
                // 非五折专区需要处理阶段收益逻辑，查找上级推荐人
                for (int i = 0; i < 3; i++) {
                    CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
                    if (null == targetMember) {
                        break;
                    }
                    pkParent = targetMember.getPkParent();

                    findMemberList.add(targetMember.getPkMember());
                }
            }
        }
        return findMemberList;
    }

    /**
     * 计算奖衔 -- 日结、秒结
     */
    private void calculateGradeAwards(Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, String rangeTableName,
                                      SaOrderExt saOrderExt, Map<Integer, BdAwards> retailAwardsMap,
                                      String secondRangeTableName, List<CuMemberAwards> cuMemberAwardsList,
                                      CuMemberRetailRangeExt targetMemberRangeExt) {
        // 计算当月奖衔
        while (true) {
            // 当月奖衔值 + 5，获取下一个奖衔值
            int awardsValue = targetMemberRangeExt.getAwardsValue() + 5;
            if (retailAwardsMap.containsKey(awardsValue)) {
                // 存在下个奖衔，判断是否能升奖衔
                BdAwards bdAwards = retailAwardsMap.get(awardsValue);
                // 先验证累计业绩
                // new 升级奖衔判断： 月累计业绩 = 本人月消费业绩 + 团队月消费业绩
                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), targetMemberRangeExt.getMonthConsumePv()), bdAwards.getTotalCheck())) {
                    // 累计业绩足够，即可升奖衔
                    cuMemberAwardsList.add(getCuMemberRetailAwards(targetMemberRangeExt, period, saOrderExt, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMemberRangeExt.getPkAwards()));
                    targetMemberRangeExt.setPkAwards(bdAwards.getPkId());
                    targetMemberRangeExt.setAwardsValue(bdAwards.getAwardsValue());
                    targetMemberRangeExt.setAwardsName(bdAwards.getAwardsName());
                    continue;
                }
            }
            break;
        }
    }

    /**
     * 计算团队极差奖衔 -- 退单秒结
     */
    public List<CuMemberRetailRangeExt> calculateRetailBackRangeGradeAwards(Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, String rangeTableName, SaOrderExt saOrderExt,
                                                                            Map<Integer, BdAwards> retailAwardsMap, String secondRangeTableName,
                                                                            Map<String, CuMemberAwards> cuMemberAwardsMap, Map<String, CuMemberAwards> cuMemberShareAwardsMap,
                                                                            boolean isSecond) {
        List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList = new ArrayList<>();
        // 订单会员
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 订单会员的推荐人
        CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(sourceMemberRangeExt.getPkParent());

        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        BigDecimal orderAmount = saOrderExt.getOrderAmount();
        while (targetMemberRangeExt != null) {
            // 累计金额
            targetMemberRangeExt.setTeamNewAmount(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamNewAmount(), orderAmount));
            targetMemberRangeExt.setTeamConsumeAmount(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamConsumeAmount(), orderAmount));
            targetMemberRangeExt.setTeamMonthAmount(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamMonthAmount(), orderAmount));
            // 累计业绩
            targetMemberRangeExt.setTeamNewPv(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamNewPv(), orderAchieve));
            targetMemberRangeExt.setTeamConsumePv(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamConsumePv(), orderAchieve));
            targetMemberRangeExt.setTeamMonthPv(ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamMonthPv(), orderAchieve));
            // 计算
            calculateBackGrade(period, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap, secondRangeTableName,
                    cuMemberAwardsMap, cuMemberShareAwardsMap, targetMemberRangeExt);
            cuMemberRetailRangeExtList.add(targetMemberRangeExt);
            // 计算
            targetMemberRangeExt = memberRangeExtMap.get(targetMemberRangeExt.getPkParent());
        }
        return cuMemberRetailRangeExtList;
    }

    private void calculateBackGrade(Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, String rangeTableName, SaOrderExt saOrderExt,
                                    Map<Integer, BdAwards> retailAwardsMap, String secondRangeTableName,
                                    Map<String, CuMemberAwards> cuMemberAwardsMap, Map<String, CuMemberAwards> cuMemberShareAwardsMap,
                                    CuMemberRetailRangeExt targetMemberRangeExt) {
        // 计算奖衔（荣誉级别）
        while (true) {
            int awardsValue = targetMemberRangeExt.getAwardsValue() + 5;
            if (retailAwardsMap.containsKey(awardsValue)) {
                // 存在下个奖衔，判断是否能升奖衔
                BdAwards bdAwards = retailAwardsMap.get(awardsValue);
                // 先验证累计业绩
                // new 升级奖衔判断为当月累计业绩，累计业绩为团队业绩 + 个人消费业绩
                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), targetMemberRangeExt.getMonthConsumePv()), bdAwards.getTotalCheck())) {
                    // 累计业绩足够，即可升奖衔
                    CuMemberAwards cuMemberRetailAwards = getCuMemberRetailAwards(targetMemberRangeExt, period, saOrderExt, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMemberRangeExt.getPkAwards());
                    cuMemberAwardsMap.put(cuMemberRetailAwards.getPkMember() + "_" + cuMemberRetailAwards.getNewLevel(), cuMemberRetailAwards);
                    targetMemberRangeExt.setPkAwards(bdAwards.getPkId());
                    targetMemberRangeExt.setAwardsValue(bdAwards.getAwardsValue());
                    targetMemberRangeExt.setAwardsName(bdAwards.getAwardsName());
                    continue;
                }
            }
            break;
        }
    }

    private CuMemberBonusRange getCuMemberRetailBonusRange(SaOrder saOrderExt, CuMemberRetailRangeExt targetMemberRangeExt,
                                                           CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusRange cuMemberBonusRange = CuMemberBonusRange.builder()
                .pkBonus(cuMemberBonus.getPkId())
                .pkOrder(saOrderExt.getPkId())
                .pkOrderItems(0L)
                .pkBonusItems(pkBonusItems)
                .incomeStatus(targetMemberRangeExt.getIncomeStatus())
                .calType(ECalType.RATIO.getValue())
                .calAchieve(saOrderExt.getOrderAchieve())
                .calValue(BigDecimal.ZERO)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .build();
        cuMemberBonusRange.setPkCountry(targetMemberRangeExt.getPkSettleCountry());
        cuMemberBonusRange.setPkCreator(MagicNumberConstants.PK_ADMIN);
        return cuMemberBonusRange;
    }

    private CuMemberAwards getCuMemberRetailAwards(CuMemberRetailRangeExt sourceRangeExt, Integer period, SaOrderExt saOrderExt,
                                                   BdAwards bdRangeAwards, Integer awardType, Integer oldLevel) {
        CuMemberAwards cuMemberAwards = CuMemberAwards.builder()
                .pkMember(sourceRangeExt.getPkMember())
                .period(period)
                .upType(EUpgradeType.AUTO_UPGRADE.getValue())
                .awardType(awardType)
                // 原等级
                .oldLevel(null == oldLevel ? sourceRangeExt.getPkAwards() : oldLevel)
                .newLevel(bdRangeAwards.getPkId())
                // 默认不免考
                .purchaseStatus(EYesNo.NO.getIntValue())
                .pkOrder(saOrderExt.getPkId())
                .systemType(2)
                .build();
        cuMemberAwards.setPkCreator(MagicNumberConstants.PK_ADMIN);
        cuMemberAwards.setPkCountry(saOrderExt.getPkCountry());
        cuMemberAwards.setCreationTime(saOrderExt.getPayTime());
        return cuMemberAwards;
    }

    private CuMemberBonusDetail getCuMemberBonusDetail(SaOrder saOrderExt, CuMemberRetailRangeExt targetMemberRangeExt,
                                                       CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusDetail cuMemberBonusDetail = CuMemberBonusDetail.builder()
                .pkBonus(cuMemberBonus.getPkId())
                .pkOrder(saOrderExt.getPkId())
                .pkBonusItems(pkBonusItems)
                .incomeStatus(targetMemberRangeExt.getIncomeStatus())
                .calType(ECalType.VALUE.getValue())
                .calAchieve(saOrderExt.getOrderAchieve())
                .calValue(BigDecimal.ZERO)
                .pretaxIncome(BigDecimal.ZERO)
                .incomeTax(BigDecimal.ZERO)
                .realIncome(BigDecimal.ZERO)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .build();
        cuMemberBonusDetail.setPkCountry(targetMemberRangeExt.getPkSettleCountry());
        cuMemberBonusDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
        return cuMemberBonusDetail;
    }

    /**
     * 计算直推收益 -- 精品专区
     */
    private void calculateDirectIncome(List<CuMemberBonusPush> cuMemberBonusPushList, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap,
                                       CuMemberRetailRangeExt sourceMember, SaOrderExt saOrderExt,
                                       BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 订单会员推荐人
        CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(sourceMember.getPkParent());
        if (null == targetMember) {
            log.warn("直推收益：订单会员推荐人不存在, pkParent: {}", sourceMember.getPkParent());
            return;
        }
        // 死点 或 停算收益 或 顾客 没有奖金
        if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                || EIncomeStatus.STOP_INCOME.getValue() == targetMember.getIncomeStatus()
                || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
            // 非正常会员、停止收益、停算收益，直接跳过
            log.warn("直推收益：订单会员推荐人不满足计算奖金条件, memberCode: {}", targetMember.getMemberCode());
            return;
        }
        // 订单金额 -- 2025.10.13直推改为按业绩来处理
        BigDecimal orderAmount = saOrderExt.getOrderAchieve();
        // 奖金金额
        BigDecimal bonusIncome = orderAmount.multiply(RetailConstants.DIRECT_BONUS_RATIO);

        // 会员奖金数据
        CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(), targetMember.getIncomeStatus(),
                targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? saOrderExt.getPkRate() : targetMember.getPkRate());

        // 直推奖金明细
        int pkBonusItem = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.DIRECT_INCOME.getValue());
        // 直推收益明细
        CuMemberBonusPush cuMemberBonusPush = getCuMemberBonusPush(saOrderExt, targetMember, cuMemberBonus, pkBonusItem);
        cuMemberBonusPush.setCalAchieve(orderAmount);
        cuMemberBonusPush.setCalValue(RetailConstants.DIRECT_BONUS_RATIO);
        cuMemberBonusPush.setPretaxIncome(bonusIncome);
        directIncomeRemark(saOrderExt, cuMemberBonusPush, sourceMember, targetMember);
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusPush, orderAmount, saOrderExt.getInExchangeRate());
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusPush.getIncomeStatus()) {
            cuMemberBonus.setDirectIncome(ComputeUtil.computeAdd(cuMemberBonus.getDirectIncome(), cuMemberBonusPush.getPretaxIncome()));
            setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusPush);
        }
        cuMemberBonusPushList.add(cuMemberBonusPush);
    }

    /**
     * 计算见点收益 -- 商城专区
     */
    private void calculateRepurDirectIncome(List<CuMemberBonusPush> cuMemberBonusPushList, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap,
                                            CuMemberRetailRangeExt sourceMember, SaOrderExt saOrderExt,
                                            BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 推荐人
        long pkParent = sourceMember.getPkParent();
        // 代数
        int algebra = 0;

        while (true) {
            if (algebra >= RetailConstants.REPUR_DIRECT_ALGEBRA) {
                // 20代拿完，则结束
                break;
            }
            CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
            if (null == targetMember) {
                // 推荐人不存在则结束
                log.warn("见点收益：订单会员血缘上推荐人不存在, pkParent: {}", sourceMember.getPkParent());
                break;
            }
            // 死点 或 停算收益 或 顾客 没有奖金
            if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                    || EIncomeStatus.STOP_INCOME.getValue() == targetMember.getIncomeStatus()
                    || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
                // 非正常会员、停止收益、停算收益，直接跳过
                log.warn("见点收益：订单会员血缘上推荐人不满足计算奖金条件, memberCode: {}", targetMember.getMemberCode());
                return;
            }
            pkParent = targetMember.getPkParent();

            // 订单业绩
            BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
            // 奖金金额
            BigDecimal bonusIncome = orderAchieve.multiply(RetailConstants.DIRECT_BONUS_RATIO);

            // 会员奖金数据
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(), targetMember.getIncomeStatus(),
                    targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? saOrderExt.getPkRate() : targetMember.getPkRate());

            // 直推奖金明细
            int pkBonusItem = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.REPUR_DIRECT_INCOME.getValue());
            // 直推收益明细
            CuMemberBonusPush cuMemberBonusPush = getCuMemberBonusPush(saOrderExt, targetMember, cuMemberBonus, pkBonusItem);
            cuMemberBonusPush.setCalAchieve(orderAchieve);
            cuMemberBonusPush.setCalValue(RetailConstants.DIRECT_BONUS_RATIO);
            cuMemberBonusPush.setPretaxIncome(bonusIncome);
            repurDirectIncomeRemark(saOrderExt, cuMemberBonusPush, sourceMember, targetMember, algebra);
            BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusPush, orderAchieve, saOrderExt.getInExchangeRate());
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusPush.getIncomeStatus()) {
                cuMemberBonus.setGlobalPoints(ComputeUtil.computeAdd(cuMemberBonus.getGlobalPoints(), cuMemberBonusPush.getPretaxIncome()));
                setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusPush);
            }
            cuMemberBonusPushList.add(cuMemberBonusPush);

            // 代数 + 1
            algebra++;
        }
    }

    /**
     * 获取直推、见点收益信息
     */
    CuMemberBonusPush getCuMemberBonusPush(SaOrderExt saOrderExt, CuMemberRetailRangeExt cuMemberRetailRange, CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusPush cuMemberBonusPush = CuMemberBonusPush.builder()
                .pkBonus(cuMemberBonus.getPkId())
                .pkOrder(saOrderExt.getPkId())
                .pkBonusItems(pkBonusItems)
                .incomeStatus(cuMemberRetailRange.getIncomeStatus())
                .calType(ECalType.RATIO.getValue())
                .calAchieve(BigDecimal.ZERO)
                .calValue(BigDecimal.ZERO)
                .pretaxIncome(BigDecimal.ZERO)
                .incomeTax(BigDecimal.ZERO)
                .realIncome(BigDecimal.ZERO)
                .round(-1)
                .second(-1)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .build();
        cuMemberBonusPush.setPkCountry(cuMemberRetailRange.getPkSettleCountry());
        cuMemberBonusPush.setPkCreator(MagicNumberConstants.PK_ADMIN);
        return cuMemberBonusPush;
    }

    /**
     * 计算一阶段收益 -- 精品专区、商城专区
     */
    private List<CuMemberRetailDetail> calculateStageIncome(List<CuMemberBonusStage> cuMemberBonusStageList, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                            BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap,
                                                            CuMemberRetailRangeExt sourceMember, SaOrderExt saOrderExt,
                                                            Date settleDate, String rangeTableName, String rangeDetailTableName) {
        List<CuMemberRetailDetail> returnRetailDetailList = new ArrayList<>();

        // 订单生成新点位数量
        int newPointInt;
        if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
            // 精品专区按订单金额计算 -- 2025.10.13精品专区改为按业绩处理
            BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
            // 订单金额除50取整，为新増点位数量
            newPointInt = orderAchieve.divide(RetailConstants.POINT_VAL, 0, RoundingMode.DOWN).intValue();
            if (orderAchieve.compareTo(BonusConstants.GIFT_TWO_AMOUNT) >= 0 && sourceMember.getGiftPoint() < 2) {
                // 首次订单金额大于等于2万，每个点位完成三阶段赠送2个点位
                sourceMember.setGiftPoint(2);
            } else if (orderAchieve.compareTo(BonusConstants.GIFT_ONE_AMOUNT) >= 0 && sourceMember.getGiftPoint() < 1) {
                // 首次订单金额大于等于1万，每个点位完成三阶段赠送1个点位
                sourceMember.setGiftPoint(1);
            }
        } else {
            // 商城专区按累计业绩处理
            BigDecimal repPvBalance = sourceMember.getRepPvBalance().add(saOrderExt.getOrderAchieve());
            newPointInt = repPvBalance.divide(RetailConstants.POINT_VAL, 0, RoundingMode.DOWN).intValue();
            sourceMember.setRepPvBalance(repPvBalance.subtract(RetailConstants.POINT_VAL.multiply(new BigDecimal(newPointInt))));
        }
        if (newPointInt == 0) {
            // 当前订单不足生成点位
            return returnRetailDetailList;
        }
        // 赠送点位
        int pointGift = sourceMember.getGiftPoint();

        // 会员一阶段子点位列表
        LinkedHashMap<Integer, CuMemberRetailDetail> detailList = sourceMember.getOneDetailMap();
        if (null == detailList) {
            detailList = new LinkedHashMap<>();
            sourceMember.setOneDetailMap(detailList);
            sourceMember.setTwoDetailMap(new LinkedHashMap<>());
            sourceMember.setThreeDetailMap(new LinkedHashMap<>());
        }
        // 当前会员子点位总数
        int pointCount = sourceMember.getPointCount();
        for (int i = 1; i <= newPointInt; i++) {
            // 订单会员生成的新点位
            CuMemberRetailDetail newRetailDetail = CuMemberRetailDetail.builder()
                    .pkMember(sourceMember.getPkMember())
                    .childNode(pointCount + i)
                    .stageSort(pointCount + i)
                    .pkParent(sourceMember.getPkParent())
                    .stage(EBonusStage.ONE.getValue())
                    .stageStatus(EBonusStageStatus.NO.getValue())
                    .pointType(EBonusStageType.NORMAL.getValue())
                    .pointGift(pointGift)
                    .creationTime(saOrderExt.getPayTime())
                    .thirdBonus1(0)
                    .thirdBonus2(0)
                    .thirdBonus3(0)
                    .updateBool(0)
                    .build();
            detailList.put(newRetailDetail.getChildNode(), newRetailDetail);

            // 处理阶段点位填充（一阶段）
            this.handleStageIncome(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                    memberRangeExtMap, saOrderExt, settleDate, rangeTableName, rangeDetailTableName, EBonusStage.ONE,
                    sourceMember, newRetailDetail, returnRetailDetailList);
        }
        pointCount += newPointInt;
        sourceMember.setPointCount(pointCount);

        // 待激活点位
        int waitPointCount = sourceMember.getWaitPointCount();
        if (waitPointCount != 0) {
            int giftNewPointInt = 0;
            for (int i = 1; i <= newPointInt; i++) {
                if (waitPointCount > 0) {
                    // 购买一个点位，激活一个待激活点位
                    CuMemberRetailDetail newRetailDetail = CuMemberRetailDetail.builder()
                            .pkMember(sourceMember.getPkMember())
                            .childNode(pointCount + i)
                            .stageSort(pointCount + i)
                            .pkParent(sourceMember.getPkParent())
                            .stage(EBonusStage.ONE.getValue())
                            .stageStatus(EBonusStageStatus.NO.getValue())
                            .pointType(EBonusStageType.GIFT.getValue())
                            .pointGift(0)
                            .creationTime(saOrderExt.getPayTime())
                            .thirdBonus1(0)
                            .thirdBonus2(0)
                            .thirdBonus3(0)
                            .updateBool(0)
                            .build();
                    detailList.put(newRetailDetail.getChildNode(), newRetailDetail);

                    // 处理阶段点位填充（一阶段赠点）
                    this.handleStageIncome(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                            memberRangeExtMap, saOrderExt, settleDate, rangeTableName, rangeDetailTableName, EBonusStage.ONE,
                            sourceMember, newRetailDetail, returnRetailDetailList);

                    waitPointCount = waitPointCount - 1;
                    giftNewPointInt += 1;
                } else {
                    break;
                }
            }
            sourceMember.setPointCount(sourceMember.getPointCount() + giftNewPointInt);
            sourceMember.setWaitPointCount(waitPointCount);
        }
        return returnRetailDetailList;
    }

    /**
     * 计算二、三阶段收益
     */
    private List<CuMemberRetailDetail> calculateStageIncomeTwoThree(List<CuMemberBonusStage> cuMemberBonusStageList, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                                    BonusConfigDTO bonusConfigDTO, Integer period,
                                                                    Map<Long, CuMemberRetailRangeExt> memberRangeExtMap,
                                                                    Date settleDate, String rangeTableName, String rangeDetailTableName, EBonusStage eBonusStage,
                                                                    List<CuMemberRetailDetail> stageList) {
        List<CuMemberRetailDetail> returnRetailDetailList = new ArrayList<>();
        for (CuMemberRetailDetail memberRetailDetail : stageList) {
            // 订单会员
            CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(memberRetailDetail.getPkMember());
            if (null == sourceMember) {
                log.error("阶段收益处理失败，{} 会员不存在. pkMember: {}", eBonusStage.getLabel(), memberRetailDetail.getPkMember());
                return returnRetailDetailList;
            }

            // 处理阶段点位填充
            this.handleStageIncome(cuMemberBonusStageList, cuMemberBonusMap, bonusConfigDTO, period,
                    memberRangeExtMap, null, settleDate, rangeTableName, rangeDetailTableName, eBonusStage,
                    sourceMember, memberRetailDetail, returnRetailDetailList);
        }
        return returnRetailDetailList;
    }

    /**
     * 处理阶段收益（一、二、三阶段）
     */
    private void handleStageIncome(List<CuMemberBonusStage> cuMemberBonusStageList, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                   BonusConfigDTO bonusConfigDTO, Integer period,
                                   Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, SaOrderExt saOrderExt,
                                   Date settleDate, String rangeTableName, String rangeDetailTableName, EBonusStage eBonusStage,
                                   CuMemberRetailRangeExt sourceMember, CuMemberRetailDetail newRetailDetail,
                                   List<CuMemberRetailDetail> returnRetailDetailList) {
        // 阶段奖金处理列表
        List<BonusStageData> bonusStageDataList = new ArrayList<>();

        boolean giftBool = false;
        if (EBonusStageType.GIFT.getValue() == newRetailDetail.getPointType()) {
            // 赠送点位处理，赠送点位给自己直推会员轮流布点
            iCuMemberRetailDetailService.listChildRetailDetail(rangeTableName, rangeDetailTableName, memberRangeExtMap,
                    sourceMember, eBonusStage);
            // 判断是不是都已经填充过一轮了，如果是则需要重新开始从第一个开始填充
            LinkedHashMap<Date, CuMemberRetailRangeExt> childRetailMap = sourceMember.getChildRetailMap();
            if (childRetailMap.size() > 0) {
                // 获取最后一条数据 key
                Date lastKey = new ArrayList<>(childRetailMap.keySet()).get(childRetailMap.size() - 1);
                // 获取最新的会员注册时间，如果没有则设置一个初始化时间
                Date giftPayTime = sourceMember.getGiftPayTime();
                if (null == giftPayTime || giftPayTime.compareTo(lastKey) == 0) {
                    giftPayTime = BonusConstants.GIFT_PAY_TIME;
                }

                for (Date keyDate : childRetailMap.keySet()) {
                    if (keyDate.compareTo(giftPayTime) > 0) {
                        // 当前会员注册比之前的要晚，则顺序进行填充
                        giftPayTime = keyDate;
                        // 需要填充的直推会员
                        CuMemberRetailRangeExt targetMember = childRetailMap.get(keyDate);

                        if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                                || EIncomeStatus.STOP_INCOME.getValue() == targetMember.getIncomeStatus()
                                || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
                            // 非正常会员、停止收益、停算收益，直接跳过
                            log.warn("阶段收益：订单会员推荐人不满足计算奖金条件, memberCode: {}", targetMember.getMemberCode());
                            continue;
                        }

                        // 直推会员一阶段子点位列表
                        LinkedHashMap<Integer, CuMemberRetailDetail> parentDetailList = targetMember.getOneDetailMap();
                        if (CollectionUtil.isEmpty(parentDetailList)) {
                            continue;
                        }

                        // 直推会员第一层点位处理
                        giftBool = iCuMemberBonusStageService.firstLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                                memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                        if (giftBool) {
                            // 在第一层找到并填充点位，就开始下一个点位的处理
                            break;
                        }
                        // 直推会员第二层点位处理
                        giftBool = iCuMemberBonusStageService.secondLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                                memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                        if (giftBool) {
                            // 在第二层找到并填充点位，就开始下一个点位的处理
                            break;
                        }
                        // 直推会员第三层点位处理
                        giftBool = iCuMemberBonusStageService.thirdLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                                memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                        if (giftBool) {
                            // 在第三层找到并填充点位，就开始下一个点位的处理
                            break;
                        }
                    }
                }
                if (giftBool) {
                    sourceMember.setGiftPayTime(giftPayTime);
                }
            }
        }

        if (EBonusStageType.NORMAL.getValue() == newRetailDetail.getPointType()
                || !giftBool) {
            // 普通点位处理
            // 推荐人
            Long pkParent = sourceMember.getPkParent();
            while (true) {
                CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
                if (null == targetMember) {
                    // 没有推荐人了，则直接结束
                    break;
                }
                pkParent = targetMember.getPkParent();

                if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                        || EIncomeStatus.STOP_INCOME.getValue() == targetMember.getIncomeStatus()
                        || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
                    // 非正常会员、停止收益、停算收益，直接跳过
                    log.warn("阶段收益：订单会员推荐人不满足计算奖金条件, memberCode: {}", targetMember.getMemberCode());
                    continue;
                }

                // 推荐人一阶段子点位列表
                LinkedHashMap<Integer, CuMemberRetailDetail> parentDetailList = null;
                if (EBonusStage.ONE.getValue() == eBonusStage.getValue()) {
                    if (null == targetMember.getOneDetailMap()) {
                        // 目标会员当前阶段为空，则需要查询一下当前阶段未完成点位数据
                        List<CuMemberRetailDetail> tmpDetailList = iCuMemberRetailDetailService.listMemberRetailDetailByQuery(
                                rangeDetailTableName, memberRangeExtMap, Collections.singletonList(targetMember.getPkMember()), EBonusStage.ONE);
                        if (CollectionUtil.isEmpty(tmpDetailList)) {
                            targetMember.setOneDetailMap(new LinkedHashMap<>());
                        }
                    }
                    parentDetailList = targetMember.getOneDetailMap();
                } else if (EBonusStage.TWO.getValue() == eBonusStage.getValue()) {
                    if (null == targetMember.getTwoDetailMap()) {
                        // 目标会员当前阶段为空，则需要查询一下当前阶段未完成点位数据
                        List<CuMemberRetailDetail> tmpDetailList = iCuMemberRetailDetailService.listMemberRetailDetailByQuery(
                                rangeDetailTableName, memberRangeExtMap, Collections.singletonList(targetMember.getPkMember()), EBonusStage.TWO);
                        if (CollectionUtil.isEmpty(tmpDetailList)) {
                            targetMember.setTwoDetailMap(new LinkedHashMap<>());
                        }
                    }
                    parentDetailList = targetMember.getTwoDetailMap();
                } else if (EBonusStage.THREE.getValue() == eBonusStage.getValue()) {
                    if (null == targetMember.getThreeDetailMap()) {
                        // 目标会员当前阶段为空，则需要查询一下当前阶段未完成点位数据
                        List<CuMemberRetailDetail> tmpDetailList = iCuMemberRetailDetailService.listMemberRetailDetailByQuery(
                                rangeDetailTableName, memberRangeExtMap, Collections.singletonList(targetMember.getPkMember()), EBonusStage.THREE);
                        if (CollectionUtil.isEmpty(tmpDetailList)) {
                            targetMember.setThreeDetailMap(new LinkedHashMap<>());
                        }
                    }
                    parentDetailList = targetMember.getThreeDetailMap();
                }
                if (CollectionUtil.isEmpty(parentDetailList)) {
                    // 推荐人没有未完成点位，继续往上找
                    continue;
                }

                // 推荐人第一层点位处理
                boolean forBool = iCuMemberBonusStageService.firstLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                        memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                if (forBool) {
                    // 在第一层找到并填充点位，就开始下一个点位的处理
                    break;
                }
                // 推荐人第二层点位处理
                forBool = iCuMemberBonusStageService.secondLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                        memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                if (forBool) {
                    // 在第二层找到并填充点位，就开始下一个点位的处理
                    break;
                }
                // 推荐人第三层点位处理
                forBool = iCuMemberBonusStageService.thirdLevelhandle(parentDetailList, newRetailDetail, rangeTableName, rangeDetailTableName,
                        memberRangeExtMap, settleDate, eBonusStage, bonusStageDataList);
                if (forBool) {
                    // 在第三层找到并填充点位，就开始下一个点位的处理
                    break;
                }
            }
        }

        if (CollectionUtil.isNotEmpty(bonusStageDataList)) {
            // 有需要生成奖金的数据
            for (BonusStageData bonusStageData : bonusStageDataList) {
                CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(bonusStageData.getTargetPkMember());
                // 会员奖金数据
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(), targetMember.getIncomeStatus(),
                        targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? (saOrderExt != null ? saOrderExt.getPkRate() : 0) : targetMember.getPkRate());
                // 阶段奖金
                int pkBonusItem = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.STAGE_INCOME.getValue());
                // 阶段收益明细
                CuMemberBonusStage cuMemberBonusStage = iCuMemberBonusStageService.getCuMemberBonusStage(saOrderExt, targetMember, cuMemberBonus, pkBonusItem);
                cuMemberBonusStage.setPretaxIncome(bonusStageData.getBonusIncome());
                cuMemberBonusStage.setChildNode(bonusStageData.getTargetChildNode());
                cuMemberBonusStage.setStage(bonusStageData.getStage());
                cuMemberBonusStage.setStageNum(bonusStageData.getStageNum());
                cuMemberBonusStage.setPkSourceMember(sourceMember.getPkMember());
                stageIncomeRemark(saOrderExt, cuMemberBonusStage, sourceMember, targetMember);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusStage, saOrderExt != null ? saOrderExt.getOrderAmount() : null, saOrderExt != null ? saOrderExt.getInExchangeRate() : null);
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusStage.getIncomeStatus()) {
                    cuMemberBonus.setStoreIncome(ComputeUtil.computeAdd(cuMemberBonus.getStoreIncome(), cuMemberBonusStage.getPretaxIncome()));
                    setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusStage);
                }
                cuMemberBonusStageList.add(cuMemberBonusStage);

                // 升阶段数据
                if (EBonusStage.ONE.getValue() == bonusStageData.getStage()) {
                    // 一阶段需要处理升阶段
                    CuMemberRetailDetail twoRetailDetail = bonusStageData.getTwoRetailDetail();
                    Integer pointCount2 = targetMember.getPointCount2() + 1;
                    targetMember.setPointCount2(pointCount2);
                    twoRetailDetail.setStageSort(pointCount2);
                    if (pointCount2 == 1) {
                        // 二阶段的第一个点位，之前没有过，需要创建二阶段点位列表
                        targetMember.setTwoDetailMap(new LinkedHashMap<>());
                    }
                    targetMember.getTwoDetailMap().put(twoRetailDetail.getChildNode(), twoRetailDetail);

                    returnRetailDetailList.add(twoRetailDetail);
                } else if (EBonusStage.TWO.getValue() == bonusStageData.getStage()) {
                    // 二阶段需要处理升阶段
                    CuMemberRetailDetail threeRetailDetail = bonusStageData.getThreeRetailDetail();
                    Integer pointCount3 = targetMember.getPointCount3() + 1;
                    targetMember.setPointCount3(pointCount3);
                    threeRetailDetail.setStageSort(pointCount3);
                    if (pointCount3 == 1) {
                        // 三阶段的第一个点位，之前没有过，需要创建三阶段点位列表
                        targetMember.setThreeDetailMap(new LinkedHashMap<>());
                    }
                    targetMember.getThreeDetailMap().put(threeRetailDetail.getChildNode(), threeRetailDetail);

                    returnRetailDetailList.add(threeRetailDetail);
                } else if (EBonusStage.THREE.getValue() == bonusStageData.getStage()) {
                    // 三阶段填充满，判断是否需要赠送点位
                    if (bonusStageData.getPointGift() != 0) {
                        // 需要添加赠送的待激活点位
                        targetMember.setWaitPointCount(targetMember.getWaitPointCount() + bonusStageData.getPointGift());
                    }
                }
            }
        }
    }

    /**
     * 查找血缘上会员（3层）
     */
    private List<Long> findParent(Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, Set<Long> pkMemberList) {
        List<Long> resultList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(pkMemberList)) {
            for (Long pkMember : pkMemberList) {
                CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(pkMember);
                resultList.add(sourceMember.getPkMember());

                int i = 1;
                Long pkParent = sourceMember.getPkParent();
                while (true) {
                    if (i > 3) {
                        break;
                    }
                    CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
                    if (null == targetMember) {
                        break;
                    }
                    pkParent = targetMember.getPkParent();

                    resultList.add(targetMember.getPkMember());
                    i += 1;
                }
            }
        }
        return resultList;
    }

//    /**
//     * 计算奖衔
//     */
//    private void calculateAwards(Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, String rangeTableName,
//                                 SaOrderExt saOrderExt, Map<Integer, BdAwards> retailAwardsMap, List<CuMemberAwards> cuMemberAwardsList,
//                                 CuMemberRetailRangeExt targetMember) {
//        // 校验大小区会员数据
//        List<CuMemberRetailRangeExt> cuMemberRangeExtList = null;
//        // 计算分红奖衔
//        while (true) {
//            // 当月奖衔值 + 5，获取下一个奖衔值
//            int awardsValue = targetMember.getAwardsValue() + 5;
//            if (retailAwardsMap.containsKey(awardsValue)) {
//                BdAwards bdAwards = retailAwardsMap.get(awardsValue);
//
//                if (ComputeUtil.compareValue(targetMember.getTeamConsumePv(), bdAwards.getTotalCheck())) {
//                    // 团队累计业绩 >= 奖衔累计业绩
//                    if (null == cuMemberRangeExtList) {
//                        // 昨日结算表，查询会员直推数据
//                        cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeExtByParent(rangeTableName, targetMember.getPkMember());
//                    }
//                    // 大区
//                    BigDecimal consumeBigPv = BigDecimal.ZERO;
//                    for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRangeExtList) {
//                        if (memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
//                            cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberRetailRangeExt.getPkMember());
//                        }
//                        // 累计业绩 = 团队累计消费业绩 + 个人累计消费业绩
//                        BigDecimal consumePv = cuMemberRetailRangeExt.getTeamConsumePv().add(cuMemberRetailRangeExt.getConsumePv());
//                        if (ComputeUtil.compareGreaterThan(consumePv, consumeBigPv)) {
//                            // 累计业绩 > 大区业绩，则累计就成为大区
//                            consumeBigPv = consumePv;
//                        }
//                    }
//                    // 小区业绩 = 团队累计业绩 - 大区业绩
//                    BigDecimal smallAreaPv = ComputeUtil.computeSubtract(targetMember.getTeamConsumePv(), consumeBigPv);
//                    if (smallAreaPv.compareTo(bdAwards.getCommunityCheck()) >= 0) {
//                        // 小区业绩 >= 考核小区业绩
//                        if (bdAwards.getPlaceDeptNum() > 0) {
//                            // 验证每条血缘下，满足达标数量
//                            List<Integer> checkList = iCuMemberRetailRangeService.listChildAwards(rangeTableName, bdAwards.getPkCheckAwardsLeft(),
//                                    cuMemberRangeExtList.stream().map(CuMemberRetailRangeExt::getPkMember).collect(Collectors.toList()));
//                            if (CollectionUtil.isNotEmpty(checkList) && checkList.size() >= bdAwards.getPlaceDeptNum()) {
//                                cuMemberAwardsList.add(getCuMemberRetailAwards(targetMember, period, saOrderExt, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMember.getPkAwards()));
//                                targetMember.setPkAwards(bdAwards.getPkId());
//                                targetMember.setAwardsValue(bdAwards.getAwardsValue());
//                                continue;
//                            }
//                        } else {
//                            // 不需要考核血缘达标，直接给奖衔
//                            cuMemberAwardsList.add(getCuMemberRetailAwards(targetMember, period, saOrderExt, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMember.getPkAwards()));
//                            targetMember.setPkAwards(bdAwards.getPkId());
//                            targetMember.setAwardsValue(bdAwards.getAwardsValue());
//                            continue;
//                        }
//                    }
//                }
//            }
//            break;
//        }
//    }

    /**
     * 计算团队数据
     */
    private void calculateParentDate(Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, CuMemberRetailRangeExt sourceMember,
                                     SaOrderExt saOrderExt) {
        // 订单会员的推荐人
        CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(sourceMember.getPkParent());

        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        BigDecimal orderAmount = saOrderExt.getOrderAmount();
        while (null != targetMember) {
            // 累计业绩
            targetMember.setTeamNewPv(targetMember.getTeamNewPv().add(orderAchieve));
            targetMember.setTeamMonthPv(targetMember.getTeamMonthPv().add(orderAchieve));
            // 累计金额
            targetMember.setTeamNewAmount(targetMember.getTeamNewAmount().add(orderAmount));
            targetMember.setTeamMonthAmount(targetMember.getTeamMonthAmount().add(orderAmount));
            if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()
            ) {
                // 团队精品专区
                targetMember.setRegTeamNewPv(targetMember.getRegTeamNewPv().add(orderAchieve));
                targetMember.setRegTeamNewAmount(targetMember.getRegTeamNewAmount().add(orderAmount));
            } else if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()
                    || EOrderType.DISCOUNT_ORDER.getValue() == saOrderExt.getOrderType()) {
                // 团队商城专区
                targetMember.setRepTeamNewPv(targetMember.getRepTeamNewPv().add(orderAchieve));
                targetMember.setRepTeamNewAmount(targetMember.getRepTeamNewAmount().add(orderAmount));
            }
            targetMember = memberRangeExtMap.get(targetMember.getPkParent());
        }
    }


    /**
     * 计算领导奖、平级奖
     */
    private void calculateRetailRangeBonus(List<CuMemberBonusRange> cuMemberBonusRangeList, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap,
                                           Map<Long, CuMemberBonus> cuMemberBonusMap, BonusConfigDTO bonusConfigDTO, Integer period,
                                           Map<Integer, BdAwards> awardsMap, SaOrderExt saOrderExt, CuMemberRetailRangeExt sourceMember) {
        // 订单PV
        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
            // 精品专区、甄选专区，最大值为350PV超过的也算350PV -- 2025.10.13改为500处理
            if (orderAchieve.compareTo(BonusConstants.RANGE_BONUS_ACHIEVE) > 0) {
                orderAchieve = BonusConstants.RANGE_BONUS_ACHIEVE;
            }
        }

        // 领导奖从自己开始算
        long pkParent = sourceMember.getPkMember();

        // 前一个会员奖衔
        int beforeAwardsValue = 0;
        // 前一个会员级差比例
        BigDecimal beforeRangeRatio = BigDecimal.ZERO;
        // 前一个会员等级的平级收益人数
        int beforeSameAlgebra = 0;
        // 计算直推级差
        while (true) {
            // 推荐人
            CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
            if (null == targetMember) {
                break;
            }
            // 推荐人的推荐人
            pkParent = targetMember.getPkParent();

            if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                    || EIncomeStatus.STOP_INCOME.getValue() == targetMember.getIncomeStatus()
                    || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
                // 非正常会员、停止收益、停算收益，直接跳过
                log.warn("领导奖或平级奖收益：订单会员推荐人不满足计算奖金条件, memberCode: {}", targetMember.getMemberCode());
                continue;
            }
            // 当前会员奖衔值
            int calAwardsValue = targetMember.getAwardsValue();
            // 当前会员奖衔
            BdAwards bdAwards = awardsMap.get(calAwardsValue);

            // 领导奖级差税前收益
            BigDecimal rangeBonusIncome = null;
            // 领导奖平级税前收益
            BigDecimal sameBonusIncome = null;

            if (calAwardsValue > beforeAwardsValue) {
                // 当前会员奖衔值大于前一个奖衔值，会有领导奖级差
                rangeBonusIncome = orderAchieve.multiply(bdAwards.getRangeRatio().subtract(beforeRangeRatio));

                beforeRangeRatio = bdAwards.getRangeRatio();
                beforeAwardsValue = calAwardsValue;
            } else if (EAwards.GLOBAL_CHAIRMAN.getValue() == beforeAwardsValue
                    && EAwards.GLOBAL_CHAIRMAN.getValue() == calAwardsValue
                    && beforeSameAlgebra < 3
                    && (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                    || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()
                    || EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType())
            ) {
                // 前一个等级是皇冠大使 当前会员等级是皇冠大使，需要有3代平级（41、42、43有平级收益）
                sameBonusIncome = orderAchieve.multiply(BonusConstants.SAME_LEVEL_RATIO).multiply(bdAwards.getSameLevelRatio());
                beforeSameAlgebra += 1;
            }

            if (null != rangeBonusIncome) {
                // 处理领导奖收益
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(),
                        targetMember.getIncomeStatus(), targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? saOrderExt.getPkRate() : targetMember.getPkRate());
                int pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.RANGE_INCOME.getValue());
                CuMemberBonusRange cuMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMember, cuMemberBonus, pkBonusItems);
                cuMemberBonusRange.setCalValue(bdAwards.getRangeRatio());
                cuMemberBonusRange.setPkRange(targetMember.getPkAwards());
                cuMemberBonusRange.setPkBeforeRange(sourceMember.getPkAwards());
                cuMemberBonusRange.setPretaxIncome(rangeBonusIncome);
                rangeRetailRemark(saOrderExt, cuMemberBonusRange, sourceMember, targetMember);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusRange.getIncomeStatus()) {
                    cuMemberBonus.setRetailRangeIncome(ComputeUtil.computeAdd(cuMemberBonus.getRetailRangeIncome(), cuMemberBonusRange.getPretaxIncome()));

                    // 级差冗余计算波比
                    if (saOrderExt.getOrderType().equals(EOrderType.RETAIL_REGISTER.getValue())
                            || saOrderExt.getOrderType().equals(EOrderType.RETAIL_UPGRADE.getValue())) {
                        // 精品、甄选
                        cuMemberBonus.setRangeIncome41(ComputeUtil.computeAdd(cuMemberBonus.getRangeIncome41(), cuMemberBonusRange.getPretaxIncome()));
                    } else if (saOrderExt.getOrderType().equals(EOrderType.RETAIL_REPURCHASE.getValue())) {
                        // 商城
                        cuMemberBonus.setRangeIncome43(ComputeUtil.computeAdd(cuMemberBonus.getRangeIncome43(), cuMemberBonusRange.getPretaxIncome()));
                    } else if (saOrderExt.getOrderType().equals(EOrderType.DISCOUNT_ORDER.getValue())) {
                        // 五折
                        cuMemberBonus.setRangeIncome47(ComputeUtil.computeAdd(cuMemberBonus.getRangeIncome47(), cuMemberBonusRange.getPretaxIncome()));
                    }

                    setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusRange);
                }
                cuMemberBonusRangeList.add(cuMemberBonusRange);
            }
            if (null != sameBonusIncome) {
                // 处理平级奖收益
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(),
                        targetMember.getIncomeStatus(), targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? saOrderExt.getPkRate() : targetMember.getPkRate());
                int pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.SAME_LEVEL_INCOME.getValue());
                CuMemberBonusRange sameLevelMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMember, cuMemberBonus, pkBonusItems);
                sameLevelMemberBonusRange.setCalValue(BonusConstants.SAME_LEVEL_RATIO.multiply(bdAwards.getSameLevelRatio()));
                sameLevelMemberBonusRange.setPkRange(targetMember.getPkAwards());
                sameLevelMemberBonusRange.setPkBeforeRange(sourceMember.getPkAwards());
                sameLevelMemberBonusRange.setPretaxIncome(sameBonusIncome);
                saveLevelRetailRangeRemark(saOrderExt, sameLevelMemberBonusRange, sourceMember, targetMember);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, sameLevelMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                if (EBonusIncomeStatus.NORMAL.getValue() == sameLevelMemberBonusRange.getIncomeStatus()) {
                    cuMemberBonus.setRetailSameLevelIncome(ComputeUtil.computeAdd(cuMemberBonus.getRetailSameLevelIncome(), sameLevelMemberBonusRange.getPretaxIncome()));

                    // 平级冗余计算波比
                    if (saOrderExt.getOrderType().equals(EOrderType.RETAIL_REGISTER.getValue())
                            || saOrderExt.getOrderType().equals(EOrderType.RETAIL_UPGRADE.getValue())) {
                        // 精品、甄选
                        cuMemberBonus.setSameLevelIncome41(ComputeUtil.computeAdd(cuMemberBonus.getSameLevelIncome41(), sameLevelMemberBonusRange.getPretaxIncome()));
                    } else if (saOrderExt.getOrderType().equals(EOrderType.RETAIL_REPURCHASE.getValue())) {
                        // 商城
                        cuMemberBonus.setSameLevelIncome43(ComputeUtil.computeAdd(cuMemberBonus.getSameLevelIncome43(), sameLevelMemberBonusRange.getPretaxIncome()));
                    }

                    setRetailTotal(bdBonusDeduct, cuMemberBonus, sameLevelMemberBonusRange);
                }
                cuMemberBonusRangeList.add(sameLevelMemberBonusRange);
            }

            if (EOrderType.DISCOUNT_ORDER.getValue() != saOrderExt.getOrderType()
                    && EAwards.GLOBAL_CHAIRMAN.getValue() == beforeAwardsValue && beforeSameAlgebra >= 3) {
                // 非五折专区，有领导奖、平级奖，本次奖衔是最高，并且已经拿满3次，直接退回
                break;
            } else if (EOrderType.DISCOUNT_ORDER.getValue() == saOrderExt.getOrderType()
                    && EAwards.GLOBAL_CHAIRMAN.getValue() == beforeAwardsValue) {
                // 五折专区，只有领导奖，本次奖衔是最高，直接退回
                break;
            }
        }
    }

    /**
     * 计算赠品积分
     */
    private void calculateGiftPoint(Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, SaOrderExt saOrderExt,
                                    Map<Long, CuMemberBonus> cuMemberBonusMap, List<CuMemberBonusDetail> cuMemberBonusDetailList,
                                    BonusConfigDTO bonusConfigDTO, Integer period) {
        // 订单业绩
        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        // 一次性消费拿赠品积分
        CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 推荐会员消费拿赠品积分
        CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(saOrderExt.getPkReference());

        // 赠送积分
        BigDecimal giftPoint = BigDecimal.ZERO;
        // 推荐赠送积分
        BigDecimal targetGiftPoint = BigDecimal.ZERO;

        if (orderAchieve.compareTo(BonusConstants.GIFT_TWO_AMOUNT) >= 0) {
            // 订单业绩大于等于2万
            giftPoint = BonusConstants.GIFT_TWO_POINT;
            targetGiftPoint = BonusConstants.TARGET_GIFT_TWO_POINT;
        } else if (orderAchieve.compareTo(BonusConstants.GIFT_ONE_AMOUNT) >= 0) {
            // 订单业绩大于等于1万
            giftPoint = BonusConstants.GIFT_ONE_POINT;
            targetGiftPoint = BonusConstants.TARGET_GIFT_ONE_POINT;
        }

        if (giftPoint.compareTo(BigDecimal.ZERO) > 0 && null != sourceMember) {
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, sourceMember.getPkMember(),
                    sourceMember.getIncomeStatus(), sourceMember.getPkSettleCountry(), sourceMember.getPkRate() == null ? saOrderExt.getPkRate() : sourceMember.getPkRate());
            int pkBonusItems = getPkBonusItems(bonusConfigDTO, sourceMember.getPkSettleCountry(), EBonusItems.GIFT_POINT.getValue());
            CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrderExt, sourceMember, cuMemberBonus, pkBonusItems);
            cuMemberBonusDetail.setPretaxIncome(giftPoint);
            setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
            giftPointRemark(saOrderExt, cuMemberBonusDetail, sourceMember);
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                cuMemberBonus.setBackPoints(ComputeUtil.computeAdd(cuMemberBonus.getBackPoints(), giftPoint));
            }
            cuMemberBonusDetailList.add(cuMemberBonusDetail);
        }
        if (targetGiftPoint.compareTo(BigDecimal.ZERO) > 0 && null != targetMember && targetMember.getGradeValue() >= EGrade.HAI_FAN.getValue()) {
            // 银卡 或 金卡会员推荐才有奖励
            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMember.getPkMember(),
                    targetMember.getIncomeStatus(), targetMember.getPkSettleCountry(), targetMember.getPkRate() == null ? saOrderExt.getPkRate() : targetMember.getPkRate());
            int pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMember.getPkSettleCountry(), EBonusItems.GIFT_POINT.getValue());
            CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrderExt, targetMember, cuMemberBonus, pkBonusItems);
            cuMemberBonusDetail.setPretaxIncome(targetGiftPoint);
            setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
            giftPointRemark(saOrderExt, cuMemberBonusDetail, targetMember);
            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                cuMemberBonus.setBackPoints(ComputeUtil.computeAdd(cuMemberBonus.getBackPoints(), targetGiftPoint));
            }
            cuMemberBonusDetailList.add(cuMemberBonusDetail);
        }


    }

}
