package cn.newfeifan.mall.module.distri.service.ptprofitlog;

import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.newfeifan.mall.module.distri.enums.CaclEnum;
import cn.newfeifan.mall.module.distri.enums.IntegralEnum;
import cn.newfeifan.mall.module.member.service.user.MemberUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.web.mappings.MappingsEndpoint;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;

import cn.newfeifan.mall.module.distri.controller.admin.ptprofitlog.vo.*;
import cn.newfeifan.mall.module.distri.dal.dataobject.ptprofitlog.PtProfitLogDO;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.object.BeanUtils;

import cn.newfeifan.mall.module.distri.dal.mysql.ptprofitlog.PtProfitLogMapper;

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.module.distri.enums.CaclEnum.*;
import static cn.newfeifan.mall.module.distri.enums.ErrorCodeConstants.*;
import static cn.newfeifan.mall.module.distri.enums.IntegralEnum.*;

/**
 * 平台利润记录 Service 实现类
 *
 * @author 非繁人
 */
@Service
@Validated
public class PtProfitLogServiceImpl implements PtProfitLogService {

    @Resource
    private PtProfitLogMapper ptProfitLogMapper;
    @Resource
    private MemberUserService memberUserService;
    @Autowired
    private MappingsEndpoint mappingsEndpoint;


    @Override
    public Long createPtProfitLog(PtProfitLogSaveReqVO createReqVO) {
        // 插入
        PtProfitLogDO ptProfitLog = BeanUtils.toBean(createReqVO, PtProfitLogDO.class);
        ptProfitLogMapper.insert(ptProfitLog);
        // 返回
        return ptProfitLog.getId();
    }

    @Override
    public void updatePtProfitLog(PtProfitLogSaveReqVO updateReqVO) {
        // 校验存在
        validatePtProfitLogExists(updateReqVO.getId());
        // 更新
        PtProfitLogDO updateObj = BeanUtils.toBean(updateReqVO, PtProfitLogDO.class);
        ptProfitLogMapper.updateById(updateObj);
    }

    @Override
    public void deletePtProfitLog(Long id) {
        // 校验存在
        validatePtProfitLogExists(id);
        // 删除
        ptProfitLogMapper.deleteById(id);
    }

    private void validatePtProfitLogExists(Long id) {
        if (ptProfitLogMapper.selectById(id) == null) {
            throw exception(PT_PROFIT_LOG_NOT_EXISTS);
        }
    }

    @Override
    public PtProfitLogDO getPtProfitLog(Long id) {
        return ptProfitLogMapper.selectById(id);
    }

