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

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.detail.CuMemberAssess;
import com.hzs.member.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.member.detail.mapper.CuMemberAssessMapper;
import com.hzs.member.detail.service.ICuMemberAssessDetailService;
import com.hzs.member.detail.service.ICuMemberAssessService;
import com.hzs.member.detail.vo.CuMemberAssessVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 会员信息-会员考核记录 服务实现类
 */
@Service
public class CuMemberAssessServiceImpl extends ServiceImpl<CuMemberAssessMapper, CuMemberAssess> implements ICuMemberAssessService {

    @Autowired
    private ICuMemberSettlePeriodService cuMemberSettlePeriodService;
    @Autowired
    private ICuMemberAssessDetailService cuMemberAssessDetailService;

    /**
     * 复购考核每月第一次考核调用此方法
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculationCuMemberAssess(Date currentDate) {
        // 查询当前时间的第一天跟最后一天
        // 需要验证考核国家是否有复购考核 分红考核
        // 考核日期不能跨越考核，只能当月考核，当月考核上月
        if (DateUtils.currentDay(currentDate) == 1) {
            String currentMonthFirstDate = DateUtils.currentMonthFirstDateStr(currentDate);
            Integer currentPeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(currentMonthFirstDate).getPkId();
            String currentTableName = TableNameConstants.CU_MEMBER_ASSESS + DateUtils.getYear(currentMonthFirstDate);
            // 清空数据  根据期数清空cu_member_assess  cu_member_assess_detail表数据
            initCurrentAssess(currentDate, currentTableName, currentPeriod);
            // 初始化复购考核的上月结余
            initCurrentAssessByBeforeMonth(currentDate, currentTableName, currentPeriod, EAssessmentType.REPURCHASE_ASSESS.getValue());
            // 更新当月结余 结余会同时更新复购跟分红，只需要更新一次
            // 1 有免考状态的 本月使用是 0，考核状态是免考通过，免考将所有的值更改一下期末 期末= 期初+本月
            // 注意 不修改考核状态为通过的值，可能存在之前考核通过，又手动免考的人
            baseMapper.updateAssessPeriodExemptBalanceByUsed(currentTableName, currentPeriod);
            // 2 需要扣除通过的，需要记录流水
            // 记录流水，新增或修改
            cuMemberAssessDetailService.updateCuMemberAssessDetailByPeriod(currentTableName, currentPeriod);
            baseMapper.updateAssessPeriodCheckBalanceByUsed(currentTableName, currentPeriod);
        }
    }

    @Override
    public List<CuMemberAssessVO> selectAssessList(CuMemberAssessVO cuMemberAssessVO, List<Integer> orderTypeList) {
        Integer year;
        if (StringUtils.isNotNull(cuMemberAssessVO) && StringUtils.isNotNull(cuMemberAssessVO.getStartDate())) {
            year = DateUtils.currentYear(cuMemberAssessVO.getStartDate());
        } else {
            year = DateUtils.currentYear(new Date());
        }
        String tableName = TableNameConstants.CU_MEMBER_ASSESS + year;
        if (StringUtils.isNotEmpty(tableName)) {
            return baseMapper.selectAssessList(tableName, cuMemberAssessVO.getPkMember(),
                    cuMemberAssessVO.getPkCountry(), cuMemberAssessVO.getAssessStatus(),
                    cuMemberAssessVO.getAssessType(), cuMemberAssessVO.getChangeType(), cuMemberAssessVO.getStartDate(),
                    cuMemberAssessVO.getEndDate(), orderTypeList, cuMemberAssessVO.getStartTradeTime(),
                    cuMemberAssessVO.getEndDateTradeTime()
            );
        }
        return null;
    }

    @Override
    public List<CuMemberAssessVO> getMemberAssessMonthList(CuMemberAssessVO cuMemberAssessVO) {
        Integer year;
        //获取期数
        Date date = new Date();
        if (StringUtils.isNotNull(cuMemberAssessVO) && StringUtils.isNotNull(cuMemberAssessVO.getStartDate())) {
            year = DateUtils.currentYear(cuMemberAssessVO.getStartDate());
        } else {
            year = DateUtils.currentYear(date);
        }
        String tableName = TableNameConstants.CU_MEMBER_ASSESS + year;
        if (StringUtils.isNotEmpty(tableName)) {
            return baseMapper.getMemberAssessMonthList(tableName, cuMemberAssessVO.getPkMember(), cuMemberAssessVO.getAssessType(),
                    cuMemberAssessVO.getPkCountry(), null);
        }
        return null;
    }

    @Override
    public List<CuMemberAssessVO> getMemberAssessMonth(CuMemberAssessVO cuMemberAssessVO) {
        Integer year;
        //获取期数
        Date date = new Date();
        int period;
        if (StringUtils.isNotNull(cuMemberAssessVO) && StringUtils.isNotNull(cuMemberAssessVO.getStartDate())) {
            year = DateUtils.currentYear(cuMemberAssessVO.getStartDate());
            if (DateUtils.compareDateBefore(date, cuMemberAssessVO.getStartDate()) || DateUtils.compareDateEqual(date, cuMemberAssessVO.getStartDate())) {
                //获取当前月第一天
                Date date1 = DateUtils.currentMonthFirstDate(date);
                period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date1)).getPkId();
            } else {
                Date date1 = DateUtils.currentMonthFirstDate(cuMemberAssessVO.getStartDate());
                period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date1)).getPkId();
            }
        } else {
            year = DateUtils.currentYear(date);
            Date date1 = DateUtils.currentMonthFirstDate(date);
            period = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date1)).getPkId();
        }
        String tableName = TableNameConstants.CU_MEMBER_ASSESS + year;
        if (StringUtils.isNotEmpty(tableName)) {
            return baseMapper.getMemberAssessMonthList(tableName, cuMemberAssessVO.getPkMember(), cuMemberAssessVO.getAssessType(),
                    cuMemberAssessVO.getPkCountry(), period);
        }
        return null;
    }

    private void initCurrentAssess(Date currentDate, String currentTableName, Integer currentPeriod) {
        // 获取上月最后一天
        String beforeLastDate = DateUtils.beforeMonthLastDateStr(currentDate);
        CuMemberSettlePeriod cuMemberSettlePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeLastDate);
        int period = cuMemberSettlePeriod.getPkId();
        String sourceTable = TableNameConstants.CU_MEMBER_SETTLE + period;
        // 清空子表、主表数据
        cuMemberAssessDetailService.deleteCuMemberAssessDetailByPeriod(currentTableName, currentPeriod);
        // 初始化复购考核
        String month = DateUtils.getMonth(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate));
        // 结算日期后一天
        baseMapper.insertRepCuMemberAssess(currentTableName, sourceTable, currentPeriod, month);
        // 初始化分红考核
        baseMapper.insertShareCuMemberAssess(currentTableName, sourceTable, currentPeriod, month);
        // 初始化订单数据，将当月新增加入数据库
        // 上月第一天，上月最后一天
        Date beforeFirstDate = DateUtils.beforeMonthFirstDate(currentDate);
        Date currentFirstDate = DateUtils.currentMonthFirstDate(currentDate);
        cuMemberAssessDetailService.insertCuMemberAssesDetailByOrder(currentTableName, currentPeriod, beforeFirstDate, currentFirstDate);
    }

    /**
     * 初始化期初数据，将上月结余作为本月期初，更新当月新增
     *
     * @param currentDate      结算日期
     * @param currentTableName 当前月结算表
     * @param currentPeriod    当前结算期间
     * @param assessmentType   考核类型 0=复购考核 1=分红考核
     */
    private void initCurrentAssessByBeforeMonth(Date currentDate, String currentTableName, Integer currentPeriod, Integer assessmentType) {
        List<Integer> orderTypeList = new ArrayList<>();
        if (EAssessmentType.REPURCHASE_ASSESS.getValue() == assessmentType) {
            orderTypeList.add(EOrderType.REPURCHASE_ORDER.getValue());
            orderTypeList.add(EOrderType.MALL_ORDER.getValue());
        }
        // 更新考核值，期初是上月考核表的当月剩余业绩
        // 获取结算日月初第一天，获取期间
        // 获取结算日上月最后一天，获取期间
        Date beforeMonthFirstDate = DateUtils.beforeMonthFirstDate(currentDate);
        String beforeMonthFirstDateStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, beforeMonthFirstDate);
        Integer beforePeriod = cuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeMonthFirstDateStr).getPkId();
        String beforeTableName = TableNameConstants.CU_MEMBER_ASSESS + DateUtils.getYear(beforeMonthFirstDateStr);
        Date currentMonthFirstDate = DateUtils.currentMonthFirstDate(currentDate);
        // 初始化复购考核的上月结余 // 更新当月结余
        baseMapper.updateAssessPeriodBeginByBeforeMonth(beforeTableName, currentTableName, beforePeriod, currentPeriod, assessmentType);
        // 更新当月新增
        baseMapper.updateAssessPeriodAddBySaOrder(currentTableName, currentPeriod, assessmentType,
                beforeMonthFirstDate, currentMonthFirstDate, orderTypeList);
    }

    @Override
    public CuMemberAssessVO getOrderAssessList(CuMemberAssessVO cuMemberAssessVO) {
        return baseMapper.getOrderAssessList(cuMemberAssessVO);
    }

}
