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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.achieve.service.ICuMemberTreeService;
import com.hzs.bonus.achieve.service.impl.CuMemberBonusSettle;
import com.hzs.bonus.bonus.mapper.*;
import com.hzs.bonus.bonus.param.BonusParam;
import com.hzs.bonus.bonus.service.IBonusSettleService;
import com.hzs.bonus.bonus.service.ICuMemberBonusService;
import com.hzs.bonus.bonus.vo.MemberBonusDetailSerVO;
import com.hzs.bonus.bonus.vo.MemberBonusDetailVO;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.member.bonus.CuMemberBonus;
import com.hzs.common.domain.member.ext.*;
import com.hzs.common.domain.system.config.BdBonusItems;
import com.hzs.common.domain.system.config.ext.BdBonusItemsExt;
import com.hzs.system.base.ICurrencyServiceApi;
import com.hzs.system.base.ISystemConfigServiceApi;
import com.hzs.system.base.dto.CurrencyDTO;
import com.hzs.system.config.IBonusItemsServiceApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 会员奖金-会员奖金汇总表 服务实现类
 */
@Service
@Slf4j
public class CuMemberBonusServiceImpl extends ServiceImpl<CuMemberBonusMapper, CuMemberBonus> implements ICuMemberBonusService {

    @DubboReference
    ISystemConfigServiceApi iSystemConfigServiceApi;
    @DubboReference
    ICurrencyServiceApi iCurrencyServiceApi;
    @DubboReference
    IBonusItemsServiceApi iBonusItemsServiceApi;

    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;

    private CuMemberBonusDetailMapper cuMemberBonusDetailMapper;

    private CuMemberBonusPushMapper cuMemberBonusPushMapper;

    private CuMemberBonusExpandMapper cuMemberBonusExpandMapper;

    private CuMemberBonusCoachMapper cuMemberBonusCoachMapper;

    private CuMemberBonusRangeMapper cuMemberBonusRangeMapper;

    private CuMemberBonusSettle cuMemberBonusSettle;

    private ICuMemberTreeService cuMemberTreeService;

    private IBonusSettleService bonusSettleService;

    @Autowired
    public void setBonusSettleService(IBonusSettleService bonusSettleService) {
        this.bonusSettleService = bonusSettleService;
    }

    @Autowired
    public void setCuMemberTreeService(ICuMemberTreeService cuMemberTreeService) {
        this.cuMemberTreeService = cuMemberTreeService;
    }

    @Autowired
    public void setCuMemberBonusSettle(CuMemberBonusSettle cuMemberBonusSettle) {
        this.cuMemberBonusSettle = cuMemberBonusSettle;
    }

    @Autowired
    public void setCuMemberBonusPushMapper(CuMemberBonusPushMapper cuMemberBonusPushMapper) {
        this.cuMemberBonusPushMapper = cuMemberBonusPushMapper;
    }

    @Autowired
    public void setCuMemberBonusExpandMapper(CuMemberBonusExpandMapper cuMemberBonusExpandMapper) {
        this.cuMemberBonusExpandMapper = cuMemberBonusExpandMapper;
    }

    @Autowired
    public void setCuMemberBonusCoachMapper(CuMemberBonusCoachMapper cuMemberBonusCoachMapper) {
        this.cuMemberBonusCoachMapper = cuMemberBonusCoachMapper;
    }

    @Autowired
    public void setCuMemberBonusRangeMapper(CuMemberBonusRangeMapper cuMemberBonusRangeMapper) {
        this.cuMemberBonusRangeMapper = cuMemberBonusRangeMapper;
    }

    @Autowired
    public void setCuMemberBonusDetailMapper(CuMemberBonusDetailMapper cuMemberBonusDetailMapper) {
        this.cuMemberBonusDetailMapper = cuMemberBonusDetailMapper;
    }

    @Override
    public List<Long> batchQueryCuMemberBonusSeq(Integer rowNum) {
        return baseMapper.batchQueryCuMemberBonusSeq(rowNum);
    }

    @Override
    public List<CuMemberBonusExt> queryMemberBonusVoByCondition(BonusParam bonusParam) {
//        String value = iSystemConfigServiceApi.getBonusSystemConfig(bonusParam.getPkCountry(), ESystemConfig.EXPAND_CAP_METHOD.getKey()).getData();
//        if (StringUtils.isNotEmpty(value) && Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), value)) {
//            // 周结的话不能查询当前周的数据，只能查询上周的数据
//            bonusParam.setEndDate(DateUtils.parseStringToDate(DateUtils.getRecentlyTuesday(bonusParam.getEndDate())));
//        }
        return handleMemberBonusPurchase(getCuMemberBonusExtList(bonusParam), bonusParam);
    }

