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

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.bonus.achieve.service.ICuMemberRetailRangeService;
import com.hzs.bonus.achieve.service.ICuMemberTreeService;
import com.hzs.bonus.achieve.service.impl.CuMemberBonusSettle;
import com.hzs.bonus.detail.service.ICuMemberAwardsService;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.ComputeUtil;
import com.hzs.common.domain.member.achieve.ext.CuMemberRetailRangeExt;
import com.hzs.common.domain.member.detail.CuMemberAwards;
import com.hzs.bonus.base.service.ICuMemberService;
import com.hzs.bonus.detail.mapper.CuMemberAwardsMapper;
import com.hzs.common.domain.system.config.BdAwards;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 会员信息-奖衔升级记录 服务实现类
 */
@Service
public class CuMemberAwardsServiceImpl extends ServiceImpl<CuMemberAwardsMapper, CuMemberAwards> implements ICuMemberAwardsService {

    @Autowired
    private ICuMemberService iCuMemberService;
    @Autowired
    private ICuMemberTreeService iCuMemberTreeService;
    @Autowired
    private CuMemberBonusSettle cuMemberBonusSettle;
    @Autowired
    private ICuMemberRetailRangeService iCuMemberRetailRangeService;

    @Override
    public void calculateCuMemberAwards(String rangeTableName, List<BdAwards> awardsList, Date settleDate, Integer period) {
        // 回退结算表奖衔
        iCuMemberTreeService.updateBackCuMemberRetailRangeAward(rangeTableName, period);
        // 回退会员表奖衔
        iCuMemberService.updateBackCuMemberRetailRangeAward(period);
        // 删除会员奖衔升级记录
        baseMapper.deleteCuMemberAwards(period);

        // 更新手动设置奖衔，一种有效期前的，一种有效期到达的
        // 有效期前的奖衔小于手动的，修改奖衔，
        iCuMemberTreeService.updateCuMemberRetailRangeAwardByDate(rangeTableName, settleDate);
        iCuMemberService.updateCuMemberRetailRangeAwardByDate(settleDate);

        // 会员升级记录
        List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();
        // 校验大小区会员数据（key:会员ID，value:会员推荐人列表）
        Map<Long, List<CuMemberRetailRangeExt>> cuMemberRangeExtMap = new HashMap<>();

        for (BdAwards bdAwards : awardsList) {
            List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList;
            if (bdAwards.getPlaceDeptNum() > 0) {
                BdAwards checkAwards = awardsList.stream().filter(tmpDate -> tmpDate.getPkId().equals(bdAwards.getPkCheckAwardsLeft())).findFirst().get();
                cuMemberRetailRangeExtList = iCuMemberRetailRangeService.queryEnoughAwardPlaceMember(rangeTableName, bdAwards.getAwardsValue(),
                        bdAwards.getTotalCheck(), bdAwards.getPlaceDeptNum(), checkAwards.getAwardsValue());
            } else {
                cuMemberRetailRangeExtList = iCuMemberRetailRangeService.queryEnoughAwardMember(rangeTableName, bdAwards.getTotalCheck(), bdAwards.getAwardsValue());
            }
            cuMemberAwardsList.addAll(this.calculateAwards(rangeTableName, bdAwards, period, cuMemberRetailRangeExtList, cuMemberRangeExtMap));
        }
        if (cuMemberAwardsList.size() > 0) {
            // 插入会员升级记录表
            this.saveBatchCuMemberAwards(cuMemberAwardsList);
            // 更新会员表奖衔数据
            iCuMemberService.updateCuMemberAwardsByPeriod(period);
            // 更新结算网体表 -- 结算日期到当前日期的所有日结算表
            iCuMemberRetailRangeService.updateCuMemberAwardsByPeriod(rangeTableName, period);
        }
    }

