package com.wecloud.im.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.protobuf.ServiceException;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.enums.VerifySceneEnum;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.entity.User;
import com.wecloud.im.user.mapper.UserMapper;
import com.wecloud.im.user.param.ChangePhoneParam;
import com.wecloud.im.user.param.CheckPhoneParam;
import com.wecloud.im.user.param.ResetPasswordParam;
import com.wecloud.im.user.param.UserLoginParam;
import com.wecloud.im.user.param.UserRegisterParam;
import com.wecloud.im.ws.utils.RedisUtils;
import com.wecloud.utils.AesUtil;
import com.wecloud.utils.SnowflakeUtil;
import io.geekidea.springbootplus.framework.common.exception.BusinessException;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @Author wenzhida
 * @Date 2022/2/21 17:05
 * @Description 用户服务接口
 */
@Service
public class UserService extends BaseServiceImpl<UserMapper, User> {


    @Autowired
    private RedisUtils redisUtils;

    /**
     * 校验手机号码是否可使用
     * @param param
     */
    public Boolean checkPhone(CheckPhoneParam param) {
        User userExist = this.getOne(new QueryWrapper<User>().lambda()
                .eq(User::getPhone, param.getPhone()));
        if (userExist != null) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    /**
     * 注册用户
     * @param param
     */
    public String registerUser(UserRegisterParam param) {
        String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.REGISTER.getCode()).append(param.getPhone()).toString();
        this.verifySMSVerifyCode(param.getVerifyCode(), key);
        User userExist = this.getOne(new QueryWrapper<User>().lambda()
                .eq(User::getPhone, param.getPhone()));
        if (userExist != null) {
            throw new BusinessException("已存在此电话号码用户");
        }
        User user = new User();
        user.setId(SnowflakeUtil.getId());
        user.setPhone(param.getPhone());
        user.setPassword(AesUtil.encrypt(param.getPassword()));
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        this.save(user);
        return String.valueOf(user.getId());
    }

    /**
     * 用户登录
     * @param param
     */
    public String loginUser(UserLoginParam param) {
        User user = this.getOne(new QueryWrapper<User>().lambda()
                .eq(User::getPhone, param.getPhone()));
        if (!param.getPassword().equals(AesUtil.decrypt(user.getPassword()))) {
            throw new BusinessException("账户或密码错误");
        }
        return String.valueOf(user.getId());
    }

    /**
     * 重置密码
     * @param param
     */
    public void resetPassword(ResetPasswordParam param) {
        String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.RESET_PWD.getCode()).append(param.getPhone()).toString();
        this.verifySMSVerifyCode(param.getVerifyCode(), key);
        User user = this.getOne(new QueryWrapper<User>().lambda()
                .eq(User::getPhone, param.getPhone()));
        if (user == null) {
            throw new BusinessException("查无此用户");
        }
        user.setPassword(AesUtil.encrypt(param.getPassword()));
        this.updateById(user);
    }

    /**
     * 更换手机号码
     * @param param
     */
    public void changePhone(ChangePhoneParam param) {
        String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.CHANGE_PHONE.getCode()).append(param.getPhone()).toString();
        this.verifySMSVerifyCode(param.getVerifyCode(), key);
        User user = this.getOne(new QueryWrapper<User>().lambda()
                .eq(User::getId, param.getUserId()));
        if (user == null) {
            throw new BusinessException("查无此用户");
        }
        if (param.getPhone().equals(user.getPhone())) {
            throw new BusinessException("更换后的手机号码与当前手机号码一致，无需更换");
        }
        User userExist = this.getOne(new QueryWrapper<User>().lambda()
                .ne(User::getId, param.getUserId())
                .eq(User::getPhone, param.getPhone()));
        if (userExist != null) {
            throw new BusinessException("新手机号码已被注册");
        }
        user.setPhone(param.getPhone());
        this.updateById(user);
    }

    /**
     * 校验短信验证码
     * @param verifyCode
     * @param redisKey
     */
    public void verifySMSVerifyCode(String verifyCode, String redisKey) {
        String verifyCodeInRedis = redisUtils.getKey(redisKey);
        if (verifyCodeInRedis == null || !verifyCodeInRedis.equals(verifyCode)) {
            throw new BusinessException("短信验证码不正确");
        }
        redisUtils.delKey(redisKey);
    }

}
