package com.hzs.report.report.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.*;
import com.hzs.common.core.enums.EPlaceDept;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.member.achieve.CuMemberAchieve;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.ext.CuMemberSettleExt;
import com.hzs.report.member.service.IMemberService;
import com.hzs.report.report.mapper.ReportCuMemberAchieveMapper;
import com.hzs.report.report.service.*;
import com.hzs.report.report.vo.AchievementVO;
import com.hzs.report.report.vo.ReportCuMemberNewAddAchieveVO;
import com.hzs.report.report.vo.DeptMemberNumberVO;
import com.hzs.report.report.vo.ReportRecommendAchievementVo;
import com.hzs.system.base.dto.CurrencyDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 会员业绩记录 服务实现类
 *
 * @author hzs
 * @since 2022-10-26
 */
@Slf4j
@Service
public class ReportCuMemberAchieveServiceImpl extends ServiceImpl<ReportCuMemberAchieveMapper, CuMemberAchieve> implements IReportCuMemberAchieveService {

    @Autowired
    private ICuMemberBaseService iCuMemberBaseService;
    @Autowired
    private IMemberService iMemberService;
    @Autowired
    private IReportCuMemberSettlePeriodService iMemberSettlePeriodService;
    @Autowired
    private IReportCuMemberTreeService iMemberTreeService;

    @Override
    public List<ReportCuMemberNewAddAchieveVO> selectNewAddAchieveByDay(ReportCuMemberNewAddAchieveVO cuMemberNewAddAchieveVO) {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minus(cuMemberNewAddAchieveVO.getDays(), ChronoUnit.DAYS);
        return selectNewAddAchieveByDate(cuMemberNewAddAchieveVO, endDate, startDate);
    }

    /**
     * 根据日期查询会员的新增业绩
     *
     * @param cuMemberNewAddAchieveVO 入参
     * @param endDate                 结束时间
     * @param startDate               开始时间
     * @return List<CuMemberNewAddAchieveVO>
     */
    private List<ReportCuMemberNewAddAchieveVO> selectNewAddAchieveByDate(ReportCuMemberNewAddAchieveVO cuMemberNewAddAchieveVO, LocalDate endDate, LocalDate startDate) {
        String upAchieveTableName = null;
        BigDecimal rate = null;
        String startDateStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String endDateStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //当前月份第一天
        LocalDate firstMonthDay = endDate.with(TemporalAdjusters.firstDayOfMonth());
        //判断是否跨月
        if (!firstMonthDay.isEqual(LocalDate.now()) && startDate.isBefore(firstMonthDay)) {
            upAchieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(startDateStr);
        }
        String achieveTableName = TableNameConstants.CU_MEMBER_ACHIEVE + DateUtils.getMonth(LocalDate.now().minus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        cuMemberNewAddAchieveVO.setStartDate(startDateStr);
        cuMemberNewAddAchieveVO.setEndDate(endDateStr);
        cuMemberNewAddAchieveVO.setAchieveTableName(achieveTableName);
        cuMemberNewAddAchieveVO.setUpAchieveTableName(upAchieveTableName);
        List<ReportCuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList = baseMapper.selectNewAddAchieve(cuMemberNewAddAchieveVO);
        if (CollUtil.isNotEmpty(cuMemberNewAddAchieveVOList)) {
            //中国转汇率
            Integer pkCountry = cuMemberNewAddAchieveVO.getPkCountry();
            if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
                //根据国家查汇率
                rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
            }

            // 转万
            BigDecimal big10000 = new BigDecimal("10000");

            for (ReportCuMemberNewAddAchieveVO newAddAchieveVO : cuMemberNewAddAchieveVOList) {
                //转化单位万
                BigDecimal aNewPv = newAddAchieveVO.getANewPv().divide(big10000);
                BigDecimal bNewPv = newAddAchieveVO.getBNewPv().divide(big10000);
                BigDecimal aRegNewPv = newAddAchieveVO.getRepANewPv().divide(big10000);
                BigDecimal bRegNewPv = newAddAchieveVO.getRepBNewPv().divide(big10000);

                newAddAchieveVO.setANewPv(null != rate ? aNewPv.multiply(rate) : aNewPv);
                newAddAchieveVO.setBNewPv(null != rate ? bNewPv.multiply(rate) : bNewPv);
                newAddAchieveVO.setRepANewPv(null != rate ? aRegNewPv.multiply(rate) : aRegNewPv);
                newAddAchieveVO.setRepBNewPv(null != rate ? bRegNewPv.multiply(rate) : bRegNewPv);
            }
        }
        initialDate(cuMemberNewAddAchieveVOList, endDate, startDate);
        return cuMemberNewAddAchieveVOList;
    }

