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

import com.hzs.bonus.achieve.service.ICuMemberRetailRangeService;
import com.hzs.bonus.bonus.vo.BonusRecordDetailVO;
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.ext.CuMemberRetailRangeExt;
import com.hzs.common.domain.member.bonus.*;
import com.hzs.common.domain.member.detail.CuMemberLevel;
import com.hzs.common.domain.member.detail.CuMemberServiceLog;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.system.config.BdGrade;
import com.hzs.member.detail.ICuMemberServiceLogServiceApi;
import com.hzs.system.config.dto.BonusConfigDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

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

    @Autowired
    private ICuMemberRetailRangeService iCuMemberRetailRangeService;
    @Autowired
    private IBonusOrderService iBonusOrderService;
    @Autowired
    private ICuMemberGradeService iCuMemberGradeService;

    @DubboReference
    ICuMemberServiceLogServiceApi iCuMemberServiceLogServiceApi;

    /**
     * 日结：
     * 计算新零售奖金，首购级差、复购级差
     */
    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> retailOrderList = new ArrayList<>();
        // 新零售订单
        List<SaOrderExt> orderList = iBonusOrderService.queryRetailSaOrderByDay(settleStartDate, settleEndDate, null);
        for (SaOrderExt saOrderExt : orderList) {
            if (saOrderExt.getDelFlag() == EYesNo.YES.getIntValue()) {
                retailOrderList.add(saOrderExt);
            }
        }

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

        // 更新网体
        iCuMemberRetailRangeService.mergeMemberRetailRangeByYesterday(settleEndDate, rangeTableName, yesterdayRangeTableName, isSameMonth);

        // 当期的手动激活的记录列表
        Map<Long, Date> activateMap = this.getActivateMap(settleStartDate);

        if (retailOrderList.size() > 0) {
            // 会员购买升级记录
            Map<Long, CuMemberLevel> memberLevelMap = new HashMap<>();
            List<CuMemberLevel> memberLevelList = iCuMemberGradeService.calculateCuMemberRetailGradeInit(period, settleStartDate, settleEndDate, rangeTableName);
            memberLevelList.forEach(cuMemberLevel -> memberLevelMap.put(cuMemberLevel.getPkOrder(), cuMemberLevel));

            // 会员的自动升级记录
            Map<Long, CuMemberLevel> autoLevelMap = new HashMap<>();
            List<CuMemberLevel> autoLevelList = iCuMemberGradeService.listAutoLevel(settleStartDate, settleEndDate);
            autoLevelList.forEach(tmpLevel -> autoLevelMap.put(tmpLevel.getPkOrder(), tmpLevel));

            // 按照血缘，查询该会员所有伞上会员
            List<CuMemberRetailRangeExt> memberRetailRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeParent(rangeTableName, retailOrderList);

            // 会员结算map（key：会员ID，value：结算扩展）
            Map<Long, CuMemberRetailRangeExt> memberRangeExtMap = new HashMap<>();
            // 等级map（key:等级ID，value:等级对象）
            Map<Integer, BdGrade> gradeIdMap = new HashMap<>();
            // 等级列表
            List<BdGrade> retaiGradeList = bonusConfigDTO.getRetaiGradeList();
            for (BdGrade bdGrade : retaiGradeList) {
                gradeIdMap.put(bdGrade.getPkId(), bdGrade);
            }
            // 结算会员map处理
            for (CuMemberRetailRangeExt cuMemberRetailRangeExt : memberRetailRangeExtList) {
                if (!memberRangeExtMap.containsKey(cuMemberRetailRangeExt.getPkMember())) {
                    memberRangeExtMap.put(cuMemberRetailRangeExt.getPkMember(), cuMemberRetailRangeExt);
                }
            }

            // 级差收益
            List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();

            // 上面更新网体，按会员表是否激活进行处理
            for (SaOrderExt saOrderExt : retailOrderList) {
                CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
                if (EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType()) {
                    // 注册、升级才能算激活状态
                    sourceMemberRangeExt.setEnableStatus(EYesNo.YES.getIntValue());
                }
            }

            for (SaOrderExt saOrderExt : retailOrderList) {
                // 计算自消费奖衔
                CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());

                // 订单指定产品盒数（计算等级使用）
                int boxNum = saOrderExt.getBoxNum();

                // 个人累计消费pv
                BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
                // 复购、重消，盒数、业绩算个人累计数据（盒数、业绩）
                sourceMemberRangeExt.setNewBoxNum(sourceMemberRangeExt.getNewBoxNum() + boxNum);
                sourceMemberRangeExt.setConsumeBoxNum(sourceMemberRangeExt.getConsumeBoxNum() + boxNum);
                sourceMemberRangeExt.setMonthBoxNum(sourceMemberRangeExt.getMonthBoxNum() + boxNum);
                sourceMemberRangeExt.setNewConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getNewConsumePv(), orderAchieve));
                sourceMemberRangeExt.setConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getConsumePv(), orderAchieve));
                sourceMemberRangeExt.setMonthConsumePv(ComputeUtil.computeAdd(sourceMemberRangeExt.getMonthConsumePv(), orderAchieve));
                if (EYesNo.NO.getIntValue() == sourceMemberRangeExt.getEnableStatus()
                        && activateMap.containsKey(sourceMemberRangeExt.getPkMember())) {
                    // 存在手动激活
                    sourceMemberRangeExt.setEnableStatus(EYesNo.YES.getIntValue());
                }
                // 计算团队业绩、盒数
                calculateRetailRangeGradeAwards(memberRangeExtMap, saOrderExt, boxNum, activateMap);

                // 计算奖金 直推级差
                if ((EOrderType.RETAIL_REGISTER.getValue() == saOrderExt.getOrderType()
                        || EOrderType.RETAIL_UPGRADE.getValue() == saOrderExt.getOrderType())
                        && boxNum > 0
                ) {
                    // 注册或升级订单并且存在盒数产品，才有 直推级差
                    cuMemberBonusRangeList.addAll(calculateRetailRangeBonus(memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, period, saOrderExt, gradeIdMap));

                    // 订单存在升级记录
                    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() > sourceMemberRangeExt.getGradeValue()) {
                                sourceMemberRangeExt.setPkGrade(bdGrade.getPkId());
                                sourceMemberRangeExt.setGradeValue(bdGrade.getGradeValue());
                                sourceMemberRangeExt.setGradeName(bdGrade.getGradeName());
                            }
                        }
                    }
                    // 订单存在自动升级记录（高级店主处理）
                    if (autoLevelMap.containsKey(saOrderExt.getPkId())) {
                        CuMemberLevel cuMemberLevel = autoLevelMap.get(saOrderExt.getPkId());
                        if (gradeIdMap.containsKey(cuMemberLevel.getNewLevel())) {
                            BdGrade bdGrade = gradeIdMap.get(cuMemberLevel.getNewLevel());
                            CuMemberRetailRangeExt tmpMemberRetailRange = memberRangeExtMap.get(cuMemberLevel.getPkMember());
                            tmpMemberRetailRange.setPkGrade(bdGrade.getPkId());
                            tmpMemberRetailRange.setGradeValue(bdGrade.getGradeValue());
                            tmpMemberRetailRange.setGradeName(bdGrade.getGradeName());
                        }
                    }
                } else if (EOrderType.RETAIL_REPURCHASE.getValue() == saOrderExt.getOrderType()
                        && boxNum > 0) {
                    // 复购订单，计算复购级差
                    cuMemberBonusRangeList.addAll(calculateRetailRepurRangeBonus(memberRangeExtMap, cuMemberBonusMap, bonusConfigDTO, period, saOrderExt));
                }
            }
            if (cuMemberBonusRangeList.size() > 0) {
                if (bonusRecordDetailVO.getCuMemberBonusRangeList() == null) {
                    bonusRecordDetailVO.setCuMemberBonusRangeList(cuMemberBonusRangeList);
                } else {
                    bonusRecordDetailVO.getCuMemberBonusRangeList().addAll(cuMemberBonusRangeList);
                }
            }
            // 更新网体
            iCuMemberRetailRangeService.updateCuMemberRetailRange(rangeTableName, memberRangeExtMap);
        }
    }

    /**
     * 累计团队盒数、业绩等
     */
    public void calculateRetailRangeGradeAwards(Map<Long, CuMemberRetailRangeExt> memberRangeExtMap, SaOrderExt saOrderExt,
                                                Integer boxNum, Map<Long, Date> activateMap) {
        // 订单会员
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 订单会员的推荐人
        CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(sourceMemberRangeExt.getPkParent());

        BigDecimal orderAchieve = saOrderExt.getOrderAchieve();
        BigDecimal orderAmount = saOrderExt.getOrderAmount();
        while (null != targetMemberRangeExt) {
            // 手动激活时间
            if (EYesNo.NO.getIntValue() == targetMemberRangeExt.getEnableStatus()
                    && activateMap.containsKey(targetMemberRangeExt.getPkMember())) {
                // 存在手动激活
                targetMemberRangeExt.setEnableStatus(EYesNo.YES.getIntValue());
            }

            // 激活的账号才能累计业绩和盒数（有注册、升级订单）
            if (targetMemberRangeExt.getEnableStatus() == EYesNo.YES.getIntValue()) {
                // 累计金额
                targetMemberRangeExt.setTeamNewAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamNewAmount(), orderAmount));
                targetMemberRangeExt.setTeamConsumeAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamConsumeAmount(), orderAmount));
                targetMemberRangeExt.setTeamMonthAmount(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthAmount(), orderAmount));
                // 累计业绩
                targetMemberRangeExt.setTeamNewPv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamNewPv(), orderAchieve));
                targetMemberRangeExt.setTeamConsumePv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamConsumePv(), orderAchieve));
                targetMemberRangeExt.setTeamMonthPv(ComputeUtil.computeAdd(targetMemberRangeExt.getTeamMonthPv(), orderAchieve));
                // 累计盒数
                targetMemberRangeExt.setTeamNewBoxNum(targetMemberRangeExt.getTeamNewBoxNum() + boxNum);
                targetMemberRangeExt.setTeamBoxNum(targetMemberRangeExt.getTeamBoxNum() + boxNum);
                targetMemberRangeExt.setTeamMonthBoxNum(targetMemberRangeExt.getTeamMonthBoxNum() + boxNum);
            }
            targetMemberRangeExt = memberRangeExtMap.get(targetMemberRangeExt.getPkParent());
        }
    }

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

        // 订单下单人自己
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 推荐人
        long pkParent = sourceMemberRangeExt.getPkParent();
        // 订单等级值
        Integer orderGradeValue = gradeIdMap.get(saOrderExt.getPkGrade()).getGradeValue();

        // 前一个会员等级
        int beforeGradeValue = 0;
        // 前面累计奖金
        BigDecimal totalBonus = BigDecimal.ZERO;
        // 平级合伙人数量
        int v3Count = 1;
        // 计算直推级差
        while (true) {
            // 上一次处理的是公司等级，则结束退出
            if (beforeGradeValue == EGrade.COMPANY.getValue()) {
                break;
            }
            // 推荐人
            CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(pkParent);
            if (null == targetMemberRangeExt) {
                break;
            }
            // 推荐人的推荐人
            pkParent = targetMemberRangeExt.getPkParent();

            if (EAccountStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getAccountStatus()
                    || ECategory.NORMAL.getValue() != targetMemberRangeExt.getCategory()
                    || targetMemberRangeExt.getEnableStatus() == EYesNo.NO.getIntValue()
                    || targetMemberRangeExt.getGradeValue() == EGrade.START_UP.getValue()
                    || EIncomeStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getIncomeStatus()) {
                // 停算收益、非正常会员、未激活、等级为顾客、停止收益，直接跳过
                continue;
            }
            // 当前会员等级值
            int targetGradeValue = targetMemberRangeExt.getGradeValue();

            // 直推级差收益
            BigDecimal rangeBonusIncome = BigDecimal.ZERO;

            if (EGrade.HAI_FAN.getValue() == orderGradeValue) {
                // 订单等级是会员、VIP
                if (targetGradeValue > beforeGradeValue) {
                    // 当前会员等级大于上一个会员等级
                    if (EGrade.HAI_FAN.getValue() == targetGradeValue) {
                        // V1 推拿 60
                        rangeBonusIncome = RetailConstants.V1_V1;
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V1_V1;
                    } else if (EGrade.YOU_KE.getValue() == targetGradeValue) {
                        // V2 推拿 80，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V2_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V2_V1;
                    } else if (EGrade.MAKER.getValue() == targetGradeValue) {
                        // V3 推拿 100，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V1;
                    } else if (EGrade.VIP.getValue() == targetGradeValue) {
                        // V4 推拿 200，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V4_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V4_V1;
                    } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                        // V5 推拿 208，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V5_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V5_V1;
                    } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                        // V6 推拿 220 ，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V6_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V6_V1;
                    } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                        // V7 推拿 240，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V7_V1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V7_V1;
                    }
                    // 前一级会员等级
                    beforeGradeValue = targetGradeValue;
                }
            } else if (EGrade.YOU_KE.getValue() == orderGradeValue) {
                // 订单等级是VIP
                if (targetGradeValue > beforeGradeValue) {
                    // 当前会员等级大于上一个会员等级
                    if (EGrade.HAI_FAN.getValue() == targetGradeValue) {
                        // V1 推拿 300
                        rangeBonusIncome = RetailConstants.V1_V2;
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V1_V2;
                    } else if (EGrade.YOU_KE.getValue() == targetGradeValue) {
                        // V2 推拿 400，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V2_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V2_V2;
                    } else if (EGrade.MAKER.getValue() == targetGradeValue) {
                        // V3 推拿 500，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V2;
                    } else if (EGrade.VIP.getValue() == targetGradeValue) {
                        // V4 推拿 1000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V4_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V4_V2;
                    } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                        // V5 推拿 1040，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V5_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V5_V2;
                    } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                        // V6 推拿 1100，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V6_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V6_V2;
                    } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                        // V7 推拿 1200，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V7_V2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V7_V2;
                    }
                    // 前一级会员等级
                    beforeGradeValue = targetGradeValue;
                }
            } else if (EGrade.MAKER.getValue() == orderGradeValue) {
                // 订单是合伙人
                if (targetGradeValue > beforeGradeValue) {
                    // 当前等级大于之前等级
                    if (EGrade.HAI_FAN.getValue() == targetGradeValue) {
                        // V1 推拿 600
                        rangeBonusIncome = RetailConstants.V1_V3;
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V1_V3;
                    } else if (EGrade.YOU_KE.getValue() == targetGradeValue) {
                        // V2 推拿 800，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V2_V3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V2_V3;
                    } else if (EGrade.MAKER.getValue() == targetGradeValue) {
                        // V3 推拿 1000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V3_1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V3_1;
                    } else if (EGrade.VIP.getValue() == targetGradeValue) {
                        // V4 推拿 2000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V4_V3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V4_V3;
                    } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                        // V5 推拿 2080，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V5_V3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V5_V3;
                    } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                        // V6 推拿 2200，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V6_V3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V6_V3;
                    } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                        // V7 推拿 2400，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V7_V3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V7_V3;
                    }
                    // 前一级会员等级
                    beforeGradeValue = targetGradeValue;
                } else if (EGrade.MAKER.getValue() == beforeGradeValue
                        && EGrade.MAKER.getValue() == targetGradeValue) {
                    // 之前和现在都是合伙人，处理平级
                    if (v3Count == 1) {
                        // V3第一平级 推拿 1200，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V3_2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V3_2;
                        v3Count++;
                    } else if (v3Count == 2) {
                        // V3第二平级 推拿 1300，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V3_3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V3_3;
                        v3Count++;
                    }
                }
            } else if (EGrade.VIP.getValue() == orderGradeValue) {
                // 订单是博羚店主
                if (targetGradeValue > beforeGradeValue) {
                    // 当前等级大于之前等级
                    if (EGrade.HAI_FAN.getValue() == targetGradeValue) {
                        // V1 推拿 1200
                        rangeBonusIncome = RetailConstants.V1_V4;
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V1_V4;
                    } else if (EGrade.YOU_KE.getValue() == targetGradeValue) {
                        // V2 推拿 1600，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V2_V4.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V2_V4;
                    } else if (EGrade.MAKER.getValue() == targetGradeValue) {
                        // V3 推拿 2000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V4_1.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V4_1;
                    } else if (EGrade.VIP.getValue() == targetGradeValue) {
                        // V4 推拿 4000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V4_V4.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V4_V4;
                    } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                        // V5 推拿 4160，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V5_V4.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V5_V4;
                    } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                        // V6 推拿 4400，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V6_V4.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V6_V4;
                    } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                        // V7 推拿 4800，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V7_V4.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V7_V4;
                    }
                    // 前一级会员等级
                    beforeGradeValue = targetGradeValue;
                } else if (EGrade.MAKER.getValue() == beforeGradeValue
                        && EGrade.MAKER.getValue() == targetGradeValue) {
                    // 之前和现在都是合伙人，处理平级
                    if (v3Count == 1) {
                        // V3第一平级 推拿 2400，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V4_2.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V4_2;
                        v3Count++;
                    } else if (v3Count == 2) {
                        // V3第二平级 推拿 2600，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V3_V4_3.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V3_V4_3;
                        v3Count++;
                    }
                }
            } else if (EGrade.BRANCH_COMPANY.getValue() == orderGradeValue) {
                // 订单是分公司
                if (targetGradeValue >= EGrade.VIP.getValue() && targetGradeValue > beforeGradeValue) {
                    // 博羚店主以上才有级差 并且 当前等级大于之前等级
                    if (EGrade.VIP.getValue() == targetGradeValue) {
                        // 博羚店主拿 50000
                        rangeBonusIncome = RetailConstants.V4_V6.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V4_V6;
                    } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                        // 高级店主拿 52000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V5_V6.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V5_V6;
                    } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                        // 分公司拿 55000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V6_V6.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V6_V6;
                    } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                        // 总公司拿 60000，或者减去之前累计
                        rangeBonusIncome = RetailConstants.V7_V6.subtract(totalBonus);
                        // 前面累计的奖金
                        totalBonus = RetailConstants.V7_V6;
                    }
                    // 前一级会员等级
                    beforeGradeValue = targetGradeValue;
                }
            }

            if (rangeBonusIncome.compareTo(BigDecimal.ZERO) > 0) {
                // 处理直推级差收益
                // 会员奖金
                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.RETAIL_RANGE_INCOME.getValue());
                // 会员级差
                CuMemberBonusRange cuMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMemberRangeExt, cuMemberBonus, pkBonusItems);
                cuMemberBonusRange.setCalValue(BigDecimal.ZERO);
                cuMemberBonusRange.setCalAchieve(saOrderExt.getOrderAmount());
                cuMemberBonusRange.setPretaxIncome(rangeBonusIncome);
                cuMemberBonusRange.setPkRange(targetMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkBeforeRange(sourceMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkOrder(saOrderExt.getPkId());
                cuMemberBonusRange.setPkOrderItems(0L);
                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);
            }
        }
        return memberBonusRangeList;
    }

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

        // 订单下单人自己
        CuMemberRetailRangeExt sourceMemberRangeExt = memberRangeExtMap.get(saOrderExt.getPkMember());
        // 推荐人
        long pkParent = sourceMemberRangeExt.getPkParent();
        // 商品盒数
        BigDecimal boxNum = new BigDecimal(saOrderExt.getBoxNum());

        // 前一个会员等级
        int beforeGradeValue = 0;
        // 前面累计奖金
        BigDecimal totalBonus = BigDecimal.ZERO;
        // 平级合伙人数量
        int v3Count = 1;
        // 计算直推级差
        while (true) {
            // 上一次处理的是公司等级，则结束退出
            if (beforeGradeValue == EGrade.COMPANY.getValue()) {
                break;
            }
            // 推荐人
            CuMemberRetailRangeExt targetMemberRangeExt = memberRangeExtMap.get(pkParent);
            if (null == targetMemberRangeExt) {
                break;
            }
            // 推荐人的推荐人
            pkParent = targetMemberRangeExt.getPkParent();

            if (EAccountStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getAccountStatus()
                    || ECategory.NORMAL.getValue() != targetMemberRangeExt.getCategory()
                    || targetMemberRangeExt.getEnableStatus() == EYesNo.NO.getIntValue()
                    || targetMemberRangeExt.getGradeValue() == EGrade.START_UP.getValue()
                    || EIncomeStatus.STOP_INCOME.getValue() == targetMemberRangeExt.getIncomeStatus()) {
                // 停算收益、非正常会员、未激活、等级为顾客、停止收益，直接跳过
                continue;
            }
            // 当前会员等级值
            int targetGradeValue = targetMemberRangeExt.getGradeValue();

            // 复购级差收益
            BigDecimal rangeBonusIncome = BigDecimal.ZERO;

            if (targetGradeValue > beforeGradeValue) {
                // 当前等级大于之前等级
                if (EGrade.HAI_FAN.getValue() == targetGradeValue) {
                    // V1 拿 6
                    rangeBonusIncome = RetailConstants.REPURCHASE_V1.multiply(boxNum);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V1).multiply(boxNum);
                } else if (EGrade.YOU_KE.getValue() == targetGradeValue) {
                    // V2 拿 8，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V2.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V2.multiply(boxNum).subtract(totalBonus));
                } else if (EGrade.MAKER.getValue() == targetGradeValue) {
                    // V3 拿 10，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V3_1.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V3_1.multiply(boxNum).subtract(totalBonus));
                } else if (EGrade.VIP.getValue() == targetGradeValue) {
                    // V4 拿 20，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V4.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V4.multiply(boxNum).subtract(totalBonus));
                } else if (EGrade.S_VIP.getValue() == targetGradeValue) {
                    // V5 拿 20.8，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V5.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V5.multiply(boxNum).subtract(totalBonus));
                } else if (EGrade.BRANCH_COMPANY.getValue() == targetGradeValue) {
                    // V6 拿 22，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V6.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V6.multiply(boxNum).subtract(totalBonus));
                } else if (EGrade.COMPANY.getValue() == targetGradeValue) {
                    // V7 拿 24，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V7.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V7.multiply(boxNum).subtract(totalBonus));
                }
                // 前一级会员等级
                beforeGradeValue = targetGradeValue;
            } else if (EGrade.MAKER.getValue() == beforeGradeValue
                    && EGrade.MAKER.getValue() == targetGradeValue) {
                // 之前和现在都是合伙人，处理平级
                if (v3Count == 1) {
                    // V3第一平级 推拿 12，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V3_2.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V3_2.multiply(boxNum).subtract(totalBonus));
                    v3Count++;
                } else if (v3Count == 2) {
                    // V3第二平级 推拿 13，或者减去之前累计
                    rangeBonusIncome = RetailConstants.REPURCHASE_V3_3.multiply(boxNum).subtract(totalBonus);
                    // 前面累计的奖金
                    totalBonus = totalBonus.add(RetailConstants.REPURCHASE_V3_3.multiply(boxNum).subtract(totalBonus));
                    v3Count++;
                }
            }

            if (rangeBonusIncome.compareTo(BigDecimal.ZERO) > 0) {
                // 处理复购级差收益
                // 会员奖金
                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.RETAIL_REPURCHASE_INCOME.getValue());
                // 会员级差
                CuMemberBonusRange cuMemberBonusRange = getCuMemberRetailBonusRange(saOrderExt, targetMemberRangeExt, cuMemberBonus, pkBonusItems);
                cuMemberBonusRange.setCalValue(BigDecimal.ZERO);
                cuMemberBonusRange.setCalAchieve(saOrderExt.getOrderAmount());
                cuMemberBonusRange.setPretaxIncome(rangeBonusIncome);
                cuMemberBonusRange.setPkRange(targetMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkBeforeRange(sourceMemberRangeExt.getPkGrade());
                cuMemberBonusRange.setPkOrder(saOrderExt.getPkId());
                cuMemberBonusRange.setPkOrderItems(0L);
                rangeRepurRetailRemark(saOrderExt, cuMemberBonusRange, sourceMemberRangeExt, targetMemberRangeExt);
                BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusRange.getIncomeStatus()) {
                    cuMemberBonus.setRepurRangeIncome(ComputeUtil.computeAdd(cuMemberBonus.getRepurRangeIncome(), cuMemberBonusRange.getPretaxIncome()));
                    setRetailTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusRange);
                }
                memberBonusRangeList.add(cuMemberBonusRange);
            }
        }
        return memberBonusRangeList;
    }

    private CuMemberBonusRange getCuMemberRetailBonusRange(SaOrder saOrderExt, CuMemberRetailRangeExt targetMemberRangeExt,
                                                           CuMemberBonus cuMemberBonus, Integer pkBonusItems) {
        CuMemberBonusRange cuMemberBonusRange = CuMemberBonusRange.builder()
                .incomeStatus(targetMemberRangeExt.getIncomeStatus())
                .pkOrder(saOrderExt.getPkId())
                .pkBonusItems(pkBonusItems)
                .pkBonus(cuMemberBonus.getPkId())
                // 正常还是烧伤
                .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;
    }

    /**
     * 获取手动激活map
     *
     * @param settleStartDate
     * @return
     */
    private Map<Long, Date> getActivateMap(Date settleStartDate) {
        // 当期的手动激活的记录列表
        List<CuMemberServiceLog> activateList = iCuMemberServiceLogServiceApi.listActivateLog(settleStartDate).getData();
        return activateList.stream()
                .collect(Collectors.groupingBy(
                        CuMemberServiceLog::getPkMember,
                        Collectors.collectingAndThen(
                                Collectors.minBy(Comparator.comparing(CuMemberServiceLog::getCreationTime)),
                                optional -> optional.get().getCreationTime()
                        )
                ));
    }
}
