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.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.FriendshipCardDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.FriendshipCard;
import com.red.circle.other.infra.database.rds.service.user.user.FriendshipCardService;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户友谊关系卡 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2022-06-09
 */
@Service
public class FriendshipCardServiceImpl extends
    BaseServiceImpl<FriendshipCardDAO, FriendshipCard> implements FriendshipCardService {

  @Override
  public FriendshipCard getMaxUserByTypeByUserId(String type, Long userId) {

    List<FriendshipCard> userCards1 = listByTypeByAcceptUserId(type, userId);

    List<FriendshipCard> userCards2 = listByTypeBySendUserId(type, userId);

    if (CollectionUtils.isEmpty(userCards1) && CollectionUtils.isEmpty(userCards2)) {
      return null;
    }
    if (CollectionUtils.isEmpty(userCards1)) {
      FriendshipCard friendshipCard = userCards2.get(0);
      friendshipCard.setAcceptUserId(friendshipCard.getSendUserId());
      friendshipCard.setSendUserId(userId);
      return friendshipCard;
    }
    if (CollectionUtils.isEmpty(userCards2)) {
      return userCards1.get(0);
    }

    userCards1.forEach(card -> {

      FriendshipCard card2 = userCards2.stream()
          .filter(card2Tmp -> Objects.equals(card2Tmp.getAcceptUserId(), card.getSendUserId()))
          .findAny().orElse(null);

      if (Objects.isNull(card2)) {
        return;
      }
      card.setFriendshipValue(card.getFriendshipValue().add(card2.getFriendshipValue()));
    });

    if (CollectionUtils.isEmpty(userCards1)) {
      return null;
    }

    return userCards1.stream()
        .sorted(Comparator.comparing(FriendshipCard::getFriendshipValue).reversed())
        .collect(Collectors.toList()).get(0);

  }

  private List<FriendshipCard> listByTypeByAcceptUserId(String type, Long userId) {
    return query()
        .eq(FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getAcceptUserId, userId)
        .orderByDesc(FriendshipCard::getFriendshipValue)
        .last(PageConstant.formatLimit(500))
        .list();
  }

  private List<FriendshipCard> listByTypeBySendUserId(String type, Long userId) {
    return query()
        .eq(FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getSendUserId, userId)
        .orderByDesc(FriendshipCard::getFriendshipValue)
        .last(PageConstant.formatLimit(500))
        .list();
  }

  @Override
  public List<FriendshipCard> pageByCondition(Integer pageNumber, String type, Long userId) {

    if (Objects.isNull(pageNumber) || pageNumber < 1) {
      pageNumber = 1;
    }

    return query()
        .eq(StringUtils.isNotBlank(type), FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getAcceptUserId, userId)
        .orderByDesc(FriendshipCard::getFriendshipValue)
        .last(getPageSql(pageNumber))
        .list();

  }

  private String getPageSql(Integer pageNumber) {
    return String.format("LIMIT %s, %s", (pageNumber - 1) * PageConstant.DEFAULT_LIMIT_SIZE,
        PageConstant.DEFAULT_LIMIT_SIZE);
  }

  @Override
  public Boolean exist(String type, Long sendUserId, Long acceptUserId) {

    return Objects.nonNull(query()
        .eq(FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getAcceptUserId, acceptUserId)
        .eq(FriendshipCard::getSendUserId, sendUserId)
        .last(PageConstant.LIMIT_ONE)
        .getOne());
  }

  @Override
  public FriendshipCard getByCondition(String type, Long sendUserId, Long acceptUserId) {

    return query()
        .eq(FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getAcceptUserId, acceptUserId)
        .eq(FriendshipCard::getSendUserId, sendUserId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public Boolean deleteByCondition(String type, Long sendUserId, Long acceptUserId) {

    return delete()
        .eq(FriendshipCard::getCardType, type)
        .eq(FriendshipCard::getAcceptUserId, acceptUserId)
        .eq(FriendshipCard::getSendUserId, sendUserId)
        .execute();
  }

  @Override
  public List<FriendshipCard> listByCondition(Long sendUserId, Long acceptUserId) {

    return query()
        .eq(FriendshipCard::getAcceptUserId, acceptUserId)
        .eq(FriendshipCard::getSendUserId, sendUserId)
        .orderByDesc(FriendshipCard::getFriendshipValue)
        .last(PageConstant.formatLimit(5))
        .list();
  }

  @Override
  public List<FriendshipCard> listByCondition(Long sendUserId, Collection<Long> acceptUserIds) {

    return query()
        .in(FriendshipCard::getAcceptUserId, acceptUserIds)
        .eq(FriendshipCard::getSendUserId, sendUserId)
        .orderByDesc(FriendshipCard::getFriendshipValue)
        .last(PageConstant.formatLimit(acceptUserIds.size() * 6))
        .list();
  }

}
