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

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.common.core.constant.BonusFieldConstants;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.enums.EBonusIncomeStatus;
import com.hzs.common.core.enums.EBonusItems;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.domain.bonus.BdBonusDeduct;
import com.hzs.common.domain.member.bonus.CuMemberBonus;
import com.hzs.common.domain.member.bonus.CuMemberBonusDetail;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.system.config.BdStoreLevelDetail;
import com.hzs.common.domain.system.config.ext.BdStoreLevelExt;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.dto.BonusConfigDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

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

/**
 * @description: 计算店铺奖金
 * @author: sui q
 * @time: 2023/5/8 15:40
 * @classname: BonusStoreHandle
 * @package_name: com.hzs.member.bonus.service.impl
 * version 1.0.0
 */
@Component
public class BonusSettleStoreHandle extends BonusSettleHandle{

    @DubboReference
    private IGradeServiceApi gradeServiceApi;

    /**
     * @param period            期间
     * @param bonusConfigDTO    参数
     * @param cuMemberBonusMap  所有计算出来的奖金汇总
     * @Description: 计算嗨粉奖金
     * @return: void
     * @Author: sui q
     * @Date: 2022/11/10 14:17
     */
    List<CuMemberBonusDetail> calculateStoreBonus(String settleDateStr, BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        // 云代区域 月奖
        // 查询时间范围内订单
        Date settleDate = DateUtils.parseStringToDate(settleDateStr);
        // 上个月最后一天
        settleDate = DateUtils.beforeMonthLastDate(settleDate);
        // 结算月第一天
        Date currentMonthFirstDate = DateUtils.currentMonthFirstDate(settleDate);
        // 结算月下月第一天
        Date nextMonthFirstDate = DateUtils.afterDate(1, ChronoUnit.DAYS, settleDate);
        // 查询月末会员状态
        Date currentMonthLastDate = DateUtils.currentMonthLastDate(settleDate);
        Integer lastPeriod = getCuMemberSettlePeriodService().getCuMemberSettlePeriodByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentMonthLastDate)).getPkId();
        String currentSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + lastPeriod;
        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        List<SaOrderExt> currentMonthOrderList = saOrderServiceApi.querySaOrderByTimeForStore(currentMonthFirstDate, nextMonthFirstDate).getData();
        if(CollectionUtil.isNotEmpty(currentMonthOrderList)){
            // 查询店铺奖金配置表
            Set<Long> pkMemberSet = currentMonthOrderList.stream().distinct().map(SaOrder::getPkMember).collect(Collectors.toSet());
            List<CuMemberSettleExt> cuMemberSettleExtList = cuMemberTreeService.batchQueryMemberSettleByMemberPk(currentSettleTableName, pkMemberSet);
            Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
            getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
            List<BdStoreLevelExt> storeLevelList = gradeServiceApi.queryStoreLevel().getData();
            Map<String, BdStoreLevelExt> storeLevelExtMap = new HashMap<>(ComputeUtil.mapInitCapacity(storeLevelList.size()));
            if(CollectionUtil.isNotEmpty(storeLevelList)){
                for (BdStoreLevelExt bdStoreLevel : storeLevelList) {
                    storeLevelExtMap.put(bdStoreLevel.getPkId().toString() + bdStoreLevel.getPkCreator().toString(), bdStoreLevel);
                }
            }
            for (SaOrderExt saOrderExt : currentMonthOrderList) {
                String key = saOrderExt.getPkMemberStore().toString() + saOrderExt.getPkCountry().toString();
                if(storeLevelExtMap.containsKey(key)){
                    BdStoreLevelExt bdStoreLevelExt = storeLevelExtMap.get(key);
                    for (BdStoreLevelDetail bdStoreLevelDetail : bdStoreLevelExt.getStoreLevelDetailList()) {
                        if(ComputeUtil.compareValue(saOrderExt.getOrderAchieve(), bdStoreLevelDetail.getEndAchievement())){
                            CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(saOrderExt.getPkMember());
                            CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrderExt, targetMemberSettleExt);
                            CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrderExt, targetMemberSettleExt, cuMemberBonus);
                            // 计算比例
                            cuMemberBonusDetail.setCalValue(bdStoreLevelDetail.getRatio());
                            cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.STORE_INCOME.getValue()));
                            cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrderExt.getOrderAchieve(), bdStoreLevelDetail.getRatio()));
                            storeRemark(cuMemberBonusDetail, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentMonthLastDate));
                            cuMemberBonusDetailList.add(cuMemberBonusDetail);
                            BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrderExt.getOrderAmount(), saOrderExt.getInExchangeRate());
                            if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                                cuMemberBonus.setStoreIncome(cuMemberBonusDetail.getPretaxIncome());
                                setBonusDeduct(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
                                BigDecimal realIncome = ReflectUtils.invokeGetter(cuMemberBonusDetail, BonusFieldConstants.REAL_INCOME);
                                cuMemberBonus.setRealIncomeTotal(ComputeUtil.computeAdd(cuMemberBonus.getRealIncomeTotal(), realIncome));
                            }
                            break;
                        }
                    }
                }
            }
        }
        return cuMemberBonusDetailList;

    }
}
