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

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.bonus.achieve.service.ICuMemberRetailDetailService;
import com.hzs.bonus.achieve.service.ICuMemberRetailRangeService;
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.detail.service.ICuMemberAwardsService;
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.ext.SaOrderWaresExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.system.config.BdAwards;
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 ICuMemberService iCuMemberService;
    @Autowired
    private IBonusOrderService iBonusOrderService;

    /**
     * 秒结：
     * 实时计算秒结数据（业绩、奖衔、日奖）
     */
    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<>();
        // 计算自己奖衔等
        calculateGradeAwards(currentPeriod, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap, secondRangeTableName,
                cuMemberAwardsList, sourceMemberRangeExt);
        // 计算团队业绩、计算奖衔
        cuMemberAwardsList.addAll(calculateRetailRangeGradeAwards(currentPeriod, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap,
                secondRangeTableName));

        // 奖金处理
        List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();
//        if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()) {
//            // 注册，计算奖金： 直推级差收益 + 平级收益
//            for (SaOrderWaresExt saOrderItems : saOrderExt.getOrderWaresExtList()) {
//                if (EDelFlag.UN_DELETE.getValue() == saOrderItems.getDelFlag()) {
//                    // 指定盒数商品
//                    // 计算直推级差收益 + 平级收益
//                    cuMemberBonusRangeList.addAll(calculateRetailRangeBonus(memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, currentPeriod, saOrderItems, saOrderExt));
//                }
//            }
//        }

        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, EYesNo.YES.getIntValue());
            // 查询 昨天日结 + 今天秒结 血缘伞上+直推
            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, EYesNo.NO.getIntValue());
            // 查询 订单下单日结 血缘上会员结算数据
            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 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()));

        // 更新当月会员， 将昨天业绩更到到今天，更新当月会员考核结果，有消费的考核通过
        // 结算期间表
        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;

        // TODO 回退奖衔，将奖衔回退到结算前状态
        iCuMemberAwardsService.calculateCuMemberRetailRangeAwardsInit(settleDate, period, rangeTableName);
        // 初始化结算网体数据（昨天数据更新到今天数据）
        iCuMemberRetailRangeService.mergeMemberRetailRangeByYesterday(rangeTableName, yesterdayRangeTableName, isSameMonth);
        // 初始化结算明细数据（昨天数据更新到今天数据）
        iCuMemberRetailRangeService.mergeMemberRetailRangeDetailByYesterday(rangeDetailTableName, yesterdayRangeDetailTableName);

        if (orderList.size() > 0) {
            // 按照血缘，查询该会员所有伞上会员
            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);
                }
            }
            // 查询血缘会员明细数据（一阶段）
            iCuMemberRetailDetailService.listMemberRetailDetail(rangeDetailTableName, memberRangeExtMap, EBonusStage.ONE);

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

            // 会员奖衔升级记录
            List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();
            // 直推收益、见点收益
            List<CuMemberBonusPush> cuMemberBonusPushList = new ArrayList<>();
            // 阶段收益
            List<CuMemberBonusStage> cuMemberBonusStageList = new ArrayList<>();
            // 复购级差收益
            List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();
            // 会员奖金明细
            List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();

            for (SaOrderExt saOrderExt : orderList) {
                if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
                    // 精品专区、甄选专区
                    // 直推收益 -- 来源订单金额，直推拿金额的10%
                    this.calculateDirectIncome(cuMemberBonusPushList, memberRangeExtMap, saOrderExt,
                            bonusConfigDTO, period, cuMemberBonusMap);

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


                    // TODO 领导级差收益 -- 来源PV
                    // TODO 领导平差收益 -- 来源PV
                } else if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()) {
                    // 商城专区
                    // 见点收益 -- 来源订单业绩，血缘上20代，每代拿业绩的10%
                    this.calculateRepurDirectIncome(cuMemberBonusPushList, memberRangeExtMap, saOrderExt,
                            bonusConfigDTO, period, cuMemberBonusMap);
                    // TODO 阶段收益 -- 来源订单业绩


                }
            }

            // TODO 统一处理第二阶段还是 fillRetailDetail 方法进行处理

            if (cuMemberBonusPushList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusPushList(cuMemberBonusPushList);
            }
            if (cuMemberBonusStageList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusStageList(cuMemberBonusStageList);
            }
            if (cuMemberBonusRangeList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusRangeList(cuMemberBonusRangeList);
            }
            if (cuMemberBonusDetailList.size() > 0) {
                bonusRecordDetailVO.setCuMemberBonusDetailList(cuMemberBonusDetailList);
            }
            if (cuMemberAwardsList.size() > 0) {
                // 批量插入会员奖衔记录
                iCuMemberAwardsService.saveBatchCuMemberAwards(cuMemberAwardsList);
                // 更新会员表奖衔数据
                iCuMemberService.updateCuMemberRetailRangeByPeriod(period);
            }
            // 更新日结数据
            iCuMemberRetailRangeService.updateCuMemberRetailRange(rangeTableName, memberRangeExtMap);
            // 更新日结明细数据
            iCuMemberRetailRangeService.updateCuMemberRetailDetail(rangeDetailTableName, memberRangeExtMap);
        }
    }

    /**
     * 计算团队奖衔 -- 秒结、日结
     */
    public List<CuMemberAwards> calculateRetailRangeGradeAwards(Integer period, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, String rangeTableName, SaOrderExt saOrderExt,
                                                                Map<Integer, BdAwards> retailAwardsMap, String secondRangeTableName) {
        // 会员奖衔升级列表
        List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();
        // 订单会员
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 订单会员的推荐人
        CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(sourceMemberRangeExt.getPkParent());

        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        BigDecimal orderAmount = saOrderExt.getOrderAmount();
        while (null != targetMemberRangeExt) {
            // 累计业绩，不管激活不激活都处理，兼容不激活判断显示有问题
            targetMemberRangeExt.setAllTeamNewPv(targetMemberRangeExt.getAllTeamNewPv().add(orderAchieve));
            targetMemberRangeExt.setAllTeamConsumePv(targetMemberRangeExt.getAllTeamConsumePv().add(orderAchieve));
            targetMemberRangeExt.setAllTeamMonthPv(targetMemberRangeExt.getAllTeamMonthPv().add(orderAchieve));

            // 累计业绩
            targetMemberRangeExt.setTeamNewPv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamNewPv(), orderAchieve));
            targetMemberRangeExt.setTeamConsumePv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamConsumePv(), orderAchieve));
            targetMemberRangeExt.setTeamMonthPv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), orderAchieve));
            // 累计金额
            targetMemberRangeExt.setTeamNewAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamNewAmount(), orderAmount));
            targetMemberRangeExt.setTeamConsumeAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamConsumeAmount(), orderAmount));
            targetMemberRangeExt.setTeamMonthAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthAmount(), orderAmount));
            // 计算
            calculateGradeAwards(period, memberRangeExtMap, rangeTableName, saOrderExt, retailAwardsMap,
                    secondRangeTableName, cuMemberAwardsList, targetMemberRangeExt);
            targetMemberRangeExt = memberRangeExtMap.get(targetMemberRangeExt.getPkParent());
        }
        return cuMemberAwardsList;
    }

    /**
     * 计算奖衔 -- 日结、秒结
     */
    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;
        }

