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

import cn.hutool.core.collection.CollectionUtil;
import com.hzs.activity.base.IActivityServiceApi;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.constant.msg.BonusMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.activity.recommend.AcRepurSharOrderType;
import com.hzs.common.domain.activity.recommend.ext.AcRepurSharRuleConfigExt;
import com.hzs.common.domain.bonus.BdBonusDeduct;
import com.hzs.common.domain.member.base.CuMemberAgent;
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.order.SaOrder;
import com.hzs.common.domain.system.config.BdBonusCloud;
import com.hzs.bonus.base.service.ICuMemberAgentService;
import com.hzs.system.config.dto.BonusConfigDTO;
import com.hzs.system.sys.dto.BdCurrencyDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @Description:
 * @Author: sui q
 * @Time: 2023/1/4 17:19
 * @Classname: BonusSettleAgentHandle
 * @PackageName: com.hzs.member.bonus.service.impl
 */
@Component
public class BonusSettleAgentHandle extends BonusSettleHandle {

    @DubboReference
    IActivityServiceApi iActivityServiceApi;

    // 代理直推 推荐给多少钱 代理复购 区域 所有订单的1%
    @Autowired
    private ICuMemberAgentService iCuMemberAgentService;

    /**
     * 计算嗨粉奖金
     *
     * @param period           期间
     * @param bonusConfigDTO   参数
     * @param cuMemberBonusMap 所有计算出来的奖金汇总
     */
    List<CuMemberBonusDetail> calculateCloudAgentAreaBonus(String settleDateStr, BonusConfigDTO bonusConfigDTO, Integer period, Map<Long, CuMemberBonus> cuMemberBonusMap) {
        List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
        // 云代区域 月奖
        // 查询时间范围内订单
        Date settleDate = DateUtils.parseStringToDate(settleDateStr);
        // 上个月最后一天
        settleDate = DateUtils.beforeMonthLastDate(settleDate);
        // 结算月第一天
        Date currentMonthFirstDate = DateUtils.currentMonthFirstDate(settleDate);
        // 结算月下月第一天
        Date nextMonthFirstDate = DateUtils.afterDate(1, ChronoUnit.DAYS, settleDate);
        List<SaOrder> currentMonthOrderList = iSaOrderServiceApi.querySaOrderByDayForCloud(currentMonthFirstDate, nextMonthFirstDate).getData();
        // 查询月末会员状态
        Integer lastPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDateStr).getPkId();
        String currentSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + lastPeriod;
        Set<Long> pkMemberSet = new HashSet<>();
        // 获取配置
        Map<String, BdBonusCloud> bdBonusCloudMap = bonusConfigDTO.getBonusCloudMap();
        if (bdBonusCloudMap == null) {
            return cuMemberBonusDetailList;
        }
        // 计算奖金 云代首购 首购订单1%  云代复购 复购订单1%
        // 查询会员，查询出所有代理的会员
        Map<String, List<CuMemberAgent>> cuMemberAgentMap = iCuMemberAgentService.queryCuMemberAgent();
        List<SaOrder> saOrderList = new ArrayList<>();
        for (SaOrder saOrder : currentMonthOrderList) {
            if (saOrder.getPkCountry() == null || saOrder.getRecProvince() == null || saOrder.getRecCity() == null) {
                continue;
            }
            String key = saOrder.getPkCountry().toString() + saOrder.getRecProvince() + saOrder.getRecCity();
            if (!cuMemberAgentMap.containsKey(key)) {
                continue;
            } else {
                saOrderList.add(saOrder);
            }
            pkMemberSet.add(saOrder.getPkMember());
            List<CuMemberAgent> cuMemberAgentList = cuMemberAgentMap.get(key);
            cuMemberAgentList.forEach(cuMemberAgent ->
                    pkMemberSet.add(cuMemberAgent.getPkMember()));
        }
        List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.batchQueryMemberSettleByMemberPk(currentSettleTableName, pkMemberSet);
        Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
        getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
        Map<String, BdCurrencyDTO> currencyDtoMap = bonusConfigDTO.getCurrencyDtoMap();
        for (SaOrder saOrder : saOrderList) {
            String key = saOrder.getPkCountry().toString() + saOrder.getRecProvince().toString() + saOrder.getRecCity().toString();
            List<CuMemberAgent> cuMemberAgentList = cuMemberAgentMap.get(key);
            BigDecimal exchangeRate = BigDecimal.ONE;
            if (currencyDtoMap.containsKey(saOrder.getPkCountry().toString() + saOrder.getPkRate())) {
                exchangeRate = currencyDtoMap.get(saOrder.getPkCountry().toString() + saOrder.getPkRate()).getInExchangeRate();
            }
            // 云代首购
            CuMemberSettleExt sourceMemberSettleExt = cuMemberSettleExtMap.get(saOrder.getPkMember());
            if (sourceMemberSettleExt == null) {
                continue;
            }
            if (EOrderType.REGISTER_ORDER.getValue() == saOrder.getOrderType() ||
                    EOrderType.UPGRADE_ORDER.getValue() == saOrder.getOrderType() ||
                    Objects.equals(EOrderType.FICTITIOUS_ORDER.getValue(), saOrder.getOrderType()) ||
                    Objects.equals(EOrderType.SPECIAL_REGISTER_ORDER.getValue(), saOrder.getOrderType()) ||
                    Objects.equals(EOrderType.SPECIAL_UPGRADE_ORDER.getValue(), saOrder.getOrderType())) {
                BdBonusCloud bdBonusCloud = bdBonusCloudMap.get(saOrder.getPkCountry().toString() + ECloudType.CLOUD_TYPE_FIRST_PURCHASE.getValue());
                for (CuMemberAgent cuMemberAgent : cuMemberAgentList) {
                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberAgent.getPkMember());
                    if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                            EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus() ||
                            EGrade.START_UP.getValue() == targetMemberSettleExt.getGradeValue()) {
                        continue;
                    }
                    if (cuMemberAgent.getAgentGrade() == 7 && cuMemberAgent.getAgentCounty() != null && saOrder.getRecCounty() != null &&
                            !Objects.equals(cuMemberAgent.getAgentCounty(), saOrder.getRecCounty())) {
                        continue;
                    } else {
                        if (cuMemberAgent.getAgentGrade() == 8 && cuMemberAgent.getAgentCounty() != null &&
                                !Objects.equals(cuMemberAgent.getAgentCounty(), saOrder.getRecCounty())) {
                            continue;
                        }
                    }
                    CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
                    CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrder, targetMemberSettleExt, cuMemberBonus);
                    // 计算比例
                    cuMemberBonusDetail.setCalValue(bdBonusCloud.getCloudRatio());
                    cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.CLOUD_AGENT_FIRST_PURCHASE.getValue()));
                    cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrder.getOrderAchieve(), bdBonusCloud.getCloudRatio()));
                    cloudAgentRemark(saOrder, cuMemberBonusDetail, sourceMemberSettleExt, targetMemberSettleExt, BonusMsgConstants.CLOUD_AGENT_FIRST_REPURCHASE);
                    cuMemberBonusDetailList.add(cuMemberBonusDetail);
                    BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrder.getOrderAmount(), exchangeRate);
                    if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                        cuMemberBonus.setCloudPurIncome(ComputeUtil.computeAdd(cuMemberBonus.getCloudPurIncome(), cuMemberBonusDetail.getPretaxIncome()));
                        setCloudTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
                    }
                }
            } else {
                // 云代复购
                BdBonusCloud bdBonusCloud = bdBonusCloudMap.get(saOrder.getPkCountry().toString() + ECloudType.CLOUD_TYPE_PURCHASE.getValue());
                for (CuMemberAgent cuMemberAgent : cuMemberAgentList) {
                    CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberAgent.getPkMember());
                    if (targetMemberSettleExt == null || ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory() ||
                            EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus() ||
                            EGrade.START_UP.getValue() == targetMemberSettleExt.getGradeValue()) {
                        continue;
                    }
                    if (cuMemberAgent.getAgentGrade() == 7 && cuMemberAgent.getAgentCounty() != null && saOrder.getRecCounty() != null &&
                            !Objects.equals(cuMemberAgent.getAgentCounty(), saOrder.getRecCounty())) {
                        continue;
                    } else {
                        if (cuMemberAgent.getAgentGrade() == 8 && cuMemberAgent.getAgentCounty() != null &&
                                !Objects.equals(cuMemberAgent.getAgentCounty(), saOrder.getRecCounty())) {
                            continue;
                        }
                    }
                    CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
                    CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrder, targetMemberSettleExt, cuMemberBonus);
                    // 计算比例
                    cuMemberBonusDetail.setCalValue(bdBonusCloud.getCloudRatio());
                    cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.CLOUD_AGENT_REPURCHASE.getValue()));
                    cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrder.getOrderAchieve(), bdBonusCloud.getCloudRatio()));
                    cloudAgentRemark(saOrder, cuMemberBonusDetail, sourceMemberSettleExt, targetMemberSettleExt, BonusMsgConstants.CLOUD_AGENT_REPURCHASE);
                    cuMemberBonusDetailList.add(cuMemberBonusDetail);

                    BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrder.getOrderAmount(), exchangeRate);
                    if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                        cuMemberBonus.setCloudRepurIncome(ComputeUtil.computeAdd(cuMemberBonus.getCloudRepurIncome(), cuMemberBonusDetail.getPretaxIncome()));
                        setCloudTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
                    }
                }
            }
        }

        // 复购券均分收益规则
        List<AcRepurSharRuleConfigExt> repurSharRuleConfigExtList = iActivityServiceApi.queryRepurSharRuleConfig(currentMonthFirstDate, nextMonthFirstDate).getData();
        if (CollectionUtil.isNotEmpty(repurSharRuleConfigExtList)) {
            for (AcRepurSharRuleConfigExt acRepurSharRuleConfigExt : repurSharRuleConfigExtList) {
                List<Integer> orderTypeList = acRepurSharRuleConfigExt.getRepurSharOrderTypeList().stream().distinct().map(AcRepurSharOrderType::getOrderType).collect(Collectors.toList());
                List<SaOrder> orderList = iSaOrderServiceApi.querySaOrderByTimeForCouponShare(settleDate, nextMonthFirstDate, orderTypeList,
                        acRepurSharRuleConfigExt.getOrderAmount(), acRepurSharRuleConfigExt.getOrderAchieve(), acRepurSharRuleConfigExt.getPkCountry()).getData();
                if (CollectionUtil.isNotEmpty(orderList)) {
                    Set<Long> memberSet = orderList.stream().distinct().map(SaOrder::getPkMember).collect(Collectors.toSet());
                    cuMemberSettleExtList = iCuMemberTreeService.batchQueryMemberSettleByMemberPk(currentSettleTableName, memberSet);
                    getMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
                    for (SaOrder saOrder : orderList) {
                        BigDecimal exchangeRate = BigDecimal.ONE;
                        if (currencyDtoMap.containsKey(saOrder.getPkCountry().toString() + saOrder.getPkRate())) {
                            exchangeRate = currencyDtoMap.get(saOrder.getPkCountry().toString() + saOrder.getPkRate()).getInExchangeRate();
                        }
                        CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(saOrder.getPkMember());
                        CuMemberBonus cuMemberBonus = getCuMemberBonus(period, cuMemberBonusMap, saOrder, targetMemberSettleExt);
                        CuMemberBonusDetail cuMemberBonusDetail = getCuMemberBonusDetail(saOrder, targetMemberSettleExt, cuMemberBonus);
                        // 计算比例
                        cuMemberBonusDetail.setCalValue(acRepurSharRuleConfigExt.getRatioValue());
                        cuMemberBonusDetail.setPkBonusItems(getPkBonusItems(bonusConfigDTO, targetMemberSettleExt.getPkSettleCountry(), EBonusItems.REPURCHASE_COUPONS_SHARE.getValue()));
                        cuMemberBonusDetail.setPretaxIncome(ComputeUtil.computeBonusMultiply(saOrder.getOrderAchieve(), acRepurSharRuleConfigExt.getRatioValue()));
                        shareCouponRemark(cuMemberBonusDetail, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, settleDate));
                        cuMemberBonusDetailList.add(cuMemberBonusDetail);
                        BdBonusDeduct bdBonusDeduct = setBonusDetailDeduct(bonusConfigDTO, cuMemberBonusDetail, saOrder.getOrderAmount(), exchangeRate);
                        if (EBonusIncomeStatus.NORMAL.getValue() == cuMemberBonusDetail.getIncomeStatus()) {
                            cuMemberBonus.setRepurCouponShare(cuMemberBonusDetail.getPretaxIncome());
                            setRepurchaseCouponTotal(bdBonusDeduct, cuMemberBonus, cuMemberBonusDetail);
                        }
                    }
                }
            }
        }
        return cuMemberBonusDetailList;
    }
}
