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.member.service.user.MemberUserService;
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.app.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.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.newfeifan.mall.module.distri.enums.CaclEnum.*;
import static cn.newfeifan.mall.module.distri.enums.ErrorCodeConstants.*;

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

    @Resource
    private PtProfitLogMapper ptProfitLogMapper;

    @Resource
    private MemberUserService memberUserService;

    @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) {
        pageReqVO.setUserId(getLoginUserId());
        PageResult<PtProfitLogRespVO> result = BeanUtils.toBean(ptProfitLogMapper.selectPage(pageReqVO), PtProfitLogRespVO.class);
        for (PtProfitLogRespVO ptProfitLogRespVO : result.getList()) {
            if (ptProfitLogRespVO.getProfitStatus().equals(RECOMMENDED_PERSON_QUOTA.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(CaclEnum.ORDER_PAY_INTEGRAL_ANCESTER.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(CaclEnum.ORDER_REFUND_INTEGRAL_ANCESTER.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(SMALL_QUOTA_CRASH.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(MANUAL_RETURN_INTEGRAL.getType()) ||
                    ptProfitLogRespVO.getProfitStatus().equals(SMALL_QUOTA_CRASH_SETTLE.getType())) {
                ptProfitLogRespVO.setUsername(memberUserService.getUser(ptProfitLogRespVO.getGenerateUserId()).getUsername());
            }
            ptProfitLogRespVO.setProfitStatusName(Objects.requireNonNull(CaclEnum.getCaclEnumByValue(ptProfitLogRespVO.getProfitStatus())).getName());
        }
        return result;
    }

    @Override
    public PageResult<PtProfitLogRespVO> getMaxAmountPage(PtProfitLogPageReqVO pageReqVO) {
        pageReqVO.setUserId(getLoginUserId());
        PageResult<PtProfitLogRespVO> result = BeanUtils.toBean(ptProfitLogMapper.getMaxAmountPage(pageReqVO), PtProfitLogRespVO.class);
        for (PtProfitLogRespVO ptProfitLogRespVO : result.getList()) {
            if (ptProfitLogRespVO.getProfitStatus().equals(RECOMMENDED_PERSON_QUOTA.getType()) || ptProfitLogRespVO.getProfitStatus().equals(SMALL_QUOTA_CRASH.getType())) {
                ptProfitLogRespVO.setUsername(memberUserService.getUser(ptProfitLogRespVO.getGenerateUserId()).getUsername());
            }
            ptProfitLogRespVO.setProfitStatusName(Objects.requireNonNull(CaclEnum.getCaclEnumByValue(ptProfitLogRespVO.getProfitStatus())).getName());
        }
        return result;
    }

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

    /**
     * 添加一条用户积分日志消息
     *
     * @param userId
     * @param caclEnum
     * @param amount
     * @param afterAmount
     * @param freezeAmount
     * @param afterFreezeAmount
     * @param percentTemplate
     * @param tradeOrderId
     * @param OrderNum
     */
    @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)
                .userId(userId)
                .generateUserId(generateUserId)
                .profitStatus(caclEnum.getType()).orderId(tradeOrderId).orderNo(OrderNum)
                .freezeAmount(freezeAmount).afterFreezeAmount(afterFreezeAmount)
                .build();
        ptProfitLogMapper.insert(BeanUtils.toBean(ptProfitLog, PtProfitLogDO.class));

    }


    @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::getUserId, 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::getUserId, sonsId));
        Long sum = ptProfitLogDOS.stream().mapToLong(PtProfitLogDO::getAmount).sum();

        return sum + "";
    }

}