package com.jiayue.center.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiayue.center.config.SendMailUtil;
import com.jiayue.center.constant.CacheConstants;
import com.jiayue.center.constant.Constants;
import com.jiayue.center.entity.SysPolicy;
import com.jiayue.center.entity.SysUser;
import com.jiayue.center.factory.LoginFactory;
import com.jiayue.center.service.SysAlarmService;
import com.jiayue.center.service.SysPolicyService;
import com.jiayue.center.service.SysUserService;
import com.jiayue.center.util.LocalCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

/**
* 失败认证处理
* @author xsl
* @date 2023/2/16
*/
@Component("customAuthenticationFailureHandler")
@Slf4j
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysPolicyService sysPolicyService;
    @Autowired
    SysAlarmService sysAlarmService;
    @Autowired
    SendMailUtil sendMailUtil;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException e) throws IOException, ServletException {
        String errorTips = "";
        // 验证码验证
        String username = request.getParameter("username");
        SysUser user = sysUserService.queryUserName(username);
        if (user == null) {
            errorTips = "用户名或密码不正确";
        }
        else {
            SysPolicy sysPolicy = sysPolicyService.getOne(new QueryWrapper<>());
            // 失败总次数
            int errCount = sysPolicy.getLoginFails();
            // 锁定时长
            int lockedTime = sysPolicy.getLoginLock()*1000*60;
            if (user.getStatus().equals("1")) {
                Long xz = (user.getLockTime() + lockedTime - System.currentTimeMillis()) / 1000;
                if (xz < 0) {
                    if (errCount-1==0) {
                        errorTips = "用户锁定，稍后再试";
                        user.setErrNum(0);
                        user.setStatus("1");
                        user.setLockTime(System.currentTimeMillis());
                    }
                    else{
                        user.setStatus("0");
                        user.setErrNum(1);
                        errorTips = "用户名或密码不正确，还有"+(errCount-1)+"次机会";
                    }
                    sysUserService.updateUser(user);
                } else {
                    //锁定状态
                    errorTips = "用户已锁定,请隔" + xz + "秒再登录";
                }
            } else {
                int errNum = user.getErrNum();
                if (errNum < errCount-1) {
                    errorTips = "用户名或密码不正确，还有" + (errCount-1 - errNum) + "次机会";
                    errNum++;
                    user.setErrNum(errNum);
                    sysUserService.updateUser(user);
                } else {

                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "连续登录失败");
                    errorTips = "用户锁定，稍后再试";
                    user.setErrNum(0);
                    user.setStatus("1");
                    user.setLockTime(System.currentTimeMillis());
                    sysUserService.updateUser(user);
                }
            }
        }
        // 记录用户退出日志
        LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "登录失败");

        // 删除缓存邮箱口令
        LocalCache.remove(CacheConstants.MAIL_CODE_KEY + username);
        LocalCache.remove(CacheConstants.PREVENT_MAIL_CODE + username);
        // 清除
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setContentType("text/html;charset=UTF-8");
        response.setStatus(401);
        response.getWriter().write(errorTips);
    }
}