//        // 校验大小区会员数据
//        List<CuMemberRetailRangeExt> cuMemberRangeExtList = null;
//        // 校验累计小部门会员数据
//        List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList = null;
//        // 计算分红奖衔
//        while (true) {
//            // 当月奖衔值 + 5，获取下一个奖衔值
//            int awardsValue = targetMemberRangeExt.getShareAwardsValue() + 5;
//            if (retailAwardsMap.containsKey(awardsValue)) {
//                BdAwards bdAwards = retailAwardsMap.get(awardsValue);
//                // 先验证累计业绩
//                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), targetMemberRangeExt.getMonthConsumePv()), bdAwards.getShareTotalCheck())) {
//                    // 再验证小区，计算小区业绩（拉取直推会员数据）
//                    if (null == cuMemberRangeExtList) {
//                        if (null != secondRangeTableName) {
//                            // 会员表 关联 秒结表 和 昨日结算表，查询订单会员直推数据
//                            cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberSecondRangeExtByParent(rangeTableName, secondRangeTableName, targetMemberRangeExt.getPkMember());
//                        } else {
//                            // 昨日结算表，查询订单会员直推数据
//                            cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeExtByParent(rangeTableName, targetMemberRangeExt.getPkMember());
//                        }
//                    }
//                    // 本人月消费业绩（默认为大区）
//                    BigDecimal consumeBigPv = targetMemberRangeExt.getMonthConsumePv();
//                    for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRangeExtList) {
//                        if (memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
//                            cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberRetailRangeExt.getPkMember());
//                        }
//                        // 月累计业绩 = 本人月消费业绩 + 团队月消费业绩
//                        BigDecimal consumePv = ComputeUtil.computeAdd(cuMemberRetailRangeExt.getMonthConsumePv(), cuMemberRetailRangeExt.getAllTeamMonthPv());
//                        if (ComputeUtil.compareGreaterThan(consumePv, consumeBigPv)) {
//                            // 月累计业绩 > 大区业绩，则月累计就成为大区了
//                            consumeBigPv = consumePv;
//                        }
//                    }
//
//                    // 小区业绩 = 本人月消费业绩 + 团队月消费业绩 - 大区业绩
//                    BigDecimal smallAreaPv = ComputeUtil.computeAdd(targetMemberRangeExt.getMonthConsumePv(), ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamMonthPv(), consumeBigPv));
//                    if (ComputeUtil.compareValue(smallAreaPv, bdAwards.getShareCommunityCheck())) {
//                        // 小区业绩 >= 小区考核业绩
//                        if (bdAwards.getPlaceDeptNum() > 0) {
//                            // 验证是否有多个区满足业绩
//                            if (null == cuMemberRetailRangeExtList) {
//                                // 非秒结需要查询日结相关数据，秒结表使用上面查出的数据就可以
//                                if (null != secondRangeTableName) {
//                                    // 会员表 关联 秒结表 和 昨日结算表，查询订单会员直推数据
//                                    cuMemberRetailRangeExtList = cuMemberRangeExtList;
//                                } else {
//                                    // 昨日结算表，查询订单会员直推数据
//                                    cuMemberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeEnoughAchieve(rangeTableName, targetMemberRangeExt.getPkMember(), bdAwards.getShareCommunityCheck());
//                                }
//                            }
//
//                            int enoughNum = 0;
//                            if (ComputeUtil.compareValue(targetMemberRangeExt.getMonthConsumePv(), bdAwards.getShareCommunityCheck())) {
//                                enoughNum += 1;
//                            }
//                            for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRetailRangeExtList) {
//                                if (memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
//                                    cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberRetailRangeExt.getPkMember());
//                                }
//                                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberRetailRangeExt.getMonthConsumePv(), cuMemberRetailRangeExt.getAllTeamMonthPv()), bdAwards.getShareCommunityCheck())) {
//                                    // 本人月消费业绩 + 团队月消费业绩 >= 小区考核业绩，则满足条件小部门 +1
//                                    enoughNum += 1;
//                                }
//                            }
//                            if (bdAwards.getPlaceDeptNum() > enoughNum) {
//                                break;
//                            }
//                        }
//                        cuMemberAwardsList.add(getCuMemberRetailAwards(targetMemberRangeExt, period, saOrderExt, bdAwards, EAwardsType.SHARE_TYPE.getValue(), targetMemberRangeExt.getPkShareAwards()));
//                        targetMemberRangeExt.setShareAwardsValue(bdAwards.getAwardsValue());
//                        targetMemberRangeExt.setPkShareAwards(bdAwards.getPkId());
//                        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) {
            // 累计盒数、业绩，不管激活不激活都处理，兼容不激活判断显示有问题
            if (isSecond) {
                // 当天，秒结处理
                targetMemberRangeExt.setAllTeamNewPv(targetMemberRangeExt.getAllTeamNewPv().subtract(orderAchieve));
            } else {
                // 非当天，日结处理
                targetMemberRangeExt.setAllTeamNewPv(targetMemberRangeExt.getAllTeamNewPv().subtract(orderAchieve));
                targetMemberRangeExt.setAllTeamConsumePv(targetMemberRangeExt.getAllTeamConsumePv().subtract(orderAchieve));
                targetMemberRangeExt.setAllTeamMonthPv(targetMemberRangeExt.getAllTeamMonthPv().subtract(orderAchieve));
            }

            // 累计金额
            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;
        }

