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.num.NumConstant;
import com.red.circle.other.infra.database.rds.dao.user.user.ShieldBlackDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.ShieldBlack;
import com.red.circle.other.infra.database.rds.service.user.user.ShieldBlackService;
import com.red.circle.other.infra.enums.user.user.PullBlackEnum;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户屏蔽不喜欢 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2019-11-01
 */
@Service
public class ShieldBlackServiceImpl extends BaseServiceImpl<ShieldBlackDAO, ShieldBlack> implements
    ShieldBlackService {

  @Override
  public void saveShieldBlack(Long userId, Long shieldUserId) {
    ShieldBlack shieldBlack = query().eq(ShieldBlack::getUserId, userId)
        .eq(ShieldBlack::getShieldUserId, shieldUserId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
    if (Objects.isNull(shieldBlack)) {
      save(new ShieldBlack()
          .setUserId(userId)
          .setShieldUserId(shieldUserId)
          .setShieldUserId(shieldUserId));
    }
  }

  @Override
  public boolean checkShieldBlack(Long userId, Long shieldUserId) {
    return Optional.ofNullable(
            query().select(ShieldBlack::getId)
                .eq(ShieldBlack::getUserId, userId)
                .eq(ShieldBlack::getShieldUserId, shieldUserId)
                .last(PageConstant.LIMIT_ONE)
                .getOne())
        .map(shieldBlack -> Objects.nonNull(shieldBlack.getId()))
        .orElse(Boolean.FALSE);
  }

  @Override
  public void removeShieldBlack(Long userId, Long shieldUserId) {
    delete().eq(ShieldBlack::getUserId, userId)
        .eq(ShieldBlack::getShieldUserId, shieldUserId)
        .execute();
  }

  @Override
  public void removeShieldBlackBothSides(Long userId, Long shieldUserId) {
    delete().eq(ShieldBlack::getUserId, userId)
        .eq(ShieldBlack::getShieldUserId, shieldUserId)
        .execute();
    delete().eq(ShieldBlack::getUserId, shieldUserId)
        .eq(ShieldBlack::getShieldUserId, userId)
        .execute();
  }

  @Override
  public PullBlackEnum getBlackStatus(Long userId, Long blackUserId) {
    Map<Long, ShieldBlack> shieldBlackMap = mapBlack(userId, blackUserId);

    if (Objects.equals(shieldBlackMap.size(), NumConstant.TWO)) {
      return PullBlackEnum.BOTH_SIDES_PULL_BLACK;
    }

    if (Objects.nonNull(shieldBlackMap.get(userId))) {
      return PullBlackEnum.PULL_BLACK;
    }

    if (Objects.nonNull(shieldBlackMap.get(blackUserId))) {
      return PullBlackEnum.BE_PULL_BLACK;
    }

    return PullBlackEnum.NORMAL;
  }

  private Map<Long, ShieldBlack> mapBlack(Long userId, Long blackUserId) {
    return query()
        .and(and -> and.eq(ShieldBlack::getUserId, userId)
            .eq(ShieldBlack::getShieldUserId, blackUserId))
        .or(and -> and.eq(ShieldBlack::getUserId, blackUserId)
            .eq(ShieldBlack::getShieldUserId, userId))
        .list2Map(ShieldBlack::getUserId);
  }


  @Override
  public List<ShieldBlack> pageUserBlacklist(Long userId, Long lastId) {
    return Optional.ofNullable(query()
        .eq(ShieldBlack::getUserId, userId)
        .lt(Objects.nonNull(lastId), ShieldBlack::getId, lastId)
        .orderByDesc(ShieldBlack::getId)
        .last(PageConstant.DEFAULT_LIMIT)
        .list()).orElse(CollectionUtils.newArrayList());
  }


}
