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

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.bonus.BdBonusDeduct;
import com.hzs.common.domain.bonus.risk.CuMemberRiskControl;
import com.hzs.common.domain.member.base.CuAwardsControl;
import com.hzs.common.domain.member.bonus.CuMemberBonus;
import com.hzs.common.domain.member.bonus.CuMemberBonusPoint;
import com.hzs.common.domain.member.bonus.CuMemberBonusRange;
import com.hzs.common.domain.member.ext.CuMemberSettleDetailExt;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.system.config.BdAwards;
import com.hzs.sale.order.dto.SaOrderRangeDto;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.config.dto.BonusConfigDTO;
import com.hzs.system.config.dto.RangeDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

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

    @DubboReference
    ISystemConfigServiceApi systemConfigServiceApi;

    /**
     * @param period           期间
     * @param bonusConfigDTO   参数
     * @param resaleOrderList  复购订单
     * @param cuMemberBonusMap 所有计算出来的奖金汇总
     * @Description: 计算复购极差
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/10 14:17
     */
    List<CuMemberBonusRange> calculateRepurchaseRangeBonus(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleTableName, String settleTableNameDetail, String settleDate, Map<String, RangeDTO> rangeDtoMap, Map<String, BdAwards> awardsMap,
                                                           BonusConfigDTO bonusConfigDTO, List<SaOrderExt> resaleOrderList,
                                                           Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, Map<Long, CuAwardsControl> cuAwardsControlMap, Map<Long, CuMemberRiskControl> riskControlMap) {
        List<CuMemberBonusRange> cuMemberBonusRangeList = new ArrayList<>();
        // 根据订单找到订单的血缘上，找到推荐人, 海外的复购极差计算
        Set<Long> expandMemberSet = resaleOrderList.stream().distinct().map(SaOrderExt::getPkMember).collect(Collectors.toSet());
        List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryCuMemberSettleParent(settleTableName, settleTableNameDetail, expandMemberSet);
        getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
        // 国内复购极差计算 业绩*比例
        if (resaleOrderList.size() > 0) {
            for (SaOrderExt saOrderExt : resaleOrderList) {
                // 获取血缘伞上的推荐人 一定要发完，从推荐人开始发
                CuMemberSettleExt sourceMemberTree = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
                while (true) {
                    if (sourceMemberTree == null) {
                        break;
                    }
                    CuMemberSettleExt parentMemberTree = cuMemberSettleExtMap.get(sourceMemberTree.getPkParent());
                    parentMemberTree = getRangeCuMemberTree(settleDate, cuMemberSettleExtMap, rangeDtoMap, awardsMap, bonusConfigDTO, sourceMemberTree, parentMemberTree, cuAwardsControlMap);
                    if (parentMemberTree == null) {
                        break;
                    }
                    RangeDTO parentRangeDto = getRangeDto(rangeDtoMap, awardsMap, parentMemberTree, cuAwardsControlMap);
                    RangeDTO sourceRangeDto = getRangeDto(rangeDtoMap, awardsMap, sourceMemberTree, cuAwardsControlMap);
                    BigDecimal achieveRatio = ComputeUtil.computeSubtract(parentRangeDto.getAchieveRatio(), sourceRangeDto.getAchieveRatio());
                    // 发放奖金
                    CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, parentMemberTree);
                    CuMemberBonusRange cuMemberBonusRange = getCuMemberBonusRange(bonusConfigDTO, saOrderExt, parentMemberTree, cuMemberBonus);
                    cuMemberBonusRange.setCalAchieve(convertLocalCurrency(saOrderExt, bonusConfigDTO));
                    if (ComputeUtil.compareValue(BigDecimal.ZERO, achieveRatio)) {
                        sourceMemberTree = cuMemberSettleExtMap.get(parentMemberTree.getPkMember());
                        continue;
                    }
                    cuMemberBonusRange.setCalValue(achieveRatio);
                    cuMemberBonusRange.setPkRange(parentRangeDto.getPkRange());
                    cuMemberBonusRange.setPkBeforeRange(sourceRangeDto.getPkRange());
                    cuMemberBonusRange.setPkOrderItems(0L);
                    BigDecimal maxGrantIncome = ComputeUtil.computeBonusMultiply(convertLocalCurrency(saOrderExt, bonusConfigDTO), achieveRatio);
                    if (ComputeUtil.compareValue(BigDecimal.ZERO, maxGrantIncome)) {
                        break;
                    }
                    // K值设置
                    if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
                        maxGrantIncome = ComputeUtil.computeBonusMultiply(maxGrantIncome, riskControlMap.get(cuMemberBonus.getPkMember()).getRangeIncome());
                        cuMemberBonusRange.setIncomeStatus(EBonusIncomeStatus.RISK_CONTROL.getValue());
                    }
                    BigDecimal maxRangeIncome = maxGrantIncome;
                    // 最大奖金金额, 剩下的作为烧伤
                    maxGrantIncome = calculatePointIncomeByPoint(maxGrantIncome, parentMemberTree, cuMemberBonusRange);
                    rangeRemark(saOrderExt, cuMemberBonusRange, sourceMemberTree, parentMemberTree, parentRangeDto, sourceRangeDto);
                    if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
                        cuMemberBonusRange.setRemark(cuMemberBonusRange.getRemark() + ",K值比例:" + riskControlMap.get(cuMemberBonus.getPkMember()).getRangeIncome());
                    }
                    packageRepurchaseRange(bonusConfigDTO, cuMemberBonusRangeList, saOrderExt, cuMemberBonus, cuMemberBonusRange, maxGrantIncome);
                    // 计算同级奖
                    Long pkParent = parentMemberTree.getPkParent();
                    while (true) {
                        if (pkParent == null) {
                            break;
                        }
                        CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(pkParent);
                        if (targetMemberSettleExt == null || targetMemberSettleExt.getPkAwards() > parentMemberTree.getPkAwards()) {
                            break;
                        }
                        if (validatePkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_SAME_LEVEL_INCOME.getValue())) {
                            pkParent = targetMemberSettleExt.getPkParent();
                            continue;
                        }
                        if (targetMemberSettleExt.getPkAwards().equals(parentMemberTree.getPkAwards()) && !validateExistBonus(targetMemberSettleExt, settleDate)) {
                            // 获得同级奖
                            CuMemberBonus targetMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
                            CuMemberBonusRange targetMemberBonusRange = getCuMemberBonusRange(bonusConfigDTO, saOrderExt, targetMemberSettleExt, targetMemberBonus);
                            targetMemberBonusRange.setCalAchieve(convertLocalCurrency(saOrderExt, bonusConfigDTO));
                            targetMemberBonusRange.setPkBonusItems(getPkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_SAME_LEVEL_INCOME.getValue()));
                            targetMemberBonusRange.setCalValue(cuMemberBonusRange.getPretaxIncome());
                            // 最大奖金金额, 剩下的作为烧伤
                            BigDecimal rangeIncome = calculatePointIncomeByPoint(ComputeUtil.computeMultiply(maxRangeIncome, BigDecimal.valueOf(0.5)), parentMemberTree, targetMemberBonusRange);
                            // K值设置
                            if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
                                rangeIncome = ComputeUtil.computeBonusMultiply(rangeIncome, riskControlMap.get(cuMemberBonus.getPkMember()).getRepurchaseIncome());
                                targetMemberBonusRange.setIncomeStatus(EBonusIncomeStatus.RISK_CONTROL.getValue());
                            }
                            targetMemberBonusRange.setPkRange(parentRangeDto.getPkRange());
                            targetMemberBonusRange.setPkBeforeRange(sourceRangeDto.getPkRange());
                            targetMemberBonusRange.setPkOrderItems(0L);
                            sameLevelRemark(saOrderExt, targetMemberBonusRange, sourceMemberTree, targetMemberSettleExt, sourceRangeDto, parentRangeDto);
                            if (riskControlMap.containsKey(cuMemberBonus.getPkMember())) {
                                targetMemberBonusRange.setRemark(targetMemberBonusRange.getRemark() + ",K值比例:" + riskControlMap.get(cuMemberBonus.getPkMember()).getRepurchaseIncome());
                            }
                            packageSameLevel(bonusConfigDTO, cuMemberBonusRangeList, saOrderExt, targetMemberBonus, targetMemberBonusRange, rangeIncome);
                            break;
                        } else {
                            pkParent = targetMemberSettleExt.getPkParent();
                        }
                    }
                    // 发放到最高级后跳出
                    if (ERangeType.AWARDS.getValue() == parentRangeDto.getRangeType() && EAwards.GLOBAL_CHAIRMAN.getValue() == parentRangeDto.getRangeValue()) {
                        break;
                    }
                    sourceMemberTree = cuMemberSettleExtMap.get(parentMemberTree.getPkMember());
                }
            }
        }
        return cuMemberBonusRangeList;
    }


    /**
     * 根据极差获取会员
     */
    private CuMemberSettleExt getRangeCuMemberTree(String settleDate, Map<Long, CuMemberSettleExt> cuMemberTreeMap, Map<String, RangeDTO> rangeDtoMap, Map<String, BdAwards> awardsMap,
                                                   BonusConfigDTO bonusConfigDTO, CuMemberSettleExt sourceMemberTree, CuMemberSettleExt parentMemberTree,
                                                   Map<Long, CuAwardsControl> cuAwardsControlMap) {
        RangeDTO parentRangeDto = getRangeDto(rangeDtoMap, awardsMap, parentMemberTree, cuAwardsControlMap);
        RangeDTO sourceRangeDto = getRangeDto(rangeDtoMap, awardsMap, sourceMemberTree, cuAwardsControlMap);
        if (parentRangeDto == null || sourceRangeDto == null || parentMemberTree == null) {
            return null;
        }
        // 需要复购考核，复购考核未通过的没有奖金
        if (ECategory.NORMAL.getValue() != parentMemberTree.getCategory() || EAccountStatus.STOP_INCOME.getValue() == parentMemberTree.getAccountStatus() ||
                validateExistBonus(parentMemberTree, settleDate) ||
                validatePkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_RANGE_INCOME.getValue()) ||
                parentRangeDto.getRangeValue() < sourceRangeDto.getRangeValue()) {
            parentMemberTree = cuMemberTreeMap.get(parentMemberTree.getPkParent());
            if (parentMemberTree == null) {
                return null;
            }
            parentMemberTree = getRangeCuMemberTree(settleDate, cuMemberTreeMap, rangeDtoMap, awardsMap, bonusConfigDTO, sourceMemberTree, parentMemberTree, cuAwardsControlMap);
        }
        return parentMemberTree;
    }

