package com.jiayue.ssi.handler;

import java.io.IOException;
import java.util.List;

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.ssi.config.SendMailUtil;
import com.jiayue.ssi.constant.CacheConstants;
import com.jiayue.ssi.constant.Constants;
import com.jiayue.ssi.entity.SysAlarm;
import com.jiayue.ssi.entity.SysPolicy;
import com.jiayue.ssi.entity.SysUser;
import com.jiayue.ssi.factory.LoginFactory;
import com.jiayue.ssi.service.SysAlarmService;
import com.jiayue.ssi.service.SysPolicyService;
import com.jiayue.ssi.service.SysUserService;
import com.jiayue.ssi.util.AesUtils;
import com.jiayue.ssi.util.DateUtils;
import com.jiayue.ssi.util.IPUtils;
import com.jiayue.ssi.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);
                    String noticeWay = "";
                    if ("0".equals(sysPolicy.getExcLevelLogin())){
                        noticeWay = sysPolicy.getExcNoticeWayA();
                    } else if ("1".equals(sysPolicy.getExcLevelLogin())){
                        noticeWay = sysPolicy.getExcNoticeWayB();
                    }

                    // 通知系统管理员
                    if ("0".equals(noticeWay)){
                        log.info("发送邮箱连续登录失败\r\n" +
                                "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓邮箱内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓"+
                                "\r\n  账号："+user.getUsername()+"  连续登录失败："+errCount+"次，锁定账号！ \r\n"     +
                                "↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑邮箱内容↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
//                        log.info("发送邮箱通知系统管理员后台输出======> "+"账号【"+user.getUsername()+"】登录失败"+errCount+"次，锁定账号！");
//                        List<SysUser> sysUserList = sysUserService.selectUserByRole("1");
//                        if (sysUserList.size()>0){
//                            String[] mailArray = new String[sysUserList.size()];
//                            for (int i=0;i<sysUserList.size();i++){
//                                mailArray[i] = AesUtils.decryptStr(sysUserList.get(i).getMailbox());
//                            }
//                            try {
//                                // 发送邮件
//                                sendMailUtil.executeSendMail(mailArray,"账号【"+user.getUsername()+"】登录失败","账号【"+user.getUsername()+"】登录失败"+errCount+"次，锁定账号！");
//                            } catch (Exception ex) {
//                                System.out.println("邮箱验证码发送失败！");
//                            }
//                        }
                    }
                    else if ("1".equals(noticeWay)){
                        // 告警
                        SysAlarm sysAlarm = new SysAlarm();
                        sysAlarm.setAlarmContent("账号【"+user.getUsername()+"】登录失败"+errCount+"次，锁定账号！");
                        sysAlarm.setReadSign("0");
                        // 低于策略设定值则告警
                        sysAlarmService.save(sysAlarm);
                    }
                }
            }
        }
        // 记录用户退出日志
        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);
    }
}
