package com.jeequan.jeepay.bizcommons.manage.auth;

import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.jwt.JWTPayload;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBsecurityConfig;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.db.entity.AgentInfo;
import com.jeequan.jeepay.service.impl.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/***
 * 登录校验管理
 *
 * @author zx
 * @date 2022/5/17 10:34
 */
@Slf4j
@Component
public class AuthManage {

    @Autowired private SysConfigService sysConfigService;

    /** 防穷举验证  **/
    public void loginErrValidate(String sysType, String username) {

        DBsecurityConfig dbSecurityConfig = sysConfigService.getDBSecurityConfig();
        if (dbSecurityConfig.getLoginErrorMaxLimit().getErrMax() == 0) {
            return;
        }

        String failPassCacheKey = CS.getCacheKeyLoginErr(sysType, username);
        String failCount = RedisUtil.getString(failPassCacheKey);
//        if(StringUtils.isNotEmpty(failCount) && Integer.parseInt(failCount) >= dbSecurityConfig.getLoginErrorMaxLimit().getErrMax()){ //已经 临时锁定
//            throw new BizException("密码输入错误次数超限，请稍后再试");
//        }
    }

    /** 防穷举累加    还可尝试x次，失败将锁定x分账 **/
    public void loginErrCount(String sysType, String username) {

        DBsecurityConfig dbSecurityConfig = sysConfigService.getDBSecurityConfig();
        if (dbSecurityConfig.getLoginErrorMaxLimit().getErrMax() == 0) {
            throw new BizException("用户名/密码错误");
        }

        String failPassCacheKey = CS.getCacheKeyLoginErr(sysType, username);

        //累加缓存统计数据
        long failCountL = RedisUtil.increment(failPassCacheKey, 1);
        RedisUtil.expire(failPassCacheKey, dbSecurityConfig.getLoginErrorMaxLimit().getLimitMinute(), TimeUnit.MINUTES); //缓存x分钟

        if(failCountL >= dbSecurityConfig.getLoginErrorMaxLimit().getErrMax()){ //超过xx次
            throw new BizException("密码输入错误次数超限，请稍后再试");
        }else{
            throw new BizException("用户名/密码错误，还可尝试" + ( dbSecurityConfig.getLoginErrorMaxLimit().getErrMax() - failCountL ) + "次，失败将锁定"
                    + dbSecurityConfig.getLoginErrorMaxLimit().getLimitMinute() + "分钟");
        }
    }


    /** 密码过期的过滤器，  返回： true: 已过期，请直接return,  false，正常请求  */
    public static boolean passwordExpiredFilter(JeeUserDetails jeeUserDetails, HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 系统不强制更改
        if(!SysConfigService.PWD_EXPIRED_MUST_RESET){
            return false;
        }

        // 如果密码认证 && 密码已过期
        if( JWTPayload.CREDENTIAL_AUTH_TYPE.PASSWD.equals(jeeUserDetails.getAuthType()) &&
                jeeUserDetails.getSysUser().getPwdExpiredTime() != null && jeeUserDetails.getSysUser().getPwdExpiredTime().compareTo(new Date()) <= 0) {

            String requestURI = request.getRequestURI();

            // 查询用户信息 修改密码，可操作
            if(requestURI.indexOf("/api/current/user") >= 0 || requestURI.indexOf("/api/current/modifyPwd") >= 0){
                return false;
            }

            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().println(ApiRes.fail(ApiCodeEnum.SYS_USER_PWD_EXPIRED).toJSONString());
            response.getWriter().flush();
            return true;
        }

        return false;
    }

    /** 服务商未审核过滤器，  返回： true: 未过审，请直接return,  false，正常请求  */
    public static boolean agentUnAuditFilter(JeeUserDetails jeeUserDetails, HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 如果当前服务商状态为待审核/审核驳回 跳转至资料
        if(jeeUserDetails.getInfoState() == AgentInfo.AUDIT_STATE_ING || jeeUserDetails.getInfoState() == AgentInfo.AUDIT_STATE_FALSE
                || jeeUserDetails.getInfoState() == AgentInfo.AUDIT_STATE_UN_AUTH) {

            String requestURI = request.getRequestURI();

            // 查询用户信息、退出登录、修改密码、文件上传、信息修改->可操作
            if(requestURI.indexOf("/api/current/user") >= 0 || requestURI.indexOf("/api/current/logout") >= 0 ||requestURI.indexOf("/api/mainChart") >= 0
                    || requestURI.indexOf("/api/ossFiles/form") >= 0 || requestURI.indexOf("/api/ossFiles/singleFile") >= 0 || requestURI.indexOf("/api/sysUsers/audit") >= 0){
                return false;
            }

            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().println(ApiRes.fail(ApiCodeEnum.SYS_USER_UN_AUDIT).toJSONString());
            response.getWriter().flush();
            return true;
        }

        return false;
    }

}