    /**
     * 初如化日期值
     *
     * @param cuMemberNewAddAchieveVOList 查询结题
     * @param endDate                     开始时间
     * @param startDate                   结束时间
     */
    private void initialDate(List<ReportCuMemberNewAddAchieveVO> cuMemberNewAddAchieveVOList, LocalDate endDate, LocalDate startDate) {
        Period between = Period.between(startDate, endDate);
        //相差天数
        int days = between.getDays();
        int months = between.getMonths();
        if (months == 1) {
            days = 30;
        }
        //初始化日期
        if (CollUtil.isEmpty(cuMemberNewAddAchieveVOList)) {
            ReportCuMemberNewAddAchieveVO memberNewAddAchieveVO;
            cuMemberNewAddAchieveVOList = new ArrayList<>();
            for (int i = 0; i < days; i++) {
                memberNewAddAchieveVO = ReportCuMemberNewAddAchieveVO.builder().settleDate(DateUtils.toDate(startDate.plusDays(i)))
                        .aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).repANewPv(BigDecimal.ZERO).repBNewPv(BigDecimal.ZERO)
                        .build();
                cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
            }
        } else {
            ReportCuMemberNewAddAchieveVO memberNewAddAchieveVO;
            Map<Date, ReportCuMemberNewAddAchieveVO> map = cuMemberNewAddAchieveVOList.stream().collect(Collectors.toMap(ReportCuMemberNewAddAchieveVO::getSettleDate, o -> o));
            for (int i = 0; i < days; i++) {
                Date localDate = DateUtils.toDate(startDate.plusDays(i));
                if (null == map.get(localDate)) {
                    memberNewAddAchieveVO = ReportCuMemberNewAddAchieveVO.builder().settleDate(localDate)
                            .aNewPv(BigDecimal.ZERO).bNewPv(BigDecimal.ZERO).repANewPv(BigDecimal.ZERO).repBNewPv(BigDecimal.ZERO)
                            .build();
                    cuMemberNewAddAchieveVOList.add(memberNewAddAchieveVO);
                }
            }
            //排序
            cuMemberNewAddAchieveVOList.sort(Comparator.comparing(ReportCuMemberNewAddAchieveVO::getSettleDate));
        }
    }

    /**
     * 安置业绩分布
     *
     * @param pkMember  登录用户
     * @param pkCountry 所属国家
     * @return
     */
    @Override
    public AchievementVO azAchievement(Long pkMember, Integer pkCountry) {
        CurrencyDTO currency = iCuMemberBaseService.getCurrency(pkCountry);

        // 查询会员左右区人数
        List<DeptMemberNumberVO> deptMemberNumberVoList = iMemberService.selectByDeptNumberPlace(pkMember);
        Map<Integer, Long> memberNumberMap = deptMemberNumberVoList.stream().collect(Collectors.toMap(DeptMemberNumberVO::getPlaceDept, DeptMemberNumberVO::getQuantity));

        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = iMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        CuMemberSettleExt memberSettleExt = iMemberTreeService.queryCuMemberTreeByPkMemberTable(settleTableName, pkMember);

        // 转万
        BigDecimal big10000 = new BigDecimal("10000");

        BigDecimal aSumRealPv = BigDecimal.ZERO;
        BigDecimal bSumRealPv = BigDecimal.ZERO;

        //当月
        AchievementVO achievementVO = new AchievementVO();
        if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            achievementVO.setLeftAchieve(aSumRealPv.divide(big10000).multiply(currency.getInExchangeRate()));
            achievementVO.setRightAchieve(bSumRealPv.divide(big10000).multiply(currency.getInExchangeRate()));
        } else {
            achievementVO.setLeftAchieve(aSumRealPv.divide(big10000));
            achievementVO.setRightAchieve(bSumRealPv.divide(big10000));
        }
        achievementVO.setLeftPeopleNumber(memberNumberMap.get(EPlaceDept.LEFT_DEPT.getValue()));
        achievementVO.setRightPeopleNumber(memberNumberMap.get(EPlaceDept.RIGHT_DEPT.getValue()));
        return achievementVO;
    }


    /**
     * 推荐小区分布
     *
     * @param pkMember  登录用户
     * @param pkCountry 所属国家
     * @return
     */
    @Override
    public AchievementVO recommendAchievement(Long pkMember, Integer pkCountry) {
        CurrencyDTO currency = iCuMemberBaseService.getCurrency(pkCountry);
        BigDecimal inExchangeRate = currency.getInExchangeRate();

        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = iMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        // 查询会员自身直推伞下
        List<ReportRecommendAchievementVo> recommendAchievementVoList = iMemberTreeService.listParentAchieve(settleTableName, Arrays.asList(pkMember));
     //   List<RecommendAchievementVo> recommendAchievementVoList = iMemberTreeService.recommendAchievement(settleTableName, Arrays.asList(pkMember));
        // 大区业绩
        BigDecimal maxAchieve = BigDecimal.ZERO;
        //小区业绩
        BigDecimal minAchieve = BigDecimal.ZERO;
        // 大区人数
        Long maxNumber = 0L;
        // 小区人数
        Long minNumber = 0L;
        if (recommendAchievementVoList.size() > 0) {

            // 查询小区业绩
            List<Long> pkParentMembers = new ArrayList<>();
            for (int i = 0; i < recommendAchievementVoList.size(); i++) {
                if (i == 0){
                    // 大区累加
                    maxAchieve = recommendAchievementVoList.get(0).getAchieve();
                }else {
                    // 小区累加
                    minAchieve = minAchieve.add(recommendAchievementVoList.get(i).getAchieve());
                    pkParentMembers.add(recommendAchievementVoList.get(i).getPkMember());
                }
            }
            maxNumber = maxNumber + 1;
            minNumber = minNumber + recommendAchievementVoList.size() - 1;
            // 查询大区伞下
            List<ReportRecommendAchievementVo> maxAchievementVoList = iMemberTreeService.recommendAchievement(settleTableName, Arrays.asList(recommendAchievementVoList.get(0).getPkMember()));
            if (maxAchievementVoList.size() > 0) {
                for (ReportRecommendAchievementVo recommendAchievementVo : maxAchievementVoList) {
                    maxAchieve = maxAchieve.add(recommendAchievementVo.getAchieve());
                }
                maxNumber = maxNumber + maxAchievementVoList.size();
            }
            // 查询小区伞下
            if (CollectionUtil.isNotEmpty(pkParentMembers)) {
                List<ReportRecommendAchievementVo> minAchievementVoList = iMemberTreeService.recommendAchievement(settleTableName, pkParentMembers);
                if (minAchievementVoList.size() > 0) {
                    for (ReportRecommendAchievementVo recommendAchievementVo : minAchievementVoList) {
                        minAchieve = minAchieve.add(recommendAchievementVo.getAchieve());
                    }
                    minNumber = minNumber + minAchievementVoList.size();
                }
            }
        }
        // 转万
        BigDecimal big10000 = new BigDecimal("10000");
        //当月
        AchievementVO achievementVo = new AchievementVO();
        if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            achievementVo.setLeftAchieve(maxAchieve.divide(big10000).multiply(inExchangeRate));
            achievementVo.setRightAchieve(minAchieve.divide(big10000).multiply(inExchangeRate));
        } else {
            achievementVo.setLeftAchieve(maxAchieve.divide(big10000));
            achievementVo.setRightAchieve(minAchieve.divide(big10000));
        }
        achievementVo.setLeftPeopleNumber(maxNumber);
        achievementVo.setRightPeopleNumber(minNumber);
        return achievementVo;
    }

    /**
     * 首购业绩分布
     *
     * @param pkMember  登录用户
     * @param pkCountry 所属国家
     * @return
     */
    @Override
    public AchievementVO firstPerformancePic(Long pkMember, Integer pkCountry) {
        CurrencyDTO currency = iCuMemberBaseService.getCurrency(pkCountry);

        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = iMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        CuMemberSettleExt memberSettleExt = iMemberTreeService.queryCuMemberTreeByPkMemberTable(settleTableName, pkMember);

        // 转万
        BigDecimal big10000 = new BigDecimal("10000");

        // 左区业绩
        BigDecimal leftAchieve = BigDecimal.ZERO;
        // 右区业绩
        BigDecimal rightAchieve = BigDecimal.ZERO;
        // 2023.11.11 TODO 切换奖金注释代码
//        if (memberSettleExt != null && memberSettleExt.getASumPv() != null) {
//            leftAchieve = memberSettleExt.getASumPv();
//        }
//        if (memberSettleExt != null && memberSettleExt.getBSumPv() != null) {
//            rightAchieve = memberSettleExt.getBSumPv();
//        }

        AchievementVO achievementVo = new AchievementVO();
        if (pkCountry.equals(CountryConstants.CHINA_COUNTRY)) {
            achievementVo.setLeftAchieve(leftAchieve.divide(big10000).multiply(currency.getInExchangeRate()));
            achievementVo.setRightAchieve(rightAchieve.divide(big10000).multiply(currency.getInExchangeRate()));
        } else {
            achievementVo.setLeftAchieve(leftAchieve.divide(big10000));
            achievementVo.setRightAchieve(rightAchieve.divide(big10000));
        }
        // 查询会员左右区人数
        List<DeptMemberNumberVO> deptMemberNumberVoList = iMemberService.selectByDeptNumberPlace(pkMember);
        Map<Integer, Long> memberNumberMap = deptMemberNumberVoList.stream().collect(Collectors.toMap(DeptMemberNumberVO::getPlaceDept, DeptMemberNumberVO::getQuantity));

        achievementVo.setLeftPeopleNumber(memberNumberMap.get(EPlaceDept.LEFT_DEPT.getValue()));
        achievementVo.setRightPeopleNumber(memberNumberMap.get(EPlaceDept.RIGHT_DEPT.getValue()));

        return achievementVo;
    }


    /**
     * 复购业绩分布
     *
     * @param pkMember  登录用户
     * @param pkCountry 所属国家
     * @return
     */
    @Override
    public AchievementVO queryRepurchasePerformancePic(Long pkMember, Integer pkCountry) {
        CurrencyDTO currency = iCuMemberBaseService.getCurrency(pkCountry);

        List<DeptMemberNumberVO> deptMemberNumberVoList = iMemberService.selectByDeptNumberPlace(pkMember);
        Map<Integer, Long> memberNumberMap = deptMemberNumberVoList.stream().collect(Collectors.toMap(DeptMemberNumberVO::getPlaceDept, DeptMemberNumberVO::getQuantity));

        DateTime dateTime = DateUtil.offsetDay(DateUtils.currentDate(), -1);
        String time = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, dateTime);
        CuMemberSettlePeriod csPeriod = iMemberSettlePeriodService.getCuMemberSettlePeriodByDate(time);
        String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + csPeriod.getPkId();
        CuMemberSettleExt memberSettleExt = iMemberTreeService.queryCuMemberTreeByPkMemberTable(settleTableName, pkMember);

        // 转万
        BigDecimal big10000 = new BigDecimal("10000");


        //当月
        AchievementVO achievementVo = new AchievementVO();
        achievementVo.setLeftPeopleNumber(memberNumberMap.get(EPlaceDept.LEFT_DEPT.getValue()));
        achievementVo.setRightPeopleNumber(memberNumberMap.get(EPlaceDept.RIGHT_DEPT.getValue()));
        return achievementVo;
    }


}
