package com.red.circle.other.infra.database.rds.service.user.user.impl;


import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.ConsumptionLevelDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.ConsumptionLevel;
import com.red.circle.other.infra.database.rds.service.user.user.ConsumptionLevelService;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户消费等级 服务实现类.
 * </p>
 *
 * @author pengliang
 * @since 2021-03-26
 */
@Service
public class ConsumptionLevelServiceImpl extends
    BaseServiceImpl<ConsumptionLevelDAO, ConsumptionLevel> implements ConsumptionLevelService {

  @Override
  public ConsumptionLevel getByUserId(Long userId) {
    return query().eq(ConsumptionLevel::getUserId, userId).last(PageConstant.LIMIT_ONE).getOne();
  }

  @Override
  public void createConsumption(Long userId) {
    save(new ConsumptionLevel()
        .setUserId(userId)
        .setConsumptionGolds(BigDecimal.ZERO)
        .setConsumptionDiamond(BigDecimal.ZERO)
    );
  }

  @Override
  public void incrConsumptionGolds(Long userId, BigDecimal quantity) {
    if (!exists(userId)) {
      save(new ConsumptionLevel()
          .setUserId(userId)
          .setConsumptionGolds(quantity)
      );
      return;
    }

    update().set(ConsumptionLevel::getUpdateTime, TimestampUtils.now())
        .setSql("consumption_golds=consumption_golds+" + quantity)
        .eq(ConsumptionLevel::getUserId, userId)
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public BigDecimal getConsumptionGolds(Long userId) {
    if(userId==1807604920249827329L||userId ==1808800573464178690L){
      return BigDecimal.ZERO;
    }
    return Optional.ofNullable(
            query().select(ConsumptionLevel::getConsumptionGolds)
                .eq(ConsumptionLevel::getUserId, userId)
                .last(PageConstant.LIMIT_ONE)
                .getOne()
        ).map(ConsumptionLevel::getConsumptionGolds)
        .orElse(BigDecimal.ZERO);
  }

  @Override
  public void incrConsumptionDiamond(Long userId, BigDecimal quantity) {

    if (!exists(userId)) {
      save(new ConsumptionLevel()
          .setUserId(userId)
          .setConsumptionDiamond(quantity)
      );
      return;
    }

    update().set(ConsumptionLevel::getUpdateTime, TimestampUtils.now())
        .setSql("consumption_diamond=consumption_diamond+" + quantity)
        .eq(ConsumptionLevel::getUserId, userId)
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public BigDecimal getConsumptionDiamond(Long userId) {
    if(userId == 1807604920249827329L||userId ==1808800573464178690L){
      return BigDecimal.ZERO;
    }
    return Optional.ofNullable(
            query().select(ConsumptionLevel::getConsumptionDiamond)
                .eq(ConsumptionLevel::getUserId, userId)
                .last(PageConstant.LIMIT_ONE)
                .getOne()
        ).map(ConsumptionLevel::getConsumptionDiamond)
        .orElse(BigDecimal.ZERO);
  }

  private boolean exists(Long userId) {
    return Optional.ofNullable(
            query().select(ConsumptionLevel::getUserId)
                .eq(ConsumptionLevel::getUserId, userId)
                .last(PageConstant.LIMIT_ONE).getOne())
        .map(consumptionLevel -> Objects.nonNull(consumptionLevel.getUserId()))
        .orElse(Boolean.FALSE);
  }

}
