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.sequence.IdWorkerUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.AuthTypeDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.AuthType;
import com.red.circle.other.infra.database.rds.service.user.user.AuthTypeService;
import com.red.circle.other.inner.enums.user.AuthTypeEnum;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户认证信息 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2019-10-23
 */
@Service
@RequiredArgsConstructor
public class AuthTypeServiceImpl extends BaseServiceImpl<AuthTypeDAO, AuthType> implements
    AuthTypeService {

  @Override
  public void deleteAuth(Long userId) {
    update().set(AuthType::getDel, Boolean.TRUE)
        .eq(AuthType::getUserId, userId)
        .execute();
  }

  @Override
  public void restoreAuthDelByUserId(Long userId) {
    update().set(AuthType::getDel, Boolean.FALSE)
            .eq(AuthType::getUserId, userId)
            .execute();
  }

  @Override
  public void deleteLogicAuthType(Long userId, String type) {
    update().set(AuthType::getDel, Boolean.TRUE)
        .setSql(String.format("open_id=concat(open_id,'_',%s)", IdWorkerUtils.getId()))
        .eq(AuthType::getUserId, userId)
        .eq(AuthType::getType, type)
        .execute();
  }

  @Override
  public void deleteAuthType(Long userId, String type) {
    delete()
        .eq(AuthType::getUserId, userId)
        .eq(AuthType::getType, type)
        .execute();
  }

  @Override
  public AuthType getAuthInfo(String openId) {
    return query().eq(AuthType::getOpenId, openId).last(PageConstant.LIMIT_ONE).getOne();
  }

  @Override
  public AuthType getAuthInfo(String type, String openId) {
    return query()
        .eq(AuthType::getOpenId, openId)
        .eq(AuthType::getType, type)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public Boolean existsAuthType(Long userId, AuthTypeEnum authType) {
    return Optional.ofNullable(
        query().select(AuthType::getId)
            .eq(AuthType::getUserId, userId)
            .eq(AuthType::getType, authType)
            .eq(AuthType::getDel, Boolean.FALSE)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(auth -> Objects.nonNull(auth.getId())).orElse(Boolean.FALSE);
  }

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

  @Override
  public List<String> listUserAuthType(Long userId) {
    return Optional
        .ofNullable(query().select(AuthType::getType)
            .eq(AuthType::getUserId, userId)
            .eq(AuthType::getDel, Boolean.FALSE)
            .list())
        .map(authTypes -> authTypes.stream().map(AuthType::getType).collect(Collectors.toList()))
        .orElse(null);
  }


  @Override
  public List<AuthType> listByUserId(Long userId) {

    return query()
        .eq(AuthType::getDel, Boolean.FALSE)
        .eq(AuthType::getUserId, userId)
        .last(PageConstant.LIMIT_ONE)
        .list();
  }


  @Override
  public void saveUserAuthType(Long userId, String type, String openId) {

    AuthType authType = query()
        .eq(AuthType::getUserId, userId)
        .eq(AuthType::getType, type)
        .eq(AuthType::getDel, Boolean.FALSE)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    if (Objects.isNull(authType)) {

      save(new AuthType()
          .setUserId(userId)
          .setType(type)
          .setDel(Boolean.FALSE)
          .setOpenId(openId)
        );
      return;
    }
    authType.setOpenId(openId);
    updateSelectiveById(authType);
  }

  @Override
  public AuthType getAuthInfoByUserId(String type, Long userId) {
    return query().eq(AuthType::getUserId, userId)
        .eq(AuthType::getType, type)
        .last(PageConstant.LIMIT_ONE).getOne();
  }
}
