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

import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.newfeifan.mall.module.distri.controller.admin.ptprofitlog.vo.PtProfitLogPageReqVO;
import cn.newfeifan.mall.module.distri.controller.admin.ptprofitlog.vo.PtProfitLogRespVO;
import cn.newfeifan.mall.module.distri.controller.admin.ptprofitlog.vo.PtProfitLogSaveReqVO;
import cn.newfeifan.mall.module.distri.dal.dataobject.ptprofitlog.PtProfitLogDO;
import cn.newfeifan.mall.module.distri.dal.mysql.ptprofitlog.PtProfitLogMapper;
import cn.newfeifan.mall.module.distri.enums.CaclEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

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

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

    @Resource
    private PtProfitLogMapper ptProfitLogMapper;

    @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()) {
//            ptProfitLogRespVO.setProfitStatusName(Objects.requireNonNull(CaclEnum.getCaclEnumByValue(ptProfitLogRespVO.getProfitStatus())).getName());
//        }

        return null;
    }

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

    @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));

    }

    /**
     * 添加一条用户积分日志消息
     * @param userId 用户id
     * @param caclEnum 计算类型
     * @param amount 可用积分
     * @param afterAmount 变动后积分
     * @param freezeAmount 冻结积分
     * @param afterFreezeAmount 变动和冻结积分
     * @param percentTemplate 模板
     * @param tradeOrderId 订单id
     * @param OrderNum 订单编号
     */
    @Override
    public void addMessage(Long generateUserId,//导致产生积分变动的用户ID
            Long userId, CaclEnum caclEnum, Long amount, Long afterAmount,
                           Long freezeAmount, Long afterFreezeAmount,
                           String percentTemplate,
                           Long tradeOrderId,
                           String OrderNum,
                           Long maxAvailablePointsAmount ,
                           Long afterMaxAvailablePointsAmount
    ) {
        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)
                .maxAvailablePointsAmount(maxAvailablePointsAmount)
                .afterMaxAvailablePointsAmount(afterMaxAvailablePointsAmount)
                .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 + "";
    }

    @Override
    public PtProfitLogDO selectProfitLogByUserIdWithProfitStatus(Long userId, Integer type, String orderNum) {
        return ptProfitLogMapper.selectOne(PtProfitLogDO::getUserId,userId,PtProfitLogDO::getProfitStatus,type,PtProfitLogDO::getOrderNo,orderNum);
    }

}