package com.njzscloud.common.security.module.code;

import cn.hutool.core.lang.Assert;
import com.njzscloud.common.core.ex.ExceptionMsg;
import com.njzscloud.common.security.contant.AuthWay;
import com.njzscloud.common.security.ex.UserLoginException;
import com.njzscloud.common.security.module.password.PasswordLoginForm;
import com.njzscloud.common.security.support.*;
import lombok.RequiredArgsConstructor;

import java.util.Set;

/**
 * 验证码登录认证器
 */
@RequiredArgsConstructor
public class CodeAuthenticationProvider extends AbstractAuthenticationProvider {
    private final IUserService iUserService;
    private final IRoleService iRoleService;
    private final VerificationCodeService verificationCodeService;

    /**
     * 读取用户信息
     *
     * @param loginForm 登录表单
     * @return 用户信息
     */
    @Override
    protected UserDetail retrieveUser(LoginForm loginForm) throws UserLoginException {
        CodeLoginForm codeLoginForm = (CodeLoginForm) loginForm;
        String phone = codeLoginForm.getPhone();
        UserDetail userDetail = iUserService.selectUser(codeLoginForm);
        if (userDetail == null) throw new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "账号不存在");
        Long userId = userDetail.getUserId();
        Set<String> roles = iRoleService.selectRoleByUserId(userId);
        return userDetail
                .setAuthWay(AuthWay.PASSWORD)
                .setRoles(roles)
                ;
    }

    @Override
    protected void afterCheck(LoginForm loginForm, UserDetail userDetail) throws UserLoginException {
        CodeLoginForm codeLoginForm = (CodeLoginForm) loginForm;
        String codeId = codeLoginForm.getCodeId();
        String code = codeLoginForm.getCode();
        Assert.isTrue(verificationCodeService.checkCode(codeId, code), () -> new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "验证码错误"));
    }

    /**
     * 获取登录表单类型
     *
     * @return 登录表单类型
     * @see PasswordLoginForm
     */
    @Override
    protected Class<?> getLoginFormClazz() {
        return CodeLoginForm.class;
    }
}
