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.other.infra.database.rds.dao.user.user.MobileAuthDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.MobileAuth;
import com.red.circle.other.infra.database.rds.service.user.user.MobileAuthService;
import com.red.circle.other.inner.model.dto.user.account.UserMobileUpdateCmd;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户手机号注册 服务实现类.
 * </p>
 *
 * @author pengliang
 * @since 2021-03-25
 */
@Service
@RequiredArgsConstructor
public class MobileAuthServiceImpl extends BaseServiceImpl<MobileAuthDAO, MobileAuth> implements
    MobileAuthService {

  private final PasswordEncoder passwordEncoder;

  @Override
  public void deleteLogicByUserId(Long userId) {
    update().set(MobileAuth::getDel, Boolean.TRUE).eq(MobileAuth::getUserId, userId)
        .last(PageConstant.LIMIT_ONE).execute();
  }

  @Override
  public void restoreLogicByUserId(Long userId) {
    update().set(MobileAuth::getDel, Boolean.TRUE).eq(MobileAuth::getUserId, userId)
            .last(PageConstant.LIMIT_ONE).execute();
  }

  @Override
  public void deleteByUserId(Long userId) {
    delete().eq(MobileAuth::getUserId, userId).execute();
  }

  @Override
  public MobileAuth getByPhone(Integer phonePrefix, String phoneNumber) {
    return query()
        .eq(MobileAuth::getDel, Boolean.FALSE)
        .eq(MobileAuth::getPhonePrefix, phonePrefix)
        .eq(MobileAuth::getPhoneNumber, phoneNumber)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public Long checkPasswordReturnUserId(Integer phonePrefix, String phoneNumber, String password) {
    return Optional.ofNullable(
            query().eq(MobileAuth::getDel, Boolean.FALSE)
                .eq(MobileAuth::getPhonePrefix, phonePrefix)
                .eq(MobileAuth::getPhoneNumber, phoneNumber)
                .last(PageConstant.LIMIT_ONE)
                .getOne()
        ).map(mobileAuth -> passwordEncoder.matches(password, mobileAuth.getPwd()) ? mobileAuth
            .getUserId() : null)
        .orElse(null);
  }

  @Override
  public boolean saveMobileAuth(MobileAuth mobileAuth) {
    mobileAuth.setPwd(passwordEncoder.encode(mobileAuth.getPwd()));
    return save(mobileAuth);
  }

  @Override
  public boolean resetPassword(Long id, String password) {
    return update().set(MobileAuth::getPwd, passwordEncoder.encode(password))
        .eq(MobileAuth::getDel, Boolean.FALSE)
        .eq(MobileAuth::getId, id)
        .last(PageConstant.LIMIT_ONE)
        .execute();

  }


  @Override
  public boolean updateUserMobileAuthPassword(UserMobileUpdateCmd param) {
    return update()
        .set(MobileAuth::getPwd, passwordEncoder.encode(param.getPwd()))
        .eq(MobileAuth::getUserId, param.getUserId())
        .eq(MobileAuth::getPhonePrefix, param.getPhonePrefix())
        .eq(MobileAuth::getPhoneNumber, param.getPhoneNumber())
        .execute();

  }


  @Override
  public Boolean addOrUpdateUserMobileAuth(UserMobileUpdateCmd param) {
    MobileAuth userMobileAuth = query().eq(MobileAuth::getUserId, param.getUserId())
        .eq(MobileAuth::getDel, Boolean.FALSE)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    if (Objects.isNull(userMobileAuth)) {
      MobileAuth auth = new MobileAuth()
          .setUserId(param.getUserId())
          .setPhonePrefix(param.getPhonePrefix())
          .setPhoneNumber(param.getPhoneNumber())
          .setPwd(passwordEncoder.encode(param.getPwd()));
      return save(auth);
    }

    userMobileAuth.setPhonePrefix(param.getPhonePrefix());
    userMobileAuth.setPhoneNumber(param.getPhoneNumber());
    userMobileAuth.setPwd(passwordEncoder.encode(param.getPwd()));

    return updateSelectiveById(userMobileAuth);

  }

  @Override
  public MobileAuth getByUserId(Long userId) {

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