//    private Map<Long, List<SaOrderRangeDto>> getRangeDtoMap(List<SaOrderRangeDto> orderRangeVOList) {
//        Map<Long, List<SaOrderRangeDto>> orderRangeDtoMap = new HashMap<>();
//        for (SaOrderRangeDto saOrderRangeDto : orderRangeVOList) {
//            if(orderRangeDtoMap.containsKey(saOrderRangeDto.getPkOrderItems())){
//                orderRangeDtoMap.get(saOrderRangeDto.getPkOrderItems()).add(saOrderRangeDto);
//            }else{
//                List<SaOrderRangeDto> saOrderRangeDtoList = new ArrayList<>();
//                saOrderRangeDtoList.add(saOrderRangeDto);
//                orderRangeDtoMap.put(saOrderRangeDto.getPkOrderItems(), saOrderRangeDtoList);
//            }
//        }
//        return orderRangeDtoMap;
//    }

//    private void executeOrderRange(Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, String settleDate, Map<String, RangeDTO> rangeDtoMap, Map<String, BdAwards> awardsMap, BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, Map<Long, CuAwardsControl> cuAwardsControlMap, List<CuMemberBonusRange> cuMemberBonusRangeList, Map<String, RangeDTO> rangePkDtoMap, SaOrderExt saOrderExt, List<SaOrderRangeDto> orderRangeVOList) {
//        CuMemberSettleExt sourceCuMemberTree = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
//        CuMemberSettleExt parentMemberTree = cuMemberSettleExtMap.get(sourceCuMemberTree.getPkParent());
//        BigDecimal orderAchieve = orderRangeVOList.get(0).getOrderAchieve();
//        int pkRange = orderRangeVOList.get(0).getPkRange();
//        for (SaOrderRangeDto saOrderRangeDto : orderRangeVOList) {
//            parentMemberTree = getCuMemberTree(cuMemberSettleExtMap, settleDate, rangeDtoMap, rangePkDtoMap, awardsMap, bonusConfigDTO,
//                    parentMemberTree, saOrderRangeDto, cuAwardsControlMap);
//            if (parentMemberTree == null) {
//                break;
//            }
//            RangeDTO rangeDto = getRangeDto(rangeDtoMap, awardsMap, parentMemberTree, cuAwardsControlMap);
//            if (saOrderRangeDto.getRangeValue() != null && rangeDto.getRangeValue() != null &&
//                    rangeDto.getRangeValue().equals(saOrderRangeDto.getRangeValue())) {
//                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, parentMemberTree);
//                CuMemberBonusRange cuMemberBonusRange = getCuMemberBonusRange(bonusConfigDTO, saOrderExt, parentMemberTree, cuMemberBonus);
//                BigDecimal maxGrantIncome = ComputeUtil.computeMultiply(ComputeUtil.computeSubtract(orderAchieve, saOrderRangeDto.getRangeAchieve()), saOrderRangeDto.getQuantity());
//                BigDecimal maxRangeIncome = maxGrantIncome;
//                if (ComputeUtil.compareValue(BigDecimal.ZERO, maxGrantIncome)) {
//                    break;
//                }
//                cuMemberBonusRange.setCalValue(BigDecimal.ZERO);
//                cuMemberBonusRange.setPkRange(rangeDto.getPkRange());
//                cuMemberBonusRange.setPkBeforeRange(pkRange);
//                cuMemberBonusRange.setPkOrderItems(saOrderRangeDto.getPkOrderItems());
//                // 最大奖金金额, 剩下的作为烧伤
//                maxGrantIncome = calculatePointIncomeByPoint(maxGrantIncome, parentMemberTree, cuMemberBonusRange);
//                rangeRemark(saOrderExt, cuMemberBonusRange, sourceCuMemberTree, parentMemberTree, rangePkDtoMap);
//                packageRepurchaseRange(bonusConfigDTO, cuMemberBonusRangeList, saOrderExt, cuMemberBonus, cuMemberBonusRange, maxGrantIncome);
//                if (ComputeUtil.compareEqual(orderAchieve, saOrderRangeDto.getRangeAchieve())) {
//                    break;
//                }
//                // 计算同级奖
//                Long pkParent = parentMemberTree.getPkParent();
//                while (true){
//                    if(pkParent == null){
//                        break;
//                    }
//                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(pkParent);
//                    if(targetMemberSettleExt == null || targetMemberSettleExt.getGradeValue() > parentMemberTree.getGradeValue()){
//                        break;
//                    }
//                    if (validatePkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_SAME_LEVEL_INCOME.getValue())) {
//                        pkParent = targetMemberSettleExt.getPkParent();
//                        continue;
//                    }
//                    if(targetMemberSettleExt.getPkGrade().equals(parentMemberTree.getPkGrade()) && !validateExistBonus(targetMemberSettleExt, settleDate)){
//                        // 获得同级奖
//                        CuMemberBonus targetMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
//                        CuMemberBonusRange targetMemberBonusRange = getCuMemberBonusRange(bonusConfigDTO, saOrderExt, targetMemberSettleExt, targetMemberBonus);
//                        targetMemberBonusRange.setPkBonusItems(getPkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_SAME_LEVEL_INCOME.getValue()));
//                        targetMemberBonusRange.setCalValue(cuMemberBonusRange.getPretaxIncome());
//                        // 最大奖金金额, 剩下的作为烧伤
//                        BigDecimal rangeIncome = ComputeUtil.computeMultiply(maxRangeIncome, BigDecimal.valueOf(0.5));
//                        rangeIncome = calculatePointIncomeByPoint(rangeIncome, parentMemberTree, targetMemberBonusRange);
//                        targetMemberBonusRange.setPkRange(rangeDto.getPkRange());
//                        targetMemberBonusRange.setPkBeforeRange(pkRange);
//                        targetMemberBonusRange.setPkOrderItems(saOrderRangeDto.getPkOrderItems());
//                        sameLevelRemark(saOrderExt, targetMemberBonusRange, sourceCuMemberTree, targetMemberSettleExt, rangePkDtoMap);
//                        packageRepurchaseRange(bonusConfigDTO, cuMemberBonusRangeList, saOrderExt, targetMemberBonus, targetMemberBonusRange, rangeIncome);
//                        break;
//                    }else {
//                        pkParent = targetMemberSettleExt.getPkParent();
//                    }
//                }
//                orderAchieve = saOrderRangeDto.getRangeAchieve();
//                pkRange = saOrderRangeDto.getPkRange();
//            }
//        }
//    }

    private void packageRepurchaseRange(BonusConfigDTO bonusConfigDTO, List<CuMemberBonusRange> cuMemberBonusRangeList, SaOrderExt saOrderExt, CuMemberBonus cuMemberBonus, CuMemberBonusRange cuMemberBonusRange, BigDecimal fireBonusIncome) {
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusRange.getIncomeStatus() ||
                EBonusIncomeStatus.RISK_CONTROL.getValue() == cuMemberBonusRange.getIncomeStatus()) {
            cuMemberBonus.setFireShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getFireShareIncome(), fireBonusIncome));
            cuMemberBonus.setRepurRangeIncome(ComputeUtil.computeAdd(cuMemberBonus.getRepurRangeIncome(), cuMemberBonusRange.getPretaxIncome()));
            setPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusRange);
        }
        cuMemberBonusRangeList.add(cuMemberBonusRange);
    }

    private void packageSameLevel(BonusConfigDTO bonusConfigDTO, List<CuMemberBonusRange> cuMemberBonusRangeList, SaOrderExt saOrderExt, CuMemberBonus cuMemberBonus, CuMemberBonusRange cuMemberBonusRange, BigDecimal fireBonusIncome) {
        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusRange, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusRange.getIncomeStatus() ||
                EBonusIncomeStatus.RISK_CONTROL.getValue() == cuMemberBonusRange.getIncomeStatus()) {
            cuMemberBonus.setFireShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getFireShareIncome(), fireBonusIncome));
            cuMemberBonus.setSameLevelIncome(ComputeUtil.computeAdd(cuMemberBonus.getSameLevelIncome(), cuMemberBonusRange.getPretaxIncome()));
            setPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusRange);
        }
        cuMemberBonusRangeList.add(cuMemberBonusRange);
    }

    /**
     * 根据极差获取会员
     */
    private CuMemberSettleExt getCuMemberTree(Map<Long, CuMemberSettleExt> cuMemberTreeMap, String settleDate, Map<String, RangeDTO> rangeDtoMap, Map<String, RangeDTO> rangePkDtoMap,
                                              Map<String, BdAwards> awardsMap, BonusConfigDTO bonusConfigDTO, CuMemberSettleExt parentMemberTree,
                                              SaOrderRangeDto saOrderRangeDto, Map<Long, CuAwardsControl> cuAwardsControlMap) {
        RangeDTO rangeDto = getRangeDto(rangeDtoMap, awardsMap, parentMemberTree, cuAwardsControlMap);
        RangeDTO orderRangeDto = rangePkDtoMap.get(saOrderRangeDto.getPkCountry().toString() + saOrderRangeDto.getPkRange());
        if (rangeDto == null || orderRangeDto == null || parentMemberTree == null) {
            return null;
        }
        if (ECategory.NORMAL.getValue() != parentMemberTree.getCategory() || EAccountStatus.STOP_INCOME.getValue() == parentMemberTree.getAccountStatus() ||
                validateExistBonus(parentMemberTree, settleDate) ||
                validatePkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.RESALE_RANGE_INCOME.getValue()) ||
                rangeDto.getRangeValue() < orderRangeDto.getRangeValue()) {
            parentMemberTree = cuMemberTreeMap.get(parentMemberTree.getPkParent());
            if (parentMemberTree == null) {
                return null;
            }
            parentMemberTree = getCuMemberTree(cuMemberTreeMap, settleDate, rangeDtoMap, rangePkDtoMap, awardsMap, bonusConfigDTO,
                    parentMemberTree, saOrderRangeDto, cuAwardsControlMap);
        }
        return parentMemberTree;
    }

    private CuMemberBonusRange getCuMemberBonusRange(BonusConfigDTO bonusConfigDTO, SaOrderExt saOrderExt, CuMemberSettleExt cuMemberSettleExt, CuMemberBonus cuMemberBonus) {
        CuMemberBonusRange cuMemberBonusRange = CuMemberBonusRange.builder()
                .pkOrder(saOrderExt.getPkId())
                .pkBonus(cuMemberBonus.getPkId())
                .pkBonusItems(getPkBonusItems(bonusConfigDTO, cuMemberSettleExt.getPkSettleCountry(), EBonusItems.RESALE_RANGE_INCOME.getValue()))
                // 正常还是烧伤
                .incomeStatus(cuMemberSettleExt.getIncomeStatus())
                .calType(ECalType.VALUE.getValue())
                .calAchieve(saOrderExt.getOrderAmount())
                .calValue(BigDecimal.ZERO)
                .incomeRatio(BigDecimal.ZERO)
                .incomeDialRatio(BigDecimal.ZERO)
                .orderDialRatio(BigDecimal.ZERO)
                .usePoint(0)
                .build();
        cuMemberBonusRange.setPkCountry(cuMemberSettleExt.getPkSettleCountry());
        cuMemberBonusRange.setPkCreator(MagicNumberConstants.PK_ADMIN);
        return cuMemberBonusRange;
    }

    /**
     * @param settleTableName  结算表
     * @param period           期间
     * @param bonusConfigDTO   参数
     * @param cuMemberBonusMap 所有计算出来的奖金汇总
     * @Description: 计算加权积分奖励  自己购买数量每1个100 1分，推荐数量每1个100 1分，血缘网体10代内新增每1个100 1分，安置网体小区每1个100 1分
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/10 14:17
     */
    List<CuMemberBonusPoint> calculatePointShareBonus(String settleTableName, String settleTableNameDetail, String currentTableNameDetail, BonusConfigDTO bonusConfigDTO,
                                                      Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap, List<SaOrderExt> resaleOrderList, List<SaOrderExt> buySaOrderExtList) {
        List<CuMemberBonusPoint> cuMemberPointBonusList = new ArrayList<>();
        if (resaleOrderList.size() == 0) {
            return cuMemberPointBonusList;
        }
//        Map<String, String> systemConfigMap = systemConfigServiceApi.getBonusSystemConfig().getData();
        // 1。个人每购买1个100积分，奖励1分
        Map<Long, CuMemberBonusPoint> cuMemberBonusPointMap = new HashMap<>();
        Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
        if (buySaOrderExtList.size() > 0) {
            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryMemberSettleBySaOrder(settleTableName, settleTableNameDetail, buySaOrderExtList);
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            // 自己每购买1个100 奖励1分
            for (SaOrderExt saOrderExt : buySaOrderExtList) {
                CuMemberBonusPoint cuMemberBonusPoint = getCuMemberBonusPoint(cuMemberBonusPointMap, saOrderExt.getPkMember());
                for (SaOrderItemsExt saOrderItems : saOrderExt.getOrderItemsExtList()) {
                    if (EYesNo.NO.getIntValue() == saOrderItems.getIsGift()) {
                        cuMemberBonusPoint.setBuyPoint(cuMemberBonusPoint.getBuyPoint() + saOrderItems.getWaresQuantity());
                        cuMemberBonusPoint.setSumPoint(cuMemberBonusPoint.getSumPoint() + saOrderItems.getWaresQuantity());
                    }
                }
            }
        }
        // 计算分的总额 复销订单的20%，需要转换为美金
        BigDecimal shareMoney = BigDecimal.ZERO;
        if (resaleOrderList.size() > 0) {
            // 计算安置关系
            Map<Long, List<CuMemberSettleExt>> memberSettleMap = cuMemberTreeService.batchQueryCuMemberSettlePlaceParent(settleTableName, settleTableNameDetail, resaleOrderList);
            List<CuMemberSettleExt> memberSettleExtList = new ArrayList<>();
            for (List<CuMemberSettleExt> cuMemberSettleExt : memberSettleMap.values()) {
                memberSettleExtList.addAll(cuMemberSettleExt);
            }
            getMemberSettle(cuMemberSettleExtMap, memberSettleExtList);
            // 获取10代内血缘 每直推一个100 获得1分  10代内每新增一个100 获得1分
            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.queryMemberSettleTenParentBySaOrder(settleTableName, resaleOrderList);
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            for (SaOrderExt saOrderExt : resaleOrderList) {
                shareMoney = ComputeUtil.computeAdd(shareMoney, convertLocalCurrency(saOrderExt, bonusConfigDTO));
                CuMemberSettleExt sourceMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
                Long pkParent = sourceMemberSettleExt.getPkParent();
                CuMemberSettleExt parentMemberSettleExt = cuMemberSettleExtMap.get(pkParent);
                CuMemberBonusPoint parentMemberBonusPoint = getCuMemberBonusPoint(cuMemberBonusPointMap, parentMemberSettleExt.getPkMember());
                // 每直推一个100获得1分
                int point = 0;
                for (SaOrderItemsExt saOrderItems : saOrderExt.getOrderItemsExtList()) {
                    if (EYesNo.NO.getIntValue() == saOrderItems.getIsGift()) {
                        point += saOrderItems.getWaresQuantity();
                    }
                }
                if (ECategory.NORMAL.getValue() == parentMemberSettleExt.getCategory() &&
                        EAccountStatus.STOP_INCOME.getValue() != parentMemberSettleExt.getAccountStatus()) {
                    parentMemberBonusPoint.setPushPoint(parentMemberBonusPoint.getPushPoint() + point);
                    parentMemberBonusPoint.setSumPoint(parentMemberBonusPoint.getSumPoint() + point);
                }
                // 血缘10代
                for (int i = 0; i < MagicNumberConstants.BLOOD_GENERATION_END; i++) {
                    if (pkParent == null) {
                        break;
                    }
                    CuMemberSettleExt targetSettleExt = cuMemberSettleExtMap.get(pkParent);
                    if (targetSettleExt == null) {
                        break;
                    }
                    if (ECategory.NORMAL.getValue() != targetSettleExt.getCategory() ||
                            EAccountStatus.STOP_INCOME.getValue() == targetSettleExt.getAccountStatus()) {
                        pkParent = targetSettleExt.getPkParent();
                        continue;
                    }
                    CuMemberBonusPoint cuMemberBonusPoint = getCuMemberBonusPoint(cuMemberBonusPointMap, targetSettleExt.getPkMember());
                    cuMemberBonusPoint.setBloodPoint(cuMemberBonusPoint.getBuyPoint() + point);
                    cuMemberBonusPoint.setSumPoint(cuMemberBonusPoint.getSumPoint() + point);
                    pkParent = targetSettleExt.getPkParent();
                }
                // 所有需要计算的父节点，只计算新增
                List<CuMemberSettleExt> settleExtList = memberSettleMap.get(saOrderExt.getPkId());
                for (CuMemberSettleExt cuMemberSettleExt : settleExtList) {
                    // 数据已经准备好了，肯定有值，map中是实际的值，先计算新增，然后根据新增结算计算碰次，list是为了存储碰次的顺序
                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberSettleExt.getPkPlaceParent());
                    if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                            EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()) {
                        continue;
                    }
                    // 获取大区 业绩相同小部门算大区
                    List<CuMemberSettleDetailExt> cuMemberSettleDetailExtList = targetMemberSettleExt.getCuMemberSettleDetailExtList();
                    if (CollectionUtil.isNotEmpty(cuMemberSettleDetailExtList) && EPlaceDept.ZERO_DEPT.getValue() == targetMemberSettleExt.getBigAreaDept()) {
                        // 计算大小区，找到大区
                        BigDecimal bigAreaPv = BigDecimal.ZERO;
                        for (CuMemberSettleDetailExt cuMemberSettleDetailExt : cuMemberSettleDetailExtList) {
                            BigDecimal sumPv = cuMemberSettleDetailExt.getSumPv();
                            if (ComputeUtil.compareGreaterThan(sumPv, bigAreaPv)) {
                                targetMemberSettleExt.setBigAreaDept(cuMemberSettleDetailExt.getPlaceDept());
                                bigAreaPv = sumPv;
                            }
                        }
                    }
                    // 判断业绩，属于小区的话计算分数
                    if (EPlaceDept.ZERO_DEPT.getValue() != targetMemberSettleExt.getBigAreaDept() &&
                            !Objects.equals(cuMemberSettleExt.getPlaceDept(), targetMemberSettleExt.getBigAreaDept())) {
                        CuMemberBonusPoint cuMemberBonusPoint = getCuMemberBonusPoint(cuMemberBonusPointMap, targetMemberSettleExt.getPkMember());
                        cuMemberBonusPoint.setPlacePoint(cuMemberBonusPoint.getPlacePoint() + point);
                        cuMemberBonusPoint.setSumPoint(cuMemberBonusPoint.getSumPoint() + point);
                    }
                }
            }
        }
        // 待分配奖金
        shareMoney = ComputeUtil.computeBonusMultiply(shareMoney, BigDecimal.valueOf(20));
        // 开始计算奖金
        if (cuMemberBonusPointMap.size() > 0) {
            // 计算总得分   RESALE_INCOME_NUMBER   RESALE_INCOME_BONUS
            int sumPont = 0;
            for (Long pkMember : cuMemberBonusPointMap.keySet()) {
                CuMemberBonusPoint cuMemberBonusPoint = cuMemberBonusPointMap.get(pkMember);
                sumPont += cuMemberBonusPoint.getSumPoint();
            }
            // 计算奖金
            for (Long pkMember : cuMemberBonusPointMap.keySet()) {
                CuMemberSettleExt parentMemberTree = cuMemberSettleExtMap.get(pkMember);
                if (validatePkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.POINT_SHARE_INCOME.getValue())) {
                    continue;
                }
                SaOrder saOrderExt = SaOrder.builder().pkRate(parentMemberTree.getPkRate()).build();
                saOrderExt.setPkCountry(parentMemberTree.getPkSettleCountry());
                CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, parentMemberTree);
                CuMemberBonusPoint cuMemberBonusPoint = cuMemberBonusPointMap.get(pkMember);
                cuMemberBonusPoint.setCalAchieve(shareMoney);
                cuMemberBonusPoint.setCalValue(BigDecimal.valueOf(sumPont));
                cuMemberBonusPoint.setPkCountry(parentMemberTree.getPkSettleCountry());
                cuMemberBonusPoint.setPkBonusItems(getPkBonusItems(bonusConfigDTO, parentMemberTree.getPkSettleCountry(), EBonusItems.POINT_SHARE_INCOME.getValue()));
                // 最大奖金金额, 剩下的作为烧伤
                BigDecimal maxGrantIncome = ComputeUtil.computeDivide(ComputeUtil.computeMultiply(shareMoney, cuMemberBonusPoint.getSumPoint()), BigDecimal.valueOf(sumPont));
                maxGrantIncome = calculatePointIncomeByPoint(maxGrantIncome, parentMemberTree, cuMemberBonusPoint);
                sharePointRemark(parentMemberTree, cuMemberBonusPoint, maxGrantIncome);
                BdBonusDeduct bdBonusDeduct = bonusConfigDTO.getBonusDeductsMap().get(cuMemberBonusPoint.getPkBonusItems());
                BigDecimal incomeTax = BigDecimal.ZERO;
                if (bdBonusDeduct != null) {
                    incomeTax = ComputeUtil.computeBonusMultiply(cuMemberBonusPoint.getPretaxIncome(), ComputeUtil.computeAdd(bdBonusDeduct.getPlatformRatio(), bdBonusDeduct.getBackRatio()));
                }
                cuMemberBonusPoint.setIncomeTax(incomeTax);
                cuMemberBonusPoint.setRealIncome(ComputeUtil.computeSubtract(cuMemberBonusPoint.getPretaxIncome(), incomeTax));
                if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusPoint.getIncomeStatus()) {
                    cuMemberBonus.setFireShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getFireShareIncome(), maxGrantIncome));
                    cuMemberBonus.setPointShareIncome(ComputeUtil.computeAdd(cuMemberBonus.getPointShareIncome(), cuMemberBonusPoint.getPretaxIncome()));
                    setPurchaseTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusPoint);
                }
                cuMemberPointBonusList.add(cuMemberBonusPoint);
            }
        }
        // 更新复销剩余积分，复销剩余奖金
        cuMemberTreeService.updateCuMemberSettle(settleTableName, settleTableNameDetail, currentTableNameDetail, cuMemberSettleExtMap);
        return cuMemberPointBonusList;
    }

    /*
     * @description: 根基会员积分计算奖金
     * @author: sui q
     * @date: 2023/10/14 9:42
     * @param: null null
     **/
    private BigDecimal calculatePointIncomeByPoint(BigDecimal maxGrantIncome, CuMemberSettleExt parentMemberTree, Object cuMemberBonusDetail) {
        // 发放奖金金额
        BigDecimal grantIncome = BigDecimal.ZERO;
        while (ComputeUtil.compareValue(maxGrantIncome)) {
            if (parentMemberTree.getResaleIncomeNumber() <= 0 && !ComputeUtil.compareValue(parentMemberTree.getResaleIncomeBonus())) {
                break;
            }
            if (!ComputeUtil.compareValue(parentMemberTree.getResaleIncomeBonus())) {
                int usePoint = ReflectUtils.invokeGetter(cuMemberBonusDetail, "usePoint");
                ReflectUtils.invokeSetter(cuMemberBonusDetail, "usePoint", usePoint + 1);
                parentMemberTree.setResaleIncomeNumber(parentMemberTree.getResaleIncomeNumber() - 1);
                parentMemberTree.setResaleIncomeBonus(ComputeUtil.computeAdd(parentMemberTree.getResaleIncomeBonus(), MagicNumberConstants.POINT_CAPPING));
            }
            if (ComputeUtil.compareValue(parentMemberTree.getResaleIncomeBonus(), maxGrantIncome)) {
                parentMemberTree.setResaleIncomeBonus(ComputeUtil.computeSubtract(parentMemberTree.getResaleIncomeBonus(), maxGrantIncome));
                grantIncome = ComputeUtil.computeAdd(grantIncome, maxGrantIncome);
                maxGrantIncome = BigDecimal.ZERO;
            } else {
                grantIncome = ComputeUtil.computeAdd(grantIncome, parentMemberTree.getResaleIncomeBonus());
                maxGrantIncome = ComputeUtil.computeSubtract(maxGrantIncome, parentMemberTree.getResaleIncomeBonus());
                parentMemberTree.setResaleIncomeBonus(BigDecimal.ZERO);
            }
        }
        ReflectUtils.invokeSetter(cuMemberBonusDetail, "pretaxIncome", grantIncome);
        return maxGrantIncome;
    }

    private CuMemberBonusPoint getCuMemberBonusPoint(Map<Long, CuMemberBonusPoint> cuMemberBonusPointMap, Long pkMember) {
        if (cuMemberBonusPointMap.containsKey(pkMember)) {
            return cuMemberBonusPointMap.get(pkMember);
        } else {
            CuMemberBonusPoint cuMemberBonusPoint = CuMemberBonusPoint
                    .builder().pkBonus(pkMember).buyPoint(0).pushPoint(0).bloodPoint(0).placePoint(0).sumPoint(0).usePoint(0)
                    .calType(ECalType.RATIO.getValue())
                    .calAchieve(BigDecimal.ZERO)
                    .calValue(BigDecimal.ZERO)
                    .pretaxIncome(BigDecimal.ZERO)
                    .incomeTax(BigDecimal.ZERO)
                    .realIncome(BigDecimal.ZERO)
                    .incomeStatus(EIncomeStatus.NORMAL.getValue())
                    .build();
            cuMemberBonusPoint.setPkCreator(MagicNumberConstants.PK_ADMIN);
            cuMemberBonusPointMap.put(pkMember, cuMemberBonusPoint);
            return cuMemberBonusPoint;
        }
    }
}
