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

import cn.hutool.core.bean.BeanUtil;
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.service.IBonusSettleService;
import com.hzs.bonus.bonus.service.ICuMemberBonusService;
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.utils.StringUtils;
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.sale.ext.SaOrderExt;
import com.hzs.common.domain.system.config.BdBonusItems;
import com.hzs.common.domain.system.config.ext.BdBonusItemsExt;
import com.hzs.bonus.bonus.param.BonusParam;
import com.hzs.bonus.bonus.vo.MemberBonusDetailSerVO;
import com.hzs.bonus.bonus.vo.MemberBonusDetailVO;
import com.hzs.bonus.bonus.vo.MemberBonusVO;
import com.hzs.sale.order.ISaOrderServiceApi;
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.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

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

    @DubboReference
    ISystemConfigServiceApi systemConfigServiceApi;
    @DubboReference
    ISaOrderServiceApi saOrderServiceApi;
    @DubboReference
    ICurrencyServiceApi currencyServiceApi;
    @DubboReference
    IBonusItemsServiceApi bonusItemsServiceApi;

    @Autowired
    private ICuMemberSettlePeriodService cuMemberSettlePeriodService;

    private CuMemberBonusDetailMapper cuMemberBonusDetailMapper;

    private CuMemberBonusPushMapper cuMemberBonusPushMapper;

    private CuMemberBonusExpandMapper cuMemberBonusExpandMapper;

    private CuMemberBonusCoachMapper cuMemberBonusCoachMapper;

    private CuMemberBonusRangeMapper cuMemberBonusRangeMapper;

    private CuMemberBonusPointMapper cuMemberBonusPointMapper;

    private CuMemberBonusSettle cuMemberBonusSettle;

    private ICuMemberTreeService cuMemberTreeService;

    private IBonusSettleService bonusSettleService;

    @Autowired
    public void setCuMemberBonusPointMapper(CuMemberBonusPointMapper cuMemberBonusPointMapper) {
        this.cuMemberBonusPointMapper = cuMemberBonusPointMapper;
    }

    @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<MemberBonusVO> queryMemberBonusTotalVoByCondition(BonusParam bonusParam) {
        List<MemberBonusVO> memberBonusVoList = new ArrayList<>();
        List<CuMemberBonus> cuMemberBonusList = baseMapper.queryMemberBonusTotalByCondition(bonusParam);
        cuMemberBonusList.forEach(cuMemberBonus -> {
            MemberBonusVO memberBonusVO = BeanUtil.copyProperties(cuMemberBonus, MemberBonusVO.class);
            memberBonusVoList.add(memberBonusVO);
        });
        return memberBonusVoList;
    }


    @Override
    public List<CuMemberBonusExt> queryMemberBonusVoByCondition(BonusParam bonusParam) {
        String value = systemConfigServiceApi.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, value), bonusParam, value);
    }

    private List<CuMemberBonusExt> handleMemberBonusPurchase(List<CuMemberBonusExt> cuMemberBonusExtList, BonusParam bonusParam, String value) {
        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 startDate = DateUtils.beforeDate(cuMemberBonusExtList.size(), ChronoUnit.DAYS, bonusParam.getEndDate());
//        if(bonusParam.getStartDate() == null || DateUtils.compareDateBefore(startDate, bonusParam.getStartDate())){
//            bonusParam.setStartDate(startDate);
//        }
        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.setSeePointIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setStoreIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setStoreRangeIncome(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.setRepurRangeIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setSameLevelIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setPointShareIncome(BigDecimal.ZERO);
                    cuMemberBonusExt.setRepurRealSubtotal(BigDecimal.ZERO);
                    cuMemberBonusExt.setGlobalPoints(BigDecimal.ZERO);
                    cuMemberBonusExt.setRealIncomeTotal(BigDecimal.ZERO);
                    memberBonusExtList.add(cuMemberBonusExt);
                }
            }
            endDate = DateUtils.beforeDate(1, ChronoUnit.DAYS, endDate);
        }
        return memberBonusExtList;
    }

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

    private List<CuMemberBonusExt> getCuMemberBonusExtList(BonusParam bonusParam, String value) {
        if (bonusParam.getGrantStatus() == null) {
            bonusParam.setGrantStatus(EGrantStatus.PUBLISHED.getValue());
        }
        List<CuMemberBonusExt> cuMemberBonusExtList = baseMapper.queryMemberBonusByCondition(bonusParam);
        R<CurrencyDTO> currency = currencyServiceApi.getCurrency(bonusParam.getPkCountry());
        // 汇率比例
        BigDecimal inExchangeRate = currency.getData().getInExchangeRate();
        for (CuMemberBonusExt cuMemberBonusExt : cuMemberBonusExtList) {
            cuMemberBonusExt.setDirectIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getDirectIncome(), inExchangeRate));
            cuMemberBonusExt.setSeePointIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getSeePointIncome(), inExchangeRate));
            cuMemberBonusExt.setStoreIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getStoreIncome(), inExchangeRate));
            cuMemberBonusExt.setStoreRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getStoreRangeIncome(), 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.setRepurRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurRangeIncome(), inExchangeRate));
            cuMemberBonusExt.setSameLevelIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getSameLevelIncome(), inExchangeRate));
            cuMemberBonusExt.setPointShareIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getPointShareIncome(), inExchangeRate));
            cuMemberBonusExt.setRepurRealSubtotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRepurRealSubtotal(), inExchangeRate));
            cuMemberBonusExt.setGlobalPoints(ComputeUtil.computeMultiply(cuMemberBonusExt.getGlobalPoints(), inExchangeRate));
            cuMemberBonusExt.setRealIncomeTotal(ComputeUtil.computeMultiply(cuMemberBonusExt.getRealIncomeTotal(), inExchangeRate));
        }
        if (StringUtils.isNotEmpty(value) && Objects.equals(Integer.toString(EExpandCapMethod.WEEK_SETTLE.getValue()), value)) {
            Map<String, List<CuMemberBonusExt>> weekDateMap = new TreeMap<>();
            // 计算周开始和结束
            for (CuMemberBonusExt cuMemberBonusExt : cuMemberBonusExtList) {
                String startDateStr = DateUtils.getRecentlyTuesday(cuMemberBonusExt.getSettleDate());
                if (weekDateMap.containsKey(startDateStr)) {
                    weekDateMap.get(startDateStr).add(cuMemberBonusExt);
                } else {
                    List<CuMemberBonusExt> cuMemberBonusExtList1 = new ArrayList<>();
                    cuMemberBonusExtList1.add(cuMemberBonusExt);
                    weekDateMap.put(startDateStr, cuMemberBonusExtList1);
                }
            }
            List<CuMemberBonusExt> cuMemberBonusExtList1 = new ArrayList<>();
            for (String key : weekDateMap.keySet()) {
                CuMemberBonusExt cuMemberBonusExt = initCuMemberBonus();
                cuMemberBonusExt.setSettleDate(DateUtils.parseStringToDate(key));
                cuMemberBonusExt.setEndSettleDate(DateUtils.afterDate(6, ChronoUnit.DAYS, cuMemberBonusExt.getSettleDate()));
                for (CuMemberBonusExt memberBonusExt : weekDateMap.get(key)) {
                    calculateBonusTotal(cuMemberBonusExt, memberBonusExt);
                }
                cuMemberBonusExtList1.add(cuMemberBonusExt);
            }
            return cuMemberBonusExtList1;
        }
        return cuMemberBonusExtList;
    }

    @Override
    public void calculateBonusTotal(CuMemberBonusExt cuMemberBonusExt, CuMemberBonusExt memberBonusExt) {
        cuMemberBonusExt.setDirectIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getDirectIncome(), memberBonusExt.getDirectIncome()));
        cuMemberBonusExt.setSeePointIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getSeePointIncome(), memberBonusExt.getSeePointIncome()));
        cuMemberBonusExt.setStoreIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getStoreIncome(), memberBonusExt.getStoreIncome()));
        cuMemberBonusExt.setStoreRangeIncome(ComputeUtil.computeMultiply(cuMemberBonusExt.getStoreRangeIncome(), memberBonusExt.getStoreRangeIncome()));
        cuMemberBonusExt.setExpandIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getExpandIncome(), memberBonusExt.getExpandIncome()));
        cuMemberBonusExt.setCoachIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getCoachIncome(), memberBonusExt.getCoachIncome()));
        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.setRepurRangeIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurRangeIncome(), memberBonusExt.getRepurRangeIncome()));
        cuMemberBonusExt.setSameLevelIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getSameLevelIncome(), memberBonusExt.getSameLevelIncome()));
        cuMemberBonusExt.setPointShareIncome(ComputeUtil.computeAdd(cuMemberBonusExt.getPointShareIncome(), memberBonusExt.getPointShareIncome()));
        cuMemberBonusExt.setRepurRealSubtotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRepurRealSubtotal(), memberBonusExt.getRepurRealSubtotal()));
        cuMemberBonusExt.setGlobalPoints(ComputeUtil.computeAdd(cuMemberBonusExt.getGlobalPoints(), memberBonusExt.getGlobalPoints()));
        cuMemberBonusExt.setRealIncomeTotal(ComputeUtil.computeAdd(cuMemberBonusExt.getRealIncomeTotal(), memberBonusExt.getRealIncomeTotal()));
    }

    @Override
    public List<CuMemberBonusExt> queryMemberBonusTotalByCondition(BonusParam bonusParam) {
        String value = systemConfigServiceApi.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())));
            bonusParam.setStartDate(DateUtils.beforeDate(7, ChronoUnit.DAYS, bonusParam.getEndDate()));
        }
        return getCuMemberBonusExtList(bonusParam, value);
    }

    @Override
    public CuMemberBonusExt initCuMemberBonus() {
        CuMemberBonusExt cuMemberBonusExt = new CuMemberBonusExt();
        cuMemberBonusExt.setDirectIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setSeePointIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setStoreIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setExpandIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setExpandNoCapping(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.setRepurRangeIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setSameLevelIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setPointShareIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setRepurRealSubtotal(BigDecimal.ZERO);
        cuMemberBonusExt.setStoreIncome(BigDecimal.ZERO);
        cuMemberBonusExt.setGlobalPoints(BigDecimal.ZERO);
        cuMemberBonusExt.setRealIncomeTotal(BigDecimal.ZERO);
        cuMemberBonusExt.setStoreRangeIncome(BigDecimal.ZERO);
        return cuMemberBonusExt;
    }

    @Override
    public Map<Long, CuMemberBonus> queryWeekMemberBonus(int startPeriod, int endPeriod) {
        List<CuMemberBonus> cuMemberBonusList = baseMapper.queryWeekMemberBonus(startPeriod, endPeriod);
        Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>(ComputeUtil.mapInitCapacity(cuMemberBonusList.size()));
        cuMemberBonusList.forEach(cuMemberBonus -> cuMemberBonusMap.put(cuMemberBonus.getPkMember(), cuMemberBonus));
        return cuMemberBonusMap;
    }

    @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 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 = bonusItemsServiceApi.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);
                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);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.EXPANSION_INCOME.getValue() == bonusItemsValue) {
            // 拓展收益、复购拓展收益
            List<CuMemberBonusExpandExt> cuMemberBonusExpandList = cuMemberBonusExpandMapper.queryMemberBonusExpandByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusExpandList);
            cuMemberBonusExpandList.forEach(cuMemberBonusExpand -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusExpand, MemberBonusDetailVO.class);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.COACHING_INCOME.getValue() == bonusItemsValue || EBonusItems.SEE_POINT_INCOME.getValue() == bonusItemsValue) {
            // 辅导收益
            // 拓展收益、复购拓展收益
            List<CuMemberBonusCoachExt> cuMemberBonusCoachList = cuMemberBonusCoachMapper.queryMemberBonusCoachByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusCoachList);
            cuMemberBonusCoachList.forEach(cuMemberBonusCoach -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusCoach, MemberBonusDetailVO.class);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.RESALE_RANGE_INCOME.getValue() == bonusItemsValue || EBonusItems.RESALE_SAME_LEVEL_INCOME.getValue() == bonusItemsValue) {
            // 复购极差
            // 拓展收益、复购拓展收益
            List<CuMemberBonusRangeExt> cuMemberBonusRangeList = cuMemberBonusRangeMapper.queryMemberBonusRangeByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusRangeList);
            cuMemberBonusRangeList.forEach(cuMemberBonusRange -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusRange, MemberBonusDetailVO.class);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else if (EBonusItems.POINT_SHARE_INCOME.getValue() == bonusItemsValue) {
            // 加权积分 加权积分收益
            List<CuMemberBonusPointExt> cuMemberBonusPointList = cuMemberBonusPointMapper.queryMemberBonusPointByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusPointList);
            cuMemberBonusPointList.forEach(cuMemberBonusPoint -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusPoint, MemberBonusDetailVO.class);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        } else {
            // 其他收益 服务补贴、分红收益、嗨粉直推
            // 拓展收益、复购拓展收益
            List<CuMemberBonusDetailExt> cuMemberBonusDetailList = cuMemberBonusDetailMapper.queryMemberBonusDetailByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusDetailList);
            cuMemberBonusDetailList.forEach(cuMemberBonusDetail -> {
                MemberBonusDetailVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusDetail, MemberBonusDetailVO.class);
                memberBonusDetailVOList.add(memberBonusDetailVO);
            });
        }
        Map<Integer, BdBonusItemsExt> bonusItemsMap = convertBonusItems(bonusParam);
        CurrencyDTO currencyDTO = currencyServiceApi.getCurrency(bonusParam.getPkCountry()).getData();
        memberBonusDetailVOList.forEach(memberBonusDetailVO -> {
            if (bonusItemsMap.containsKey(memberBonusDetailVO.getPkBonusItems())) {
                memberBonusDetailVO.setBonusName(bonusItemsMap.get(memberBonusDetailVO.getPkBonusItems()).getBonusName());
                memberBonusDetailVO.setBonusTransaction(bonusItemsMap.get(memberBonusDetailVO.getPkBonusItems()).getPkTransaction());
            }
            // 转换汇率
            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 = bonusItemsServiceApi.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 = bonusItemsServiceApi.queryBonusItems(bonusParam.getPkCountry(), bonusParam.getPkBonusItems()).getData();
            bonusItemsValue = bonusItems.getBonusValue();
            bonusParam.setBonusValue(bonusItemsValue);
        }
        if (bonusParam.getEndDate() != null) {
            bonusParam.setEndDate(DateUtils.afterDate(1, ChronoUnit.DAYS, bonusParam.getEndDate()));
        }
        Map<Integer, BdBonusItemsExt> bonusItemsMap = convertBonusItems(bonusParam);

        // 2024.04.28 与业务沟通，海外都是跨国交叉，奖金明细查询时，不区分国家直接显示全部
        bonusParam.setPkCountry(null);
        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) {
            // 拓展收益、复购拓展收益
            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.COACHING_INCOME.getValue() == bonusItemsValue || EBonusItems.SEE_POINT_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.RESALE_RANGE_INCOME.getValue() == bonusItemsValue || EBonusItems.RESALE_SAME_LEVEL_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 if (EBonusItems.POINT_SHARE_INCOME.getValue() == bonusItemsValue) {
            // 加权积分 加权积分收益
            List<CuMemberBonusPointExt> cuMemberBonusPointList = cuMemberBonusPointMapper.queryMemberBonusPointByBonusItems(bonusParam);
            dataTable = getDataTable(cuMemberBonusPointList);
            cuMemberBonusPointList.forEach(cuMemberBonusPoint -> {
                MemberBonusDetailSerVO memberBonusDetailVO = BeanUtil.copyProperties(cuMemberBonusPoint, 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);
            });
        }

        memberBonusDetailSerVoS.forEach(memberBonusDetailSerVO -> {
            if (bonusItemsMap.containsKey(memberBonusDetailSerVO.getPkBonusItems())) {
                memberBonusDetailSerVO.setBonusName(bonusItemsMap.get(memberBonusDetailSerVO.getPkBonusItems()).getBonusName());
            }
            memberBonusDetailSerVO.setOrderAmountDollar(ComputeUtil.computeDivide(memberBonusDetailSerVO.getOrderAmount(), memberBonusDetailSerVO.getOutExchangeRate()));
            memberBonusDetailSerVO.setOrderAchieveOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getOrderAchieve(), memberBonusDetailSerVO.getOutExchangeRate()));
            memberBonusDetailSerVO.setPretaxIncomeOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getPretaxIncome(), memberBonusDetailSerVO.getOutExchangeRate()));
            memberBonusDetailSerVO.setRealIncomeOri(ComputeUtil.computeMultiply(memberBonusDetailSerVO.getRealIncome(), memberBonusDetailSerVO.getOutExchangeRate()));
            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()));
            }
        });
        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 List<CuMemberBonus> queryExistsPurchaseBonusMember(Integer period, List<Integer> pkCountryList) {
        QueryWrapper<CuMemberBonus> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("pk_member,pk_country,direct_income,expand_income,coach_income,share_income,pur_real_subtotal");
        queryWrapper.eq(MemberFieldConstants.PERIOD, period);
        queryWrapper.in(SystemFieldConstants.PK_COUNTRY, pkCountryList);
        queryWrapper.gt("PUR_REAL_SUBTOTAL", 0);
        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(see_point_income) see_point_income,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(same_level_income) same_level_income," +
                "sum(repur_real_subtotal) repur_real_subtotal," +
                "sum(global_points) global_points," +
                "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);
        Date settleEndDate = DateUtils.afterDate(1, ChronoUnit.DAYS, startDate);
        if (DateUtils.compareDateBefore(startDate, DateUtils.parseStringToDate("2023-12-04"))) {
            return Boolean.TRUE;
        }
//        CuMemberSettlePeriod cuMemberSettlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate);
//        CuMemberSettlePeriodExt cuMemberSettlePeriodExt = cuMemberSettlePeriodService.getCuMemberSettlePeriod(CountryConstants.TOGO_COUNTRY, DateUtils.parseStringToDate(settleDate));
//        if(!cuMemberSettlePeriod.getPkId().equals(cuMemberSettlePeriodExt.getEndPeriod())){
//            return Boolean.TRUE;
//        }
//        startDate = DateUtils.beforeDate(6, ChronoUnit.DAYS, startDate);
        // 自动初始化表
        cuMemberTreeService.createCuMemberTree(settleDate);
        log.info("初始化表完成");
        // 奖金结算
        List<SaOrderExt> saOrderExtList = saOrderServiceApi.querySaOrderByDay(startDate, settleEndDate).getData();
        // 60天前买的订单，用于积分加权
        List<SaOrderExt> buySaOrderExtList = saOrderServiceApi.querySaOrderByEffectiveDay(startDate, settleEndDate).getData();
        // 确认收获的订单，用于店铺收益
        List<SaOrderExt> storeSaOrderExtList = null;
        if (settleDate.endsWith("10")) {
            settleEndDate = DateUtils.currentMonthFirstDate(startDate);
            storeSaOrderExtList = saOrderServiceApi.queryDeliverySaOrderByDay(DateUtils.beforeMonthFirstDate(startDate), settleEndDate).getData();
        }
        bonusSettleService.calculateCuMemberBonus(settleDate, saOrderExtList, buySaOrderExtList, storeSaOrderExtList);
        return Boolean.TRUE;
    }

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

}