    private List<CuMemberBonusExt> handleMemberBonusPurchase(List<CuMemberBonusExt> cuMemberBonusExtList, BonusParam bonusParam) {
//        if (StringUtils.isNotEmpty(value) && Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), value)) {
//            Collections.reverse(cuMemberBonusExtList);
//            return cuMemberBonusExtList;
//        }

        List<CuMemberBonusExt> memberBonusExtList = new ArrayList<>();
        Map<String, CuMemberBonusExt> cuMemberBonusExtMap = new HashMap<>();
        cuMemberBonusExtList.forEach(cuMemberBonusExt -> cuMemberBonusExtMap.put(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, cuMemberBonusExt.getSettleDate()), cuMemberBonusExt));
        Date endDate = DateUtils.beforeDate(1, ChronoUnit.DAYS, bonusParam.getEndDate());
        Date compareDate = DateUtils.parseStringToDateTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.currentDate()) + " 13:00:00");

        while (DateUtils.compareDateAfter(endDate, bonusParam.getStartDate())
                || DateUtils.compareDateEqual(endDate, bonusParam.getStartDate())) {
            String date = DateUtils.parseDateToFormat(DateUtils.YYYY_MM_DD, endDate);
            if (cuMemberBonusExtMap.containsKey(date)) {
                memberBonusExtList.add(cuMemberBonusExtMap.get(date));
            } else {
                if (!DateUtils.compareDateEqual(endDate, DateUtils.beforeDate(1, ChronoUnit.DAYS, DateUtils.currentDate()))
                        || DateUtils.compareDateTimeAfter(DateUtils.currentDateTime(), compareDate)) {
                    CuMemberBonusExt cuMemberBonusExt = new CuMemberBonusExt();
                    cuMemberBonusExt.setSettleDate(endDate);
                    cuMemberBonusExt.setServiceSpend(BigDecimal.ZERO);
                    cuMemberBonusExt.setBackPoints(BigDecimal.ZERO);
                    cuMemberBonusExt.setDirectIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setExpandIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setCoachIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setShareIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setServiceIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setBackPoints(BigDecimal.ZERO);
                    cuMemberBonusExt.setServiceSpend(BigDecimal.ZERO);
                    cuMemberBonusExt.setPurRealSubtotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurPushIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurExpandIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurRealSubtotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurCoupon(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurCouponShare(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurCouponSubtotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setGlobalPoints(BigDecimal.ZERO);
                    cuMemberBonusExt.setCarAwardPoints(BigDecimal.ZERO);
                    cuMemberBonusExt.setRealIncomeTotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setStoreIncome(BigDecimal.ZERO);

                    cuMemberBonusExt.setRepurRangeIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailRangeIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailSameLevelIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailAreaIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailBenefitRangeIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailMonthRepurchaseIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailBenefitAvgIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailBenefitIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailRealSubtotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setRetailBenefitIncomeTotal(BigDecimal.ZERO);
                    memberBonusExtList.add(cuMemberBonusExt);
                }
            }
            endDate = DateUtils.beforeDate(1, ChronoUnit.DAYS, endDate);
        }
        return memberBonusExtList;
    }

    @Override
    public List<CuMemberBonusExt> queryMemberSecondBonusVoByCondition(BonusParam bonusParam) {
        return getCuMemberBonusExtList(bonusParam);
    }

    private List<CuMemberBonusExt> getCuMemberBonusExtList(BonusParam bonusParam) {
        if (bonusParam.getGrantStatus() == null) {
            bonusParam.setGrantStatus(EGrantStatus.PUBLISHED.getValue());
        }
        List<CuMemberBonusExt> cuMemberBonusExtList = baseMapper.queryMemberBonusByCondition(bonusParam);
        R<CurrencyDTO> currency = iCurrencyServiceApi.getCurrency(bonusParam.getPkCountry());
        // 汇率比例
        BigDecimal inExchangeRate = currency.getData().getInExchangeRate();
        for (CuMemberBonusExt cuMemberBonusExt : cuMemberBonusExtList) {
            cuMemberBonusExt.setDirectIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getDirectIncome(), inExchangeRate));
            cuMemberBonusExt.setExpandIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getExpandIncome(), inExchangeRate));
            cuMemberBonusExt.setCoachIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getCoachIncome(), inExchangeRate));
            cuMemberBonusExt.setShareIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getShareIncome(), inExchangeRate));
            cuMemberBonusExt.setServiceIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getServiceIncome(), inExchangeRate));
            cuMemberBonusExt.setBackPoints(ComputeUtil.computeMultiply(cuMemberBonusExt.getBackPoints(), inExchangeRate));
            cuMemberBonusExt.setServiceSpend(ComputeUtil.computeMultiply(cuMemberBonusExt.getServiceSpend(), inExchangeRate));
            cuMemberBonusExt.setPurRealSubtotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getPurRealSubtotal(), inExchangeRate));
            cuMemberBonusExt.setRepurPushIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurPushIncome(), inExchangeRate));
            cuMemberBonusExt.setRepurExpandIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurExpandIncome(), inExchangeRate));
            cuMemberBonusExt.setRepurRealSubtotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurRealSubtotal(), inExchangeRate));
            cuMemberBonusExt.setRepurCoupon(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurCoupon(), inExchangeRate));
            cuMemberBonusExt.setRepurCouponShare(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurCouponShare(), inExchangeRate));
            cuMemberBonusExt.setRepurCouponSubtotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurCouponSubtotal(), inExchangeRate));
            cuMemberBonusExt.setGlobalPoints(ComputeUtil.computeMultiply(cuMemberBonusExt.getGlobalPoints(), inExchangeRate));
            cuMemberBonusExt.setCarAwardPoints(ComputeUtil.computeMultiply(cuMemberBonusExt.getCarAwardPoints(), inExchangeRate));
            cuMemberBonusExt.setRealIncomeTotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRealIncomeTotal(), inExchangeRate));
            cuMemberBonusExt.setStoreIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getStoreIncome(), inExchangeRate));

            cuMemberBonusExt.setRepurRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurRangeIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailRangeIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailSameLevelIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailSameLevelIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailAreaIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailAreaIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailBenefitRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailBenefitRangeIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailMonthRepurchaseIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailMonthRepurchaseIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailBenefitAvgIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailBenefitAvgIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailBenefitIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailBenefitIncome(), inExchangeRate));
            cuMemberBonusExt.setRetailRealSubtotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRetailRealSubtotal(), inExchangeRate));
            // 福利分红总计
            cuMemberBonusExt.setRetailBenefitIncomeTotal(cuMemberBonusExt.getRetailBenefitAvgIncome().add(cuMemberBonusExt.getRetailBenefitIncome()));
        }
        return cuMemberBonusExtList;
    }

    @Override
    public void calculateBonusTotal(CuMemberBonusExt cuMemberBonusExt, CuMemberBonusExt memberBonusExt) {
        cuMemberBonusExt.setDirectIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getDirectIncome(), memberBonusExt.getDirectIncome()));
        cuMemberBonusExt.setExpandIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getExpandIncome(), memberBonusExt.getExpandIncome()));
        cuMemberBonusExt.setShareIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getShareIncome(), memberBonusExt.getShareIncome()));
        cuMemberBonusExt.setServiceIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getServiceIncome(), memberBonusExt.getServiceIncome()));
        cuMemberBonusExt.setBackPoints(ComputeUtil.computeAdd(cuMemberBonusExt.getBackPoints(), memberBonusExt.getBackPoints()));
        cuMemberBonusExt.setServiceSpend(ComputeUtil.computeAdd(cuMemberBonusExt.getServiceSpend(), memberBonusExt.getServiceSpend()));
        cuMemberBonusExt.setPurRealSubtotal(ComputeUtil.computeAdd(cuMemberBonusExt.getPurRealSubtotal(), memberBonusExt.getPurRealSubtotal()));
        cuMemberBonusExt.setRepurPushIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurPushIncome(), memberBonusExt.getRepurPushIncome()));
        cuMemberBonusExt.setRepurExpandIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurExpandIncome(), memberBonusExt.getRepurExpandIncome()));
        cuMemberBonusExt.setRepurRealSubtotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurRealSubtotal(), memberBonusExt.getRepurRealSubtotal()));
        cuMemberBonusExt.setRepurCoupon(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurCoupon(), memberBonusExt.getRepurCoupon()));
        cuMemberBonusExt.setRepurCouponShare(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurCouponShare(), memberBonusExt.getRepurCouponShare()));
        cuMemberBonusExt.setRepurCouponSubtotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurCouponSubtotal(), memberBonusExt.getRepurCouponSubtotal()));
        cuMemberBonusExt.setGlobalPoints(ComputeUtil.computeAdd(cuMemberBonusExt.getGlobalPoints(), memberBonusExt.getGlobalPoints()));
        cuMemberBonusExt.setCarAwardPoints(ComputeUtil.computeAdd(cuMemberBonusExt.getCarAwardPoints(), memberBonusExt.getCarAwardPoints()));
        cuMemberBonusExt.setRealIncomeTotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRealIncomeTotal(), memberBonusExt.getRealIncomeTotal()));
        cuMemberBonusExt.setStoreIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getStoreIncome(), memberBonusExt.getStoreIncome()));

        cuMemberBonusExt.setRepurRangeIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurRangeIncome(), memberBonusExt.getRepurRangeIncome()));
        cuMemberBonusExt.setRetailRangeIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailRangeIncome(), memberBonusExt.getRetailRangeIncome()));
        cuMemberBonusExt.setRetailSameLevelIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailSameLevelIncome(), memberBonusExt.getRetailSameLevelIncome()));
        cuMemberBonusExt.setRetailAreaIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailAreaIncome(), memberBonusExt.getRetailAreaIncome()));
        cuMemberBonusExt.setRetailBenefitRangeIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailBenefitRangeIncome(), memberBonusExt.getRetailBenefitRangeIncome()));
        cuMemberBonusExt.setRetailMonthRepurchaseIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailMonthRepurchaseIncome(), memberBonusExt.getRetailMonthRepurchaseIncome()));
        cuMemberBonusExt.setCoachIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getCoachIncome(), memberBonusExt.getCoachIncome()));
        cuMemberBonusExt.setRetailBenefitAvgIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailBenefitAvgIncome(), memberBonusExt.getRetailBenefitAvgIncome()));
        cuMemberBonusExt.setRetailBenefitIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailBenefitIncome(), memberBonusExt.getRetailBenefitIncome()));
        cuMemberBonusExt.setRetailRealSubtotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRetailRealSubtotal(), memberBonusExt.getRetailRealSubtotal()));
    }

    @Override
    public List<CuMemberBonusExt> queryMemberBonusTotalByCondition(BonusParam bonusParam) {
        return getCuMemberBonusExtList(bonusParam);
    }

    @Override
    public CuMemberBonusExt initCuMemberBonus() {
        CuMemberBonusExt cuMemberBonusExt = new CuMemberBonusExt();
        cuMemberBonusExt.setDirectIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setExpandIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setExpandNoCapping(BigDecimal.ZERO);
        cuMemberBonusExt.setExpandCapping(BigDecimal.ZERO);
        cuMemberBonusExt.setShareIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setServiceIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setBackPoints(BigDecimal.ZERO);
        cuMemberBonusExt.setServiceSpend(BigDecimal.ZERO);
        cuMemberBonusExt.setPurRealSubtotal(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurPushIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurExpandIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurRealSubtotal(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurCoupon(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurCouponShare(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurCouponSubtotal(BigDecimal.ZERO);
        cuMemberBonusExt.setStoreIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setGlobalPoints(BigDecimal.ZERO);
        cuMemberBonusExt.setCarAwardPoints(BigDecimal.ZERO);
        cuMemberBonusExt.setRealIncomeTotal(BigDecimal.ZERO);

        cuMemberBonusExt.setRepurRangeIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailRangeIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailSameLevelIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailAreaIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailBenefitRangeIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailMonthRepurchaseIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setCoachIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailBenefitAvgIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailBenefitIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRetailRealSubtotal(BigDecimal.ZERO);
        return cuMemberBonusExt;
    }

    @Override
    public List<CuMemberBonusExt> queryMemberBonusVoByConditionForServer(BonusParam bonusParam) {
        if (bonusParam.getEndDate() != null) {
            bonusParam.setEndDate(DateUtils.afterDate(1, ChronoUnit.DAYS, bonusParam.getEndDate()));
        }
        return baseMapper.queryMemberBonusByConditionForServer(bonusParam);
    }

    @Override
    public CuMemberBonusExt queryMemberBonusByConditionForServerSum(BonusParam bonusParam) {
        return baseMapper.queryMemberBonusByConditionForServerSum(bonusParam);
    }

    @Override
    public List<CuMemberBonusExt> queryBonusTotalVoByConditionForServer(BonusParam bonusParam) {
        return baseMapper.queryBonusTotalVoByConditionForServer(bonusParam);
    }

    @Override
    public TableDataInfo queryMemberBonusDetailVoByCondition(BonusParam bonusParam) {
        List<MemberBonusDetailVO> memberBonusDetailVOList = new ArrayList<>();
        TableDataInfo dataTable;
        Integer bonusItemsValue = 0;
        if (bonusParam.getPkBonusItems() != null) {
            BdBonusItems bonusItems = iBonusItemsServiceApi.queryBonusItems(bonusParam.getPkCountry(), bonusParam.getPkBonusItems()).getData();
            bonusItemsValue = bonusItems.getBonusValue();
        }
        if (null == bonusParam.getPkBonusItems()) {
            List<CuMemberBonusDetailExt> cuMemberBonusDetailList = cuMemberBonusDetailMapper.queryMemberBonusDetailByCondition(bonusParam);
            dataTable = getDataTable(cuMemberBonusDetailList);
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusDetail, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusDetail.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusDetail.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.DIRECT_INCOME.getValue() == bonusItemsValue) {
            // 直推收益
            List<CuMemberBonusPushExt> cuMemberBonusPushList = cuMemberBonusPushMapper.queryMemberBonusPushByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusPushList);
            cuMemberBonusPushList.forEach(cuMemberBonusPush -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusPush, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusPush.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusPush.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.EXPANSION_INCOME.getValue() == bonusItemsValue ||
                EBonusItems.CONSUMPTION_EXPANSION_INCOME.getValue() == bonusItemsValue) {
            // 拓展收益、复购拓展收益
            List<CuMemberBonusExpandExt> cuMemberBonusExpandList = cuMemberBonusExpandMapper.queryMemberBonusExpandByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusExpandList);
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusExpand, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusExpand.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusExpand.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.COACHING_INCOME.getValue() == bonusItemsValue) {
            // 辅导收益
            // 拓展收益、复购拓展收益
            List<CuMemberBonusCoachExt> cuMemberBonusCoachList = cuMemberBonusCoachMapper.queryMemberBonusCoachByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusCoachList);
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusCoach, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusCoach.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusCoach.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.REPURCHASE_RANGE_INCOME.getValue() == bonusItemsValue) {
            // 复购极差
            List<CuMemberBonusRangeExt> cuMemberBonusRangeList = cuMemberBonusRangeMapper.queryMemberBonusRangeByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusRangeList);
            cuMemberBonusRangeList.forEach(cuMemberBonusRange -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusRange, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusRange.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusRange.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else {
            // 其他收益 服务补贴、分红收益、嗨粉直推
            // 拓展收益、复购拓展收益
            List<CuMemberBonusDetailExt> cuMemberBonusDetailList = cuMemberBonusDetailMapper.queryMemberBonusDetailByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusDetailList);
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusDetail, MemberBonusDetailVO.class);
                memberBonusDetailVO.setSourceMemberCode(cuMemberBonusDetail.getSourceMemberCode());
                memberBonusDetailVO.setSourceMemberName(cuMemberBonusDetail.getSourceMemberName());
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        }
        Map<Integer, BdBonusItemsExt> bonusItemsMap = convertBonusItems(bonusParam);
        CurrencyDTO currencyDTO = iCurrencyServiceApi.getCurrency(bonusParam.getPkCountry()).getData();
        memberBonusDetailVOList.forEach(memberBonusDetailVO -> {
            if (bonusItemsMap.containsKey(memberBonusDetailVO.getPkBonusItems())) {
                memberBonusDetailVO.setBonusName(bonusItemsMap.get(memberBonusDetailVO.getPkBonusItems()).getBonusName());
            }
            // 转换汇率
            if (!Objects.equals(bonusParam.getPkCountry(), memberBonusDetailVO.getPkSourceCountry())) {
                memberBonusDetailVO.setOrderAmount(ComputeUtil.computeMultiply(ComputeUtil.computeDivide(memberBonusDetailVO.getOrderAmount(),
                        memberBonusDetailVO.getOutExchangeRate()), currencyDTO.getOutExchangeRate()));
            }
        });
        dataTable.setRows(memberBonusDetailVOList);
        return dataTable;
    }

    private Map<Integer, BdBonusItemsExt> convertBonusItems(BonusParam bonusParam) {
        List<BdBonusItemsExt> bonusItemsExtList = iBonusItemsServiceApi.queryBonusItems(bonusParam.getPkCountry()).getData();
        Map<Integer, BdBonusItemsExt> bonusItemsMap = new HashMap<>(ComputeUtil.mapInitCapacity(bonusItemsExtList.size()));
        bonusItemsExtList.forEach(bonusItems ->
                bonusItemsMap.put(bonusItems.getPkId(), bonusItems));

        return bonusItemsMap;
    }

    @Override
    public TableDataInfo queryMemberBonusDetailSerVoByCondition(BonusParam bonusParam) {
        List<MemberBonusDetailSerVO> memberBonusDetailSerVoS = new ArrayList<>();
        Integer bonusItemsValue = 0;
        if (bonusParam.getPkBonusItems() != null) {
            BdBonusItems bonusItems = iBonusItemsServiceApi.queryBonusItems(bonusParam.getPkCountry(), bonusParam.getPkBonusItems()).getData();
            bonusItemsValue = bonusItems.getBonusValue();
        }
        if (bonusParam.getEndDate() != null) {
            bonusParam.setEndDate(DateUtils.afterDate(1, ChronoUnit.DAYS, bonusParam.getEndDate()));
        }
        TableDataInfo dataTable;
        if (null == bonusParam.getPkBonusItems()) {
            List<CuMemberBonusDetailExt> cuMemberBonusDetailList = cuMemberBonusDetailMapper.queryMemberBonusDetailByConditionForServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusDetailList);
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusDetail, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.DIRECT_INCOME.getValue() == bonusItemsValue) {
            // 启动卡直推 推荐收益
            List<CuMemberBonusPushExt> cuMemberBonusPushList = cuMemberBonusPushMapper.queryMemberBonusPushByBonusItemsFoServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusPushList);
            cuMemberBonusPushList.forEach(cuMemberBonusPush -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusPush, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.EXPANSION_INCOME.getValue() == bonusItemsValue
                || EBonusItems.CONSUMPTION_EXPANSION_INCOME.getValue() == bonusItemsValue) {
            // 拓展收益、复购拓展收益
            List<CuMemberBonusExpandExt> cuMemberBonusExpandList = cuMemberBonusExpandMapper.queryMemberBonusExpandByBonusItemsForServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusExpandList);
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusExpand, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.RETAIL_COACHING_INCOME.getValue() == bonusItemsValue) {
            // 培育津贴
            List<CuMemberBonusCoachExt> cuMemberBonusCoachList = cuMemberBonusCoachMapper.queryMemberBonusCoachByBonusItemsForServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusCoachList);
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusCoach, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.REPURCHASE_RANGE_INCOME.getValue() == bonusItemsValue
                || EBonusItems.RETAIL_RANGE_INCOME.getValue() == bonusItemsValue
                || EBonusItems.RETAIL_SAME_LEVEL_INCOME.getValue() == bonusItemsValue
                || EBonusItems.RETAIL_BENEFIT_RANGE_INCOME.getValue() == bonusItemsValue
                || EBonusItems.RETAIL_MONTH_REPURCHASE_INCOME.getValue() == bonusItemsValue) {
            // 直推收益、平级收益、福利级差、复购级差
            List<CuMemberBonusRangeExt> cuMemberBonusRangeList = cuMemberBonusRangeMapper.queryMemberBonusRangeByBonusItemsForServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusRangeList);
            cuMemberBonusRangeList.forEach(cuMemberBonusRange -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusRange, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        } else {
            // 其他收益 区域分红、月度分红平均、月度分红加权
            List<CuMemberBonusDetailExt> cuMemberBonusDetailList = cuMemberBonusDetailMapper.queryMemberBonusDetailByBonusItemsForServer(bonusParam);
            dataTable = getDataTable(cuMemberBonusDetailList);
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusDetail, MemberBonusDetailSerVO.class);
                memberBonusDetailSerVoS.add(memberBonusDetailVO);
            });
        }
        Map<Integer, BdBonusItemsExt> bonusItemsMap = convertBonusItems(bonusParam);
        memberBonusDetailSerVoS.forEach(memberBonusDetailSerVO -> {
            if (bonusItemsMap.containsKey(memberBonusDetailSerVO.getPkBonusItems())) {
                memberBonusDetailSerVO.setBonusName(bonusItemsMap.get(memberBonusDetailSerVO.getPkBonusItems()).getBonusName());
            }
            memberBonusDetailSerVO.setOrderAmountDollar(memberBonusDetailSerVO.getOrderAmount());
            memberBonusDetailSerVO.setOrderAchieveOri(memberBonusDetailSerVO.getOrderAchieve());
            memberBonusDetailSerVO.setPretaxIncomeOri(memberBonusDetailSerVO.getPretaxIncome());
            memberBonusDetailSerVO.setRealIncomeOri(memberBonusDetailSerVO.getRealIncome());
            memberBonusDetailSerVO.setIncomeRatio(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getIncomeRatio(), 100));
            memberBonusDetailSerVO.setIncomeDialRatio(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getIncomeDialRatio(), 100));
            memberBonusDetailSerVO.setOrderDialRatio(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getOrderDialRatio(), 100));
            if (memberBonusDetailSerVO.getExpandNoCapping() != null || memberBonusDetailSerVO.getExpandCappingOri() != null) {
                memberBonusDetailSerVO.setExpandNoCappingOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getExpandNoCapping(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setExpandCappingOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getExpandCapping(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setExpandNormalHalfOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getExpandNormalHalf(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setExpandNormalRealOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getExpandNormalReal(), memberBonusDetailSerVO.getOutExchangeRate()));
            }
            if (memberBonusDetailSerVO.getCoachNoCapping() != null || memberBonusDetailSerVO.getCoachNormalHalf() != null) {
                memberBonusDetailSerVO.setCoachNoCappingOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getCoachNoCapping(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setCoachCappingOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getCoachCapping(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setCoachNormalHalfOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getCoachNormalHalf(), memberBonusDetailSerVO.getOutExchangeRate()));
                memberBonusDetailSerVO.setCoachNormalRealOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getCoachNormalReal(), memberBonusDetailSerVO.getOutExchangeRate()));
            }
            memberBonusDetailSerVO.setOrderTypeVal(EOrderType.getEnumLabelByValue(memberBonusDetailSerVO.getOrderType()));
            memberBonusDetailSerVO.setIncomeStatusVal(EBonusIncomeStatus.getEnumLabelByValue(memberBonusDetailSerVO.getIncomeStatus()));
        });
        dataTable.setRows(memberBonusDetailSerVoS);
        return dataTable;
    }

    protected TableDataInfo getDataTable(List<?> list) {
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setRows(list);
        rspData.setMsg("查询成功");
        rspData.setTotal(new PageInfo<>(list).getTotal());
        return rspData;
    }

    @Override
    public void deleteCuMemberBonus(Integer period) {
        baseMapper.deleteCuMemberBonus(period);
    }

    @Override
    public void batchInsertCuMemberBonus(List<CuMemberBonus> cuMemberBonusList) {
        if (cuMemberBonusList.size() == 0) {
            return;
        }
        List<List<?>> lists = cuMemberBonusSettle.handleCutList(cuMemberBonusList);
        lists.forEach(list ->
                baseMapper.batchInsertCuMemberBonus(list));
    }

    @Override
    public void insertOrUpdateCuMemberBonus(List<CuMemberBonus> cuMemberBonusList) {
        baseMapper.insertOrUpdateCuMemberBonus(cuMemberBonusList);
    }

    @Override
    public List<CuMemberBonus> queryCuMemberBonus(int period, List<CuMemberBonus> cuMemberBonusList) {
        QueryWrapper<CuMemberBonus> queryWrapper = new QueryWrapper<>();
        List<Long> memberList = cuMemberBonusList.stream().map(CuMemberBonus::getPkMember).collect(Collectors.toList());
        queryWrapper.eq(MemberFieldConstants.PERIOD, period);
        queryWrapper.in(MemberFieldConstants.PK_MEMBER, memberList);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean updateCuMemberBonusStatus(Integer pkCountry, Integer grantStatus, Integer oldGrantStatus, Integer startPeriod, Integer endPeriod) {
        return baseMapper.updateCuMemberBonusStatus(pkCountry, grantStatus, oldGrantStatus, startPeriod, endPeriod) > 0 ? Boolean.TRUE : Boolean.FALSE;
    }

    @Override
    public List<CuMemberBonus> queryCuMemberBonusByCondition(Integer pkCountry, Integer grantStatus, Integer startPeriod, Integer endPeriod) {
        QueryWrapper<CuMemberBonus> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("pk_member,pk_rate,pk_country,sum(direct_income) direct_income,sum(expand_income) expand_income,sum(expand_no_capping) expand_no_capping," +
                "sum(expand_capping) expand_capping,sum(coach_income) coach_income,sum(share_income) share_income," +
                "sum(service_income) service_income,sum(back_points) back_points,sum(service_spend) service_spend," +
                "sum(pur_real_subtotal) pur_real_subtotal,sum(repur_range_income) repur_range_income,sum(repur_expand_income) repur_expand_income," +
                "sum(repur_real_subtotal) repur_real_subtotal,sum(cloud_direct_income) cloud_direct_income,sum(cloud_pur_income) cloud_pur_income," +
                "sum(cloud_repur_income) cloud_repur_income,sum(cloud_real_subtotal) cloud_real_subtotal,sum(repur_coupon) repur_coupon," +
                "sum(REPUR_COUPON_SHARE) REPUR_COUPON_SHARE,sum(REPUR_COUPON_SUBTOTAL) REPUR_COUPON_SUBTOTAL," +
                "sum(global_points) global_points,sum(car_award_points) car_award_points,sum(hi_fun_income) hi_fun_income," +
                "sum(real_income_total) real_income_total");
        queryWrapper.eq(SystemFieldConstants.PK_COUNTRY, pkCountry);
        queryWrapper.eq(MemberBonusFieldConstants.GRANT_STATUS, grantStatus);
        queryWrapper.eq(MemberBonusFieldConstants.INCOME_STATUS, ENormalDisable.NORMAL.getValue());
        queryWrapper.between(MemberFieldConstants.PERIOD, startPeriod, endPeriod);
        queryWrapper.gt(MemberBonusFieldConstants.REAL_INCOME_TOTAL, 0);
        queryWrapper.groupBy("pk_member,pk_rate,pk_country");
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean autoCalculateBonus(Date startDate, Date endDate) {
        String settleDate = DateUtils.parseDateTimeToStr(DateUtils.YYYY_MM_DD, startDate);
        // 自动初始化表
        cuMemberTreeService.createCuMemberTree(settleDate);
        log.info("初始化表完成");
        // 奖金结算
        bonusSettleService.calculateCuMemberBonus(settleDate, null);
        return Boolean.TRUE;
    }

    @Override
    public void backupsSettleBonusEveryday() {
        cuMemberTreeService.createCuMemberTree(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS)));
    }

    @Override
    public Set<Long> queryMemberBonusByPeriod(Integer period) {
        LambdaQueryWrapper<CuMemberBonus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CuMemberBonus::getPeriod, period);
        queryWrapper.le(CuMemberBonus::getGrantStatus, EGrantStatus.PUBLISHED.getValue());
        List<CuMemberBonus> cuMemberBonusList = baseMapper.selectList(queryWrapper);
        return cuMemberBonusList.stream().distinct().map(CuMemberBonus::getPkId).collect(Collectors.toSet());
    }

    @Override
    public void mergeBackMemberBonusIncome(Long pkOrder) {
        baseMapper.mergeBackRangeBonusIncome(pkOrder, EBonusItems.RETAIL_RANGE_INCOME.getValue());
        baseMapper.mergeBackRangeBonusIncome(pkOrder, EBonusItems.RETAIL_SAME_LEVEL_INCOME.getValue());
        baseMapper.mergeBackRangeBonusIncome(pkOrder, EBonusItems.RETAIL_AREA_INCOME.getValue());
        baseMapper.mergeBackRangeBonusIncome(pkOrder, EBonusItems.REPURCHASE_RANGE_INCOME.getValue());
    }

    @Override
    public void recalculateTeamNewBoxNum(List<Long> pkIdList) {
        String retailsTableName = getDayTableName();
        log.info("recalculateTeamNewBoxNum: pkIdList: {}, tableName: {}", JSONUtil.toJsonStr(pkIdList), retailsTableName);
        for (Long pkId : pkIdList) {
            baseMapper.recalculateTeamNewBoxNum(pkId, retailsTableName);
        }
    }

    private String getDayTableName() {
        String localDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(localDate).getPkId();
        return TableNameConstants.CU_MEMBER_RETAIL_S + period;
    }
}
