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

import com.google.common.collect.Lists;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.gift.GiftWallDAO;
import com.red.circle.other.infra.database.rds.entity.gift.GiftWall;
import com.red.circle.other.infra.database.rds.service.gift.GiftWallService;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户获得礼物梳理 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2021-01-12
 */
@Service
@RequiredArgsConstructor
public class GiftWallServiceImpl extends BaseServiceImpl<GiftWallDAO, GiftWall> implements
    GiftWallService {

  @Override
  public void incrGiftWall(Long userId, Long giftId, Long giftQuantity) {
    GiftWall giftWall = getUserGift(userId, giftId);
    if (Objects.isNull(giftWall)) {
      try {
        if (Objects.isNull(userId) || Objects.isNull(giftId)) {
          log.warn("异常数据： " + userId + giftId);
          return;
        }
        save(new GiftWall()
            .setUserId(userId)
            .setGiftId(giftId)
            .setQuantity(giftQuantity)
        );
      } catch (DuplicateKeyException ignore) {
        // ignore
      }
      return;
    }
    incr(giftWall.getId(), giftQuantity);
  }

  @Override
  public void decrGiftWall(Long userId, Long giftId, Long giftQuantity) {
    decr(userId, giftId, giftQuantity);
  }

  private GiftWall getUserGift(Long userId, Long giftId) {
    return query()
        .eq(GiftWall::getUserId, userId)
        .eq(GiftWall::getGiftId, giftId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public List<GiftWall> listTopByUserId(Long userId) {
    return Optional.ofNullable(userId)
        .map(uid -> query()
            .eq(GiftWall::getUserId, uid)
            .last(PageConstant.formatLimit(300))
            .orderByDesc(GiftWall::getQuantity)
            .list())
        .orElseGet(Lists::newArrayList);
  }

  private void incr(Long id, Long giftQuantity) {
    update().setSql("quantity=quantity+" + giftQuantity)
        .eq(GiftWall::getId, id)
        .execute();
  }

  private void decr(Long userId, Long giftId, Long giftQuantity) {
    GiftWall giftWall = query().eq(GiftWall::getUserId, userId)
        .eq(GiftWall::getGiftId, giftId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    if (Objects.isNull(giftWall)) {
      return;
    }

    if (giftWall.getQuantity() >= giftQuantity) {
      update().setSql("quantity=quantity-" + giftQuantity)
          .eq(GiftWall::getUserId, userId)
          .eq(GiftWall::getGiftId, giftId)
          .execute();
      return;
    }

    delete().eq(GiftWall::getUserId, giftWall.getId()).execute();
  }

  @Override
  public List<GiftWall> listGiftWallByUser(Long userId) {
    return query().eq(GiftWall::getUserId, userId).list();
  }

}
