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

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.props.FragmentsBackpackDAO;
import com.red.circle.other.infra.database.rds.entity.props.FragmentsBackpack;
import com.red.circle.other.infra.database.rds.service.props.FragmentsBackpackService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户碎片背包 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2022-03-15
 */
@Service
public class FragmentsBackpackServiceImpl extends
    BaseServiceImpl<FragmentsBackpackDAO, FragmentsBackpack> implements
    FragmentsBackpackService {

  @Override
  public FragmentsBackpack incrFragments(Long userId, Long fragmentsId, Integer quantity,
      String type) {

    FragmentsBackpack fragmentsBackpack = getFragments(userId, fragmentsId);

    if (Objects.isNull(fragmentsBackpack)) {
      FragmentsBackpack saveData = new FragmentsBackpack()
          .setFragmentsId(fragmentsId)
          .setDel(Boolean.FALSE)
          .setUserId(userId)
          .setType(type)
          .setQuantity(quantity.longValue());
      save(saveData);
      return saveData;
    }

    update().set(FragmentsBackpack::getUpdateTime, TimestampUtils.now())
        .setSql("quantity=quantity+" + quantity)
        .eq(FragmentsBackpack::getFragmentsId, fragmentsId)
        .eq(FragmentsBackpack::getUserId, userId)
        .last(PageConstant.LIMIT_ONE)
        .execute();
    fragmentsBackpack.setQuantity(fragmentsBackpack.getQuantity() + quantity);
    return fragmentsBackpack;
  }

  @Override
  public boolean decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
    if (Objects.isNull(userId) || CollectionUtils.isEmpty(fragmentsIds) || quantity <= 0) {
      return false;
    }

    return update().set(FragmentsBackpack::getUpdateTime, TimestampUtils.now())
        .setSql("quantity=quantity-" + quantity)
        .in(FragmentsBackpack::getFragmentsId, fragmentsIds)
        .eq(FragmentsBackpack::getUserId, userId)
        .last(PageConstant.formatLimit(fragmentsIds.size()))
        .execute();
  }

  @Override
  public List<FragmentsBackpack> listByUserIdByFragmentsIds(Long userId, Set<Long> fragmentsIds) {

    return Optional.ofNullable(query().eq(FragmentsBackpack::getUserId, userId)
            .in(FragmentsBackpack::getFragmentsId, fragmentsIds)
            .gt(FragmentsBackpack::getQuantity, 0)
            .last(PageConstant.formatLimit(fragmentsIds.size()))
            .orderByAsc(FragmentsBackpack::getQuantity)
            .list())
        .orElse(CollectionUtils.newArrayList());

  }

  private FragmentsBackpack getFragments(Long userId, Long fragmentsId) {
    return query().eq(FragmentsBackpack::getUserId, userId)
        .eq(FragmentsBackpack::getFragmentsId, fragmentsId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

}
