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

import java.time.LocalDateTime;
import java.util.*;
import javax.validation.*;
import cn.newfeifan.mall.module.distri.controller.admin.integral.vo.*;
import cn.newfeifan.mall.module.distri.dal.dataobject.integral.IntegralDO;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.module.distri.enums.CaclEnum;
import cn.newfeifan.mall.module.distri.enums.ConsumptionEnum;

/**
 * 推荐用户积分 Service 接口
 *
 * @author 非繁人
 */
public interface IntegralService {

    /**
     * 创建推荐用户积分
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    Long createIntegral(@Valid IntegralSaveReqVO createReqVO);

    /**
     * 更新推荐用户积分
     *
     * @param updateReqVO 更新信息
     */
    void updateIntegral(@Valid IntegralSaveReqVO updateReqVO);

    /**
     * 删除推荐用户积分
     *
     * @param id 编号
     */
    void deleteIntegral(Long id);

    /**
     * 获得推荐用户积分
     *
     * @param id 编号
     * @return 推荐用户积分
     */
    IntegralDO getIntegral(Long id);

    /**
     * 获得推荐用户积分分页
     *
     * @param pageReqVO 分页查询
     * @return 推荐用户积分分页
     */
    PageResult<IntegralDO> getIntegralPage(IntegralPageReqVO pageReqVO);

    /**
     * 根据用户ID查询是否有钱包
     * @param descendant 用户id
     * @return 钱包
     */
    IntegralDO selectByUser(Long descendant);


    void saveBatch(List<IntegralSaveReqVO> integralSaveReqVOS);

    /**
     * 批量修改以用户积分
     * @param integralSaveReqVOS
     */
    void updateBatch(List<IntegralSaveReqVO> integralSaveReqVOS);


    /**
     * 查询当前用户的父亲的积分信息
     * @param userId
     * @return
     */
    IntegralDO selectUserParent(Long userId);



    List<IntegralDO> selectAllUser();

    IntegralDO getIntegralByUserId(Long userId);

    /**
     * 修改用户身价
     *
     * @param generateUserId       导致产生积分变动的用户ID
     * @param userId               身价变动类别
     * @param caclEnum             变化类型
     * @param totalFreezeHighQuota 冻结峰值
     * @param tradeOrderId         订单ID
     * @param orderNum             订单号
     * @param payTime
     */
    void updateIntegralFreezeHighQuota(Long generateUserId, Long userId, CaclEnum caclEnum, Long totalFreezeHighQuota, Long tradeOrderId, String orderNum, LocalDateTime payTime);

    /**
     * 修改用户身价
     * @param generateUserId 导致产生积分变动的用户ID
     * @param userId 身价变动类别
     * @param caclEnum 变化类型
     * @param totalFreezeHighQuota 冻结峰值
     * @param tradeOrderId 订单ID
     * @param orderNum 订单号
     */
    void updateIntegralFreezeHighQuota(Long generateUserId, Long userId, CaclEnum caclEnum, Long totalFreezeHighQuota, Long tradeOrderId, String orderNum);

    /**
     * 初始化累计积分峰值
     */
    void initializeIntegralHighQuotaTotal();

    /**
     * 修改用户积分
     * @param userId 用户ID
     * @param caclEnum 变化类型
     * @param payIntegral 变化积分
     * @param tradeOrderId 订单ID
     * @param orderNum 订单号
     */
    void updateUserIntegral(Long userId, CaclEnum caclEnum, Long payIntegral, Long tradeOrderId, String orderNum);

    /**
     * 修改用户积分
     *
     * @param generateUserId 导致产生积分变动的用户ID
     * @param userId 要修改积分的用户
     * @param caclEnum 导致积分变化的事件类型枚举
     * @param amount 用户积分变化金额，可为负数
     * @param freezeAmount 用户冻结积分变化金额，可为负数
     * @return 返回是否执行成功。执行失败，通常是就是用户积分不足，没积分抵扣
     */
    Boolean updateUserIntegral(Long generateUserId,//导致产生积分变动的用户ID
                               Long userId, CaclEnum caclEnum, Long amount, Long freezeAmount,
                               Long tradeOrderId,
                               String orderNum
    );

    void calcIntegral();

    /**
     * 修改用户消费积分
     * @param userId 用户id
     * @param consumptionEnum 类型
     * @param consumptionPoints 消费分
     * @param orderId 订单id
     * @param orderNum 订单号
     */
    void updateUserConsumptionPoints(Long userId, ConsumptionEnum consumptionEnum, Long consumptionPoints, Long orderId, String orderNum);
}