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

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.bonus.achieve.service.impl.CuMemberBonusSettle;
import com.hzs.bonus.detail.mapper.CuRegionAssessMapper;
import com.hzs.bonus.detail.service.ICuRegionAssessDetailService;
import com.hzs.bonus.detail.service.ICuRegionAssessService;
import com.hzs.bonus.detail.vo.CuRegionAssessDetailVO;
import com.hzs.bonus.detail.vo.CuRegionAssessVO;
import com.hzs.bonus.param.CuRegionAssessParam;
import com.hzs.common.core.constant.MagicNumberConstants;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.member.detail.CuRegionAssess;
import com.hzs.common.domain.member.detail.CuRegionAssessDetail;
import com.hzs.common.domain.member.detail.ext.CuRegionAssessExt;
import com.hzs.common.domain.retail.member.CuMemberRetailRegion;
import com.hzs.retail.member.IMemberRetailApi;
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 org.springframework.transaction.annotation.Transactional;

import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 新零售会员区域考核 服务实现类
 */
@Slf4j
@Service
public class CuRegionAssessServiceImpl extends ServiceImpl<CuRegionAssessMapper, CuRegionAssess> implements ICuRegionAssessService {

    @DubboReference
    IMemberRetailApi iMemberRetailApi;

    @Autowired
    private ICuRegionAssessDetailService iCuRegionAssessDetailService;