//        // 计算分红奖衔
//        while (true) {
//            // 当月奖衔值 + 5，获取下一个奖衔值
//            int awardsValue = targetMemberRangeExt.getShareAwardsValue() + 5;
//            if (retailAwardsMap.containsKey(awardsValue)) {
//                BdAwards bdAwards = retailAwardsMap.get(awardsValue);
//                // 先验证累计业绩
//                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), targetMemberRangeExt.getMonthConsumePv()), bdAwards.getShareTotalCheck())) {
//                    // 验证小区，计算小区业绩（拉取直推会员数据）
//                    List<CuMemberRetailRangeExt> cuMemberRangeExtList;
//                    if (secondRangeTableName != null) {
//                        // 会员表 关联 秒结表 和 昨日结算表，查询订单会员直推数据
//                        cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberSecondRangeExtByParent(rangeTableName, secondRangeTableName, targetMemberRangeExt.getPkMember());
//                    } else {
//                        // 昨日结算表，查询订单会员直推数据
//                        cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeExtByParent(rangeTableName, targetMemberRangeExt.getPkMember());
//                    }
//                    // 本人月消费业绩（默认为大区）
//                    BigDecimal consumeBigPv = targetMemberRangeExt.getMonthConsumePv();
//                    for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRangeExtList) {
//                        if (memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
//                            cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberRetailRangeExt.getPkMember());
//                        }
//                        // 月累计业绩 = 本人月消费业绩 + 团队月消费业绩
//                        BigDecimal consumePv = ComputeUtil.computeAdd(cuMemberRetailRangeExt.getMonthConsumePv(), cuMemberRetailRangeExt.getAllTeamMonthPv());
//                        if (ComputeUtil.compareGreaterThan(consumePv, consumeBigPv)) {
//                            // 月累计业绩 > 大区业绩，则月累计就成为大区了
//                            consumeBigPv = consumePv;
//                        }
//                    }
//
//                    // 小区业绩 = 本人月消费业绩 + 团队月消费业绩 - 大区业绩
//                    BigDecimal smallAreaPv = ComputeUtil.computeAdd(targetMemberRangeExt.getMonthConsumePv(), ComputeUtil.computeSubtract(targetMemberRangeExt.getTeamMonthPv(), consumeBigPv));
//                    if (ComputeUtil.compareValue(smallAreaPv, bdAwards.getShareCommunityCheck())) {
//                        // 小区业绩 >= 小区考核业绩
//                        if (bdAwards.getPlaceDeptNum() > 0) {
//                            // 验证是否有多个区满足业绩
//                            List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList;
//                            if (secondRangeTableName != null) {
//                                // 会员表 关联 秒结表 和 昨日结算表，查询订单会员直推数据
//                                cuMemberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberSecondRangeExtByParent(rangeTableName, secondRangeTableName, targetMemberRangeExt.getPkMember());
//                            } else {
//                                // 昨日结算表，查询订单会员直推数据
//                                cuMemberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeEnoughAchieve(rangeTableName, targetMemberRangeExt.getPkMember(), bdAwards.getShareCommunityCheck());
//                            }
//
//                            int enoughNum = 0;
//                            if (ComputeUtil.compareValue(targetMemberRangeExt.getMonthConsumePv(), bdAwards.getShareCommunityCheck())) {
//                                enoughNum += 1;
//                            }
//                            for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRetailRangeExtList) {
//                                if (memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
//                                    cuMemberRetailRangeExt = memberRangeExtMap.get(cuMemberRetailRangeExt.getPkMember());
//                                }
//                                if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberRetailRangeExt.getMonthConsumePv(), cuMemberRetailRangeExt.getAllTeamMonthPv()), bdAwards.getShareCommunityCheck())) {
//                                    // 本人月消费业绩 + 团队月消费业绩 >= 小区考核业绩，则满足条件小部门 +1
//                                    enoughNum += 1;
//                                }
//                            }
//                            if (bdAwards.getPlaceDeptNum() > enoughNum) {
//                                break;
//                            }
//                        }
//                        CuMemberAwards cuMemberRetailAwards = getCuMemberRetailAwards(targetMemberRangeExt, period, saOrderExt, bdAwards, EAwardsType.SHARE_TYPE.getValue(), targetMemberRangeExt.getPkShareAwards());
//                        cuMemberShareAwardsMap.put(cuMemberRetailAwards.getPkMember() + "_" + cuMemberRetailAwards.getNewLevel(), cuMemberRetailAwards);
//                        targetMemberRangeExt.setShareAwardsValue(bdAwards.getAwardsValue());
//                        targetMemberRangeExt.setPkShareAwards(bdAwards.getPkId());
//                        continue;
//                    }
//                }
//            }
//            break;
//        }
    }


    /**
     * 计算直推级差收益，根据直推级差收益计算平级收益
     */
    List<CuMemberBonusRange> calculateRetailRangeBonus(Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, Map<Long, CuMemberBonus> cuMemberBonusMap,
                                                       BonusConfigDTO bonusConfigDTO, Integer period,
                                                       SaOrderWaresExt saOrderItems, SaOrderExt saOrderExt) {
        // 直推级差返回数据
        List<CuMemberBonusRange> memberBonusRangeList = new ArrayList<>();

        // 订单下单人自己
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 推荐人
        long pkParent = sourceMemberRangeExt.getPkParent();

        // 商品最终价格（总价，带数量的价格）
        BigDecimal waresPrice = saOrderItems.getWaresPrice();

        // 计算直推级差
        while (true) {
            // 推荐人
            CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(pkParent);
            if (targetMemberRangeExt == null) {
                break;
            }
            // 推荐人的推荐人
            pkParent = targetMemberRangeExt.getPkParent();

            if (EAccountStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getAccountStatus()
                    || ECategory.NORMAL.getValue() != targetMemberRangeExt.getCategory()
                    || EIncomeStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getIncomeStatus()) {
                // 停算收益、非正常会员、未激活、停止收益，直接跳过
                continue;
            }
            // 直推级差税前收益
            BigDecimal rangeBonusIncome = null;
            // 平级税前收益
            BigDecimal sameBonusIncome = null;

            if (null != rangeBonusIncome) {
                // 处理直推级差收益
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMemberRangeExt.getPkMember(),
                        targetMemberRangeExt.getIncomeStatus(), targetMemberRangeExt.getPkSettleCountry(), targetMemberRangeExt.getPkRate() == null ? saOrderExt.getPkRate() : targetMemberRangeExt.getPkRate());
                int pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMemberRangeExt.getPkSettleCountry(), EBonusItems.DIRECT_INCOME.getValue());
                CuMemberBonusRange cuMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMemberRangeExt, cuMemberBonus, pkBonusItems);
                cuMemberBonusRange.setCalValue(BigDecimal.ZERO);
                cuMemberBonusRange.setCalAchieve(waresPrice);
                cuMemberBonusRange.setPretaxIncome(rangeBonusIncome);
                cuMemberBonusRange.setPkRange(targetMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkBeforeRange(sourceMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkOrderItems(saOrderItems.getPkId());
                rangeRetailRemark(saOrderExt, cuMemberBonusRange, sourceMemberRangeExt, targetMemberRangeExt);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusRange.getIncomeStatus()) {
                    cuMemberBonus.setRetailRangeIncome(ComputeUtil.computeAdd(cuMemberBonus.getRetailRangeIncome(), cuMemberBonusRange.getPretaxIncome()));
                    setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusRange);
                }
                memberBonusRangeList.add(cuMemberBonusRange);
            }
            if (null != sameBonusIncome) {
                // 处理平级收益
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, targetMemberRangeExt.getPkMember(),
                        targetMemberRangeExt.getIncomeStatus(), targetMemberRangeExt.getPkSettleCountry(), targetMemberRangeExt.getPkRate() == null ? saOrderExt.getPkRate() : targetMemberRangeExt.getPkRate());
                int pkBonusItems = getPkBonusItems(bonusConfigDTO, targetMemberRangeExt.getPkSettleCountry(), EBonusItems.SAME_LEVEL_INCOME.getValue());
                CuMemberBonusRange oriMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMemberRangeExt, cuMemberBonus, pkBonusItems);
                oriMemberBonusRange.setCalValue(RetailConstants.SAME_RATIO);
                oriMemberBonusRange.setCalAchieve(waresPrice);
                oriMemberBonusRange.setPretaxIncome(sameBonusIncome);
                oriMemberBonusRange.setPkRange(targetMemberRangeExt.getPkGrade());
                oriMemberBonusRange.setPkBeforeRange(sourceMemberRangeExt.getPkGrade());
                oriMemberBonusRange.setPkOrderItems(saOrderItems.getPkId());
                oriRetailRangeRemark(saOrderExt, oriMemberBonusRange, sourceMemberRangeExt, targetMemberRangeExt);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, oriMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                if (EBonusIncomeStatus.NORMAL.getValue() == oriMemberBonusRange.getIncomeStatus()) {
                    cuMemberBonus.setRetailSameLevelIncome(ComputeUtil.computeAdd(cuMemberBonus.getRetailSameLevelIncome(), oriMemberBonusRange.getPretaxIncome()));
                    setRetailTotal(bdBonusDeduct, cuMemberBonus, oriMemberBonusRange);
                }
                memberBonusRangeList.add(oriMemberBonusRange);
            }
        }
        return memberBonusRangeList;
    }

    private CuMemberBonusRange getCuMemberRetailBonusRange(SaOrder saOrderExt, CuMemberRetailRangeExt targetMemberRangeExt,
                                                           CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusRange cuMemberBonusRange = CuMemberBonusRange.builder()
                .pkBonus(cuMemberBonus.getPkId())
                .incomeStatus(targetMemberRangeExt.getIncomeStatus())
                .pkOrder(saOrderExt.getPkId())
                .pkBonusItems(pkBonusItems)
                .calAchieve(saOrderExt.getOrderAchieve())
                .calType(ECalType.VALUE.getValue())
                .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 void calculateDirectIncome(List<CuMemberBonusPush> cuMemberBonusPushList, Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, SaOrderExt saOrderExt,
                                       BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 订单会员
        CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(saOrderExt.getPkMember());
        if (null == sourceMember) {
            log.warn("直推收益：订单会员不存在, pkMember: {}", saOrderExt.getPkMember());
            return;
        }

        // 订单会员推荐人
        CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(sourceMember.getPkParent());
        if (null == targetMember) {
            log.warn("直推收益：订单会员推荐人不存在, pkParent: {}", sourceMember.getPkParent());
            return;
        }
        // 死点 或 停算收益 或 顾客 没有奖金
        if (ECategory.NORMAL.getValue() != targetMember.getCategory()
                || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
            log.warn("直推收益：订单会员推荐人不满足计算奖金条件, memberCode: {}, category: {}, accountStatus: {}", targetMember.getMemberCode(), targetMember.getCategory(), targetMember.getAccountStatus());
            return;
        }
        // 订单金额
        BigDecimal orderAmount = saOrderExt.getOrderAmount();
        // 奖金金额
        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, SaOrderExt saOrderExt,
                                            BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 订单会员
        CuMemberRetailRangeExt sourceMember = memberRangeExtMap.get(saOrderExt.getPkMember());
        if (null == sourceMember) {
            log.warn("订单会员不存在, pkMember: {}", saOrderExt.getPkMember());
            return;
        }
        // 推荐人
        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()
                    || EAccountStatus.STOP_INCOME.getValue() == targetMember.getAccountStatus()) {
                log.warn("见点收益：订单会员血缘上推荐人不满足计算奖金条件, memberCode: {}, category: {}, accountStatus: {}", targetMember.getMemberCode(), targetMember.getCategory(), targetMember.getAccountStatus());
                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 void calculateStageIncome(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) {
        // 订单金额除50取整，为新増点位数量
        int newPointInt = saOrderExt.getOrderAmount().divide(RetailConstants.POINT_VAL, 0, RoundingMode.DOWN).intValue();
        if (newPointInt == 0) {
            // 当前精品专区订单不足生成点位
            return;
        }

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

            // 阶段奖金处理列表
            List<BonusStageData> bonusStageDataList = new ArrayList<>();
            // 推荐人
            Long pkParent = sourceMember.getPkParent();
            while (true) {
                CuMemberRetailRangeExt targetMember = memberRangeExtMap.get(pkParent);
                if (null == targetMember) {
                    // 没有推荐人了，则直接结束
                    break;
                }
                pkParent = targetMember.getPkParent();

                // 推荐人一阶段子点位列表
                LinkedHashMap<Integer, CuMemberRetailDetail> parentDetailList = targetMember.getOneDetailMap();
                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.getPkRate() : 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());
                    stageIncomeRemark(saOrderExt, cuMemberBonusStage, sourceMember, targetMember);
                    BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusStage, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                    if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusStage.getIncomeStatus()) {
                        cuMemberBonus.setStoreIncome(ComputeUtil.computeAdd(cuMemberBonus.getStoreIncome(), cuMemberBonusStage.getPretaxIncome()));
                        setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusStage);
                    }
                    cuMemberBonusStageList.add(cuMemberBonusStage);
                }
            }

        }
    }

}