    private List<CuMemberAwards> calculateAwards(String rangeTableName, BdAwards bdAwards, Integer period,
                                                 List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList, Map<Long, List<CuMemberRetailRangeExt>> cuMemberRangeExtMap) {
        // 只满足业绩的
        List<CuMemberAwards> cuMemberAwardsList = new ArrayList<>();

        if (cuMemberRetailRangeExtList.size() > 0) {
            Date nowDate = new Date();

            cuMemberRetailRangeExtList.forEach(targetMember -> {
                if (bdAwards.getPlaceDeptNum() > 0 && bdAwards.getCommunityCheck().compareTo(BigDecimal.ZERO) == 0) {
                    // 需要校验部门奖衔并且小区业绩为0的
                    cuMemberAwardsList.add(getCuMemberRetailAwards(targetMember, period, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMember.getPkAwards(), nowDate));
                    targetMember.setPkAwards(bdAwards.getPkId());
                    targetMember.setAwardsValue(bdAwards.getAwardsValue());
                } else {
                    List<CuMemberRetailRangeExt> cuMemberRangeExtList = cuMemberRangeExtMap.get(targetMember.getPkMember());
                    if (null == cuMemberRangeExtList) {
                        cuMemberRangeExtList = iCuMemberRetailRangeService.queryCuMemberRetailRangeExtByParent(rangeTableName, targetMember.getPkMember());
                        cuMemberRangeExtMap.put(targetMember.getPkMember(), cuMemberRangeExtList);
                    }
                    // 大区
                    BigDecimal consumeBigPv = BigDecimal.ZERO;
                    for (CuMemberRetailRangeExt cuMemberRetailRangeExt : cuMemberRangeExtList) {
                        // 累计业绩 = 团队累计消费业绩 + 个人累计消费业绩
                        BigDecimal consumePv = cuMemberRetailRangeExt.getTeamConsumePv().add(cuMemberRetailRangeExt.getConsumePv());
                        if (ComputeUtil.compareGreaterThan(consumePv, consumeBigPv)) {
                            // 累计业绩 > 大区业绩，则累计就成为大区
                            consumeBigPv = consumePv;
                        }
                    }
                    // 小区业绩 = 团队累计业绩 - 大区业绩
                    BigDecimal smallAreaPv = ComputeUtil.computeSubtract(targetMember.getTeamConsumePv(), consumeBigPv);
                    if (smallAreaPv.compareTo(bdAwards.getCommunityCheck()) >= 0) {
                        // 小区业绩 >= 考核小区业绩
                        if (bdAwards.getPlaceDeptNum() > 0) {
                            if (CollectionUtil.isNotEmpty(cuMemberRangeExtList)) {
                                // 验证每条血缘下，满足达标数量
                                List<Integer> checkList = iCuMemberRetailRangeService.listChildAwards(rangeTableName, bdAwards.getPkCheckAwardsLeft(),
                                        Collections.singletonList(targetMember.getPkMember()));
                                if (CollectionUtil.isNotEmpty(checkList) && checkList.size() >= bdAwards.getPlaceDeptNum()) {
                                    cuMemberAwardsList.add(getCuMemberRetailAwards(targetMember, period, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMember.getPkAwards(), nowDate));
                                    targetMember.setPkAwards(bdAwards.getPkId());
                                    targetMember.setAwardsValue(bdAwards.getAwardsValue());
                                }
                            }
                        } else {
                            // 不需要考核血缘达标，直接给奖衔
                            cuMemberAwardsList.add(getCuMemberRetailAwards(targetMember, period, bdAwards, EAwardsType.RANGE_TYPE.getValue(), targetMember.getPkAwards(), nowDate));
                            targetMember.setPkAwards(bdAwards.getPkId());
                            targetMember.setAwardsValue(bdAwards.getAwardsValue());
                        }
                    }
                }
            });
        }
        return cuMemberAwardsList;
    }

    private CuMemberAwards getCuMemberRetailAwards(CuMemberRetailRangeExt sourceRangeExt, Integer period, BdAwards bdAwards,
                                                   Integer awardType, Integer oldLevel, Date nowDate) {
        CuMemberAwards cuMemberAwards = CuMemberAwards.builder()
                .pkMember(sourceRangeExt.getPkMember())
                .period(period)
                .upType(EUpgradeType.AUTO_UPGRADE.getValue())
                .awardType(awardType)
                .oldLevel(null == oldLevel ? sourceRangeExt.getPkAwards() : oldLevel)
                .newLevel(bdAwards.getPkId())
                .purchaseStatus(EYesNo.NO.getIntValue())
                .build();
        cuMemberAwards.setPkCreator(MagicNumberConstants.PK_ADMIN);
        cuMemberAwards.setPkCountry(sourceRangeExt.getPkCountry());
        cuMemberAwards.setCreationTime(nowDate);
        return cuMemberAwards;
    }

    @Override
    public void saveBatchCuMemberAwards(List<CuMemberAwards> cuMemberAwardsList) {
        List<List<?>> cutOrderList = cuMemberBonusSettle.handleCutList(cuMemberAwardsList, MagicNumberConstants.BATCH_UPDATE_NUM);
        cutOrderList.forEach(orderList ->
                baseMapper.saveBatchCuMemberAwards(orderList));
    }

    @Override
    public void deleteCuMemberAwards(List<CuMemberAwards> cuMemberAwards, Integer period) {
        baseMapper.deleteCuMemberAwardsByList(cuMemberAwards, period);
    }

    @Override
    public List<CuMemberAwards> queryCuMemberAwards(List<CuMemberRetailRangeExt> cuMemberRetailRangeExtList, Integer period) {
        return baseMapper.queryCuMemberAwards(cuMemberRetailRangeExtList, period);
    }

    @Override
    public void mergeCuMemberBackAwards(String rangeTableName, Long pkMember, Integer period) {
        baseMapper.mergeCuMemberBackAwards(rangeTableName, pkMember, period, EAwardsType.RANGE_TYPE.getValue());
    }

}