    @Autowired
    private CuMemberBonusSettle cuMemberBonusSettle;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assessRegionByEveryMonth(String settleDate, String rangeTableName) {
        // 每月1号进行考核，结算上月最后一期的时候进行区域达标考核
        Date assDate = DateUtils.parseStringToDate(settleDate);
        Date assessDate = DateUtils.afterDate(1, ChronoUnit.DAYS, assDate);

        log.info("assDate : {}", DateUtils.parseDateTimeToStr(DateUtils.YYYY_MM_DD, assDate));
        log.info("assessDate : {}", DateUtils.parseDateTimeToStr(DateUtils.YYYY_MM_DD, assessDate));

        if (DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, assessDate).endsWith("01")) {
            // 当月第一天
            Date startDate = DateUtils.currentMonthFirstDate(assDate);

            log.info("startDate : {}", DateUtils.parseDateTimeToStr(DateUtils.YYYY_MM_DD, startDate));

            // 清空 1 号到 今天 的考核数据
            iCuRegionAssessDetailService.updateAssessRegionDetailByDate(startDate, assessDate);
            baseMapper.updateAssessRegionByDate(startDate, assessDate);
            deleteAssessRegionByDate(assessDate, 1);

            // 生成6期待考核数据，查询上月的区域，第一次考核的时候，明细生成6期
            // 查询目前有效的区域配置
            List<CuMemberRetailRegion> memberRetailRegionList = baseMapper.queryCuMemberRetailRegion(startDate, assessDate);
            if (memberRetailRegionList.size() > 0) {
                Map<Long, CuRegionAssess> regionAssessMap = new HashMap<>();
                List<CuRegionAssessDetail> regionAssessDetailList = new ArrayList<>();
                for (CuMemberRetailRegion cuMemberRetailRegion : memberRetailRegionList) {

                    if (null != cuMemberRetailRegion.getEffectiveEndDate()) {
                        // 设置过生效结束时间
                        CuRegionAssess cuRegionAssess = CuRegionAssess.builder()
                                .pkMember(cuMemberRetailRegion.getPkMember())
                                .pkRegion(cuMemberRetailRegion.getPkId())
                                .assessPeriod(1)
                                .assessStartDate(assessDate)
                                // 考核结束期
                                .assessEndDate(DateUtils.currentMonthFirstDate(DateUtils.afterMonthDate(1, cuMemberRetailRegion.getEffectiveEndDate())))
                                .source(cuMemberRetailRegion.getSource())
                                .build();
                        cuRegionAssess.setPkCreator(MagicNumberConstants.PK_ADMIN);
                        cuRegionAssess.setPkCountry(cuMemberRetailRegion.getPkCountry());
                        regionAssessMap.put(cuRegionAssess.getPkMember(), cuRegionAssess);
                        while (assessDate.compareTo(cuRegionAssess.getAssessEndDate()) <= 0) {
                            CuRegionAssessDetail cuRegionAssessDetail = CuRegionAssessDetail.builder()
                                    .pkRegionAssess(cuRegionAssess.getPkMember())
                                    .assessDate(assessDate)
                                    .pkMember(cuRegionAssess.getPkMember())
                                    .build();
                            cuRegionAssessDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
                            cuRegionAssessDetail.setPkCountry(cuMemberRetailRegion.getPkCountry());
                            regionAssessDetailList.add(cuRegionAssessDetail);

                            assessDate = DateUtils.afterMonthDate(1, assessDate);
                        }
                    } else {
                        CuRegionAssess cuRegionAssess = CuRegionAssess.builder()
                                .pkMember(cuMemberRetailRegion.getPkMember())
                                .pkRegion(cuMemberRetailRegion.getPkId())
                                .assessPeriod(1)
                                .assessStartDate(assessDate)
                                // 考核结束期
                                .assessEndDate(DateUtils.currentMonthFirstDate(DateUtils.afterMonthDate(5, assessDate)))
                                .source(cuMemberRetailRegion.getSource())
                                .build();
                        cuRegionAssess.setPkCreator(MagicNumberConstants.PK_ADMIN);
                        cuRegionAssess.setPkCountry(cuMemberRetailRegion.getPkCountry());
                        regionAssessMap.put(cuRegionAssess.getPkMember(), cuRegionAssess);
                        // 保存明细
                        for (int i = 0; i < 6; i++) {
                            CuRegionAssessDetail cuRegionAssessDetail = CuRegionAssessDetail.builder()
                                    .pkRegionAssess(cuRegionAssess.getPkMember())
                                    .assessDate(DateUtils.afterMonthDate(i, assessDate))
                                    .pkMember(cuRegionAssess.getPkMember())
                                    .build();
                            cuRegionAssessDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
                            cuRegionAssessDetail.setPkCountry(cuMemberRetailRegion.getPkCountry());
                            regionAssessDetailList.add(cuRegionAssessDetail);
                        }
                    }

                }
                saveCuRegionAssess(regionAssessMap, regionAssessDetailList);
            }
            iCuRegionAssessDetailService.assessCuRegionAssessDetail(rangeTableName, assessDate);
            baseMapper.mergeCuRegionAssess(assessDate);

            // 取消区域列表
            List<Long> cancelRegionList = new ArrayList<>();
            // 开始考核，将 上月最后一天，奖衔、业绩同步到考核表中
            // 查询主表考核结束日期=考核日期的，这部分需要生成下6期,最后一期结算完，验证是否达标，达标后继续生成下一期，不达标取消区域
            // 查询考核结束日期次数不达标的区域，进行区域取消处理
            List<CuRegionAssess> cuRegionAssessList = queryCuRegionAssessByEndDate(assessDate);
            Map<Long, CuRegionAssess> regionAssessMap = new HashMap<>();
            List<CuRegionAssessDetail> regionAssessDetailList = new ArrayList<>();
            for (CuRegionAssess cuRegionAssess : cuRegionAssessList) {
                if (cuRegionAssess.getReachNum() < 3) {
                    cancelRegionList.add(cuRegionAssess.getPkRegion());
                    continue;
                }
                Date nextAssessDate = DateUtils.afterMonthDate(1, assessDate);
                deleteAssessRegionByDate(nextAssessDate, 2);
                CuRegionAssess cuRegionAssess1 = CuRegionAssess.builder()
                        .pkMember(cuRegionAssess.getPkMember())
                        .pkRegion(cuRegionAssess.getPkRegion())
                        .assessPeriod(cuRegionAssess.getAssessPeriod() + 1)
                        .assessStartDate(DateUtils.currentMonthFirstDate(nextAssessDate))
                        .assessEndDate(DateUtils.currentMonthFirstDate(DateUtils.afterMonthDate(5, nextAssessDate)))
                        .source(cuRegionAssess.getSource())
                        .build();
                cuRegionAssess1.setPkCountry(cuRegionAssess.getPkCountry());
                cuRegionAssess1.setPkCreator(MagicNumberConstants.PK_ADMIN);
                regionAssessMap.put(cuRegionAssess1.getPkMember(), cuRegionAssess1);
                // 保存明细
                for (int i = 0; i < 6; i++) {
                    CuRegionAssessDetail cuRegionAssessDetail = CuRegionAssessDetail.builder()
                            .pkRegionAssess(cuRegionAssess.getPkMember())
                            .assessDate(DateUtils.afterMonthDate(i, cuRegionAssess1.getAssessStartDate()))
                            .pkMember(cuRegionAssess.getPkMember())
                            .build();
                    cuRegionAssessDetail.setPkCreator(MagicNumberConstants.PK_ADMIN);
                    cuRegionAssessDetail.setPkCountry(cuRegionAssess.getPkCountry());
                    regionAssessDetailList.add(cuRegionAssessDetail);
                }
                saveCuRegionAssess(regionAssessMap, regionAssessDetailList);
            }
            // 查询到期日期的区域，验证近6个月的达标次数，不达标取消
//            validateHandAreaAssess(assessDate, startDate, cancelRegionList);
            if (cancelRegionList.size() > 0) {
                if (!iMemberRetailApi.cancelRegion(cancelRegionList).isSuccess()) {
                    throw new RuntimeException("区域更新失败");
                }
            }
        }
    }

    private void saveCuRegionAssess(Map<Long, CuRegionAssess> regionAssessMap, List<CuRegionAssessDetail> regionAssessDetailList) {
        List<Long> longs = baseMapper.batchQueryCuRegionAssessSeq(regionAssessMap.size());
        int i = 0;
        List<CuRegionAssess> cuRegionAssessList = new ArrayList<>();
        for (Long pkMember : regionAssessMap.keySet()) {
            CuRegionAssess cuRegionAssess = regionAssessMap.get(pkMember);
            cuRegionAssess.setPkId(longs.get(i));
            cuRegionAssessList.add(cuRegionAssess);
            i++;
        }
        for (CuRegionAssessDetail cuRegionAssessDetail : regionAssessDetailList) {
            if (regionAssessMap.containsKey(cuRegionAssessDetail.getPkRegionAssess())) {
                CuRegionAssess cuRegionAssess = regionAssessMap.get(cuRegionAssessDetail.getPkRegionAssess());
                cuRegionAssessDetail.setPkRegionAssess(cuRegionAssess.getPkId());
            }
        }
        // 主表
        List<List<?>> lists = cuMemberBonusSettle.handleCutList(cuRegionAssessList);
        lists.forEach(list -> baseMapper.batchInsertCuRegionAssess(list));

        List<Long> idList = iCuRegionAssessDetailService.batchQueryCuRegionAssessDetailSeq(regionAssessDetailList.size());
        for (int j = 0; j < regionAssessDetailList.size(); j++) {
            regionAssessDetailList.get(j).setPkId(idList.get(j));
        }
        // 明细表
        List<List<?>> detailList = cuMemberBonusSettle.handleCutList(regionAssessDetailList);
        detailList.forEach(detail -> iCuRegionAssessDetailService.batchInsertCuRegionAssessDetail(detail));
    }

    List<CuRegionAssess> queryCuRegionAssessByEndDate(Date settleDate) {
        LambdaQueryWrapper<CuRegionAssess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CuRegionAssess::getAssessEndDate, settleDate);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAssessRegionByDate(Date assessStartDate, Integer assessPeriod) {
        // 7天内重算
        iCuRegionAssessDetailService.deleteAssessRegionDetailByDate(assessStartDate, assessPeriod);
        baseMapper.deleteAssessRegionByDate(assessStartDate, assessPeriod);
    }

    @Override
    public List<CuRegionAssessExt> queryRegionAssessByCondition(CuRegionAssessParam regionAssessParam) {
        regionAssessParam.setAssessDate(DateUtils.currentMonthFirstDate());
        return baseMapper.queryRegionAssessByCondition(regionAssessParam);
    }

    @Override
    public List<CuRegionAssessVO> getCuRegionAssessVoS(List<CuRegionAssessExt> cuRegionAssessExtList) {
        List<CuRegionAssessVO> cuRegionAssessVoList = new ArrayList<>();
        for (CuRegionAssessExt cuRegionAssessExt : cuRegionAssessExtList) {
            CuRegionAssessVO cuRegionAssessVO = BeanUtil.copyProperties(cuRegionAssessExt, CuRegionAssessVO.class);
            List<CuRegionAssessDetailVO> regionAssessDetailVoList = new ArrayList<>();
            for (CuRegionAssessDetail cuRegionAssessDetail : cuRegionAssessExt.getCuRegionAssessDetailList()) {
                CuRegionAssessDetailVO cuRegionAssessDetailVO = BeanUtil.copyProperties(cuRegionAssessDetail, CuRegionAssessDetailVO.class);
                regionAssessDetailVoList.add(cuRegionAssessDetailVO);
            }
            cuRegionAssessVO.setRegionAssessDetailVoList(regionAssessDetailVoList);
            cuRegionAssessVoList.add(cuRegionAssessVO);
        }
        return cuRegionAssessVoList;
    }
}
