package com.luojia_channel.modules.user.utils;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.luojia_channel.common.exception.UserException;
import com.luojia_channel.modules.user.dto.UserChangeInfoDTO;
import com.luojia_channel.modules.user.dto.UserRegisterDTO;
import com.luojia_channel.modules.user.entity.User;
import com.luojia_channel.modules.user.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ValidateUserUtil {
    // 参数校验正则表达式，学号校验不一定正确
    public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
    public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
    public static final String STUDENTID_REGEX = "^(?:\\d{12,13}|[A-Z]{2}\\d{8,10})$";
    public static final String PASSWORD_REGEX = "^\\w{6,32}$";
    private final UserMapper userMapper;

    /**
     * 用户手机号，邮箱，用户名三选一注册的参数校验
     * 可能需要前端在用户选择注册方式时只暴露出一个文本框
     * @param userRegisterDTO
     */
    public void validateRegisterUser(UserRegisterDTO userRegisterDTO) {
        String username = userRegisterDTO.getUsername();
        String password = userRegisterDTO.getPassword();
        String phone = userRegisterDTO.getPhone();
        String email = userRegisterDTO.getEmail();
        if (StrUtil.isBlank(password)){
            throw new UserException("密码不能为空");
        }

        // 前端做了校验后端还要校验，保证选择一种注册方式
        int cnt = 0;
        if(StrUtil.isNotBlank(phone)) cnt++;
        if(StrUtil.isNotBlank(email)) cnt++;
        if(StrUtil.isNotBlank(username)) cnt++;
        if (cnt == 0) {
            throw new UserException("必须填写手机号、邮箱或用户名其中一种注册方式");
        }
        if (cnt > 1) {
            throw new UserException("只能选择一种注册方式（手机/邮箱/用户名）");
        }
        // 格式校验
        validateFormats(userRegisterDTO);
    }


    // 格式校验，未来更改用户信息时可能使用
    public void validateFormats(UserRegisterDTO userRegisterDTO) {
        String username = userRegisterDTO.getUsername();
        String password = userRegisterDTO.getPassword();
        String phone = userRegisterDTO.getPhone();
        String email = userRegisterDTO.getEmail();
        // 仅对非空字段做格式校验
        if (userMapper.exists(Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, username))) {
            throw new UserException("用户名已存在");
        }
        if(!password.matches(PASSWORD_REGEX)){
            throw new UserException("密码格式错误");
        }
        validateUserFlag(phone, email, null);
    }

    public void validateFormats(UserChangeInfoDTO userChangeInfoDTO, Long currentUserId){
        String username = userChangeInfoDTO.getUsername();
        String phone = userChangeInfoDTO.getPhone();
        String email = userChangeInfoDTO.getEmail();
        // String college = userChangeInfoDTO.getCollege();
        if (userMapper.exists(Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, userChangeInfoDTO.getUsername())
                .ne(currentUserId != null, User::getId, currentUserId))) {
            throw new UserException("用户名已被使用");
        }

        validateUserFlag(phone, email, currentUserId);
    }

    private void validateUserFlag(String phone, String email,  Long currentUserId) {
        if(StrUtil.isNotBlank(phone)){
            if(!phone.matches(PHONE_REGEX))
                throw new UserException("手机号格式错误");
            if (userMapper.exists(Wrappers.<User>lambdaQuery()
                    .eq(User::getPhone, phone)
                    .ne(currentUserId != null, User::getId, currentUserId))) {
                throw new UserException("手机已存在");
            }
        }
        if(StrUtil.isNotBlank(email)){
            if(!email.matches(EMAIL_REGEX))
                throw new UserException("邮箱格式错误");
            if (userMapper.exists(Wrappers.<User>lambdaQuery()
                    .eq(User::getEmail, email)
                    .ne(currentUserId != null, User::getId, currentUserId))) {
                throw new UserException("邮箱已存在");
            }
        }
    }

}