    @Override
    public PageResult<PtProfitLogRespVO> getPtProfitLogPage(PtProfitLogPageReqVO pageReqVO) {
        PageResult<PtProfitLogRespVO> result = BeanUtils.toBean(ptProfitLogMapper.selectPage(pageReqVO), PtProfitLogRespVO.class);
        for (PtProfitLogRespVO ptProfitLogRespVO : result.getList()) {
            ptProfitLogRespVO.setProfitStatusName(Objects.requireNonNull(IntegralEnum.getName(ptProfitLogRespVO.getProfitStatus())));

            if (ptProfitLogRespVO.getProfitStatus().equals(BUY_ORDER.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(TEAM_BONUS.getType())) {
                ptProfitLogRespVO.setUsername(memberUserService.getUser(ptProfitLogRespVO.getGenerateUserId()).getUsername());
            }
        }
        return result;
    }

    @Override
    public void saveBatch(List<PtProfitLogSaveReqVO> ptProfitLogSaveReqVOS) {
        List<PtProfitLogDO> ptProfitLog = BeanUtils.toBean(ptProfitLogSaveReqVOS, PtProfitLogDO.class);
        ptProfitLogMapper.insertBatch(ptProfitLog);
    }

    @Override
    public void addMessage(Long userId, CaclEnum caclEnum, Long amount, Long afterAmount, String percentTemplate,Long accumulatedQuotAmount, Long maxAvailablePointsAmount ,Long afterMaxAvailablePointsAmount) {
        PtProfitLogSaveReqVO ptProfitLog = PtProfitLogSaveReqVO.builder()
                .afterAmount(afterAmount)
                .amount(amount)
                .percentTemplate(percentTemplate)
                .profitStatus(caclEnum.getType())
                .generateUserId(userId)
                .build();
        ptProfitLogMapper.insert(BeanUtils.toBean(ptProfitLog, PtProfitLogDO.class));
        // todo 发送通知
        // todo 发短信

    }
    @Override
    public Long addMessageFreeze(Long userId,Long ancestorId, CaclEnum caclEnum, Long amount, Long afterAmount, String percentTemplate,Long accumulatedQuotAmount, Long maxAvailablePointsAmount ,Long afterMaxAvailablePointsAmount) {
        PtProfitLogSaveReqVO ptProfitLog = PtProfitLogSaveReqVO.builder()
                .percentTemplate(percentTemplate)
                .profitStatus(caclEnum.getType())
                .generateUserId(ancestorId)
                .build();
        PtProfitLogDO bean = BeanUtils.toBean(ptProfitLog, PtProfitLogDO.class);
        ptProfitLogMapper.insert(bean);
        return bean.getId();
        // todo 发送通知
        // todo 发短信

    }

    @Override
    public void addMessage(Long userId, CaclEnum caclEnum, Integer amount, Integer afterAmount) {



    }

    @Override
    public String getYesterdayLog(List<Long> sonsId) {

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 获取昨天的3点
        LocalDateTime yesterdayThreeAM = now.minusDays(1).withHour(3).withMinute(0).withSecond(0).withNano(0);

        // 获取今天的3点
        LocalDateTime todayThreeAM = now.withHour(3).withMinute(0).withSecond(0).withNano(0);
        if (now.isBefore(todayThreeAM)) {
            // 如果当前时间在今天的3点之前，调整今天的3点为昨天的3点
            todayThreeAM = todayThreeAM.minusDays(1);
        }

        List<PtProfitLogDO> ptProfitLogDOS = ptProfitLogMapper.selectList(new LambdaQueryWrapperX<PtProfitLogDO>()
                .betweenIfPresent(PtProfitLogDO::getCreateTime, yesterdayThreeAM, todayThreeAM)
                .eqIfPresent(PtProfitLogDO::getProfitStatus, CaclEnum.DIRECT_REFERRAL_QUOTA.getType())
                .or().eq(PtProfitLogDO::getProfitStatus, CaclEnum.TOGETHER_AWARD.getType())
                .in(PtProfitLogDO::getGenerateUserId, sonsId));
        Long sum = ptProfitLogDOS.stream().mapToLong(PtProfitLogDO::getAmount).sum();

        return sum + "";
    }

    @Override
    public String getTotalLog(List<Long> sonsId) {
        List<PtProfitLogDO> ptProfitLogDOS = ptProfitLogMapper.selectList(new LambdaQueryWrapperX<PtProfitLogDO>()
                .eqIfPresent(PtProfitLogDO::getProfitStatus, CaclEnum.DIRECT_REFERRAL_QUOTA.getType())
                .or().eq(PtProfitLogDO::getProfitStatus, CaclEnum.TOGETHER_AWARD.getType())
                .in(PtProfitLogDO::getGenerateUserId, sonsId));
        Long sum = ptProfitLogDOS.stream().mapToLong(PtProfitLogDO::getAmount).sum();

        return sum + "";
    }

    @Override
    public void addMessage(Long generateUserId,//导致产生积分变动的用户ID
                           Long userId, //实际变动积分的用户ID
                           CaclEnum caclEnum, Long amount, Long afterAmount,
                           Long freezeAmount, Long afterFreezeAmount,
                           String percentTemplate,
                           Long tradeOrderId,
                           String OrderNum
    ) {
        PtProfitLogSaveReqVO ptProfitLog = PtProfitLogSaveReqVO.builder()
                .afterAmount(afterAmount)
                .amount(amount)
                .percentTemplate(percentTemplate)
                .generateUserId(generateUserId)
                .profitStatus(caclEnum.getType()).orderId(tradeOrderId).orderNo(OrderNum)
                .build();
        ptProfitLogMapper.insert(BeanUtils.toBean(ptProfitLog, PtProfitLogDO.class));

    }

    @Override
    public List<PtProfitLogDO> calcIntegral() {
        return ptProfitLogMapper.selectList(new LambdaQueryWrapper<PtProfitLogDO>()
                .eq(PtProfitLogDO::getProfitStatus, SMALL_QUOTA_CRASH.getType())
                .lt(PtProfitLogDO::getCreateTime, LocalDateTime.now().minusDays(5))
        );
    }

    @Override
    public Long createPtProfitLog(Long userId, Long amount, Long afterAmount, String percentTemplate, IntegralEnum integralEnum, Integer profitType) {
        PtProfitLogDO log = PtProfitLogDO.builder()
                .generateUserId(userId)
                .amount(amount)
                .afterAmount(afterAmount)
                .percentTemplate(percentTemplate)
                .profitType(profitType)
                .profitStatus(integralEnum.getType())
                .build();
        ptProfitLogMapper.insert(log);

        return log.getId();
    }

}