package com.junmp.jyzb.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.junmp.jyzb.api.bean.dto.printDto.LoginV2Dto;
import com.junmp.jyzb.api.bean.req.PrintReq.LoginV2Req;
import com.junmp.jyzb.api.constant.JYZBConstant;
import com.junmp.jyzb.api.exception.JYZBAppException;
import com.junmp.jyzb.api.exception.enums.UserExceptionEnum;
import com.junmp.jyzb.cache.MsgRedisCache;
import com.junmp.jyzb.doc.LoginDoc;
import com.junmp.jyzb.entity.Policeman;
import com.junmp.jyzb.entity.PubOrg;
import com.junmp.jyzb.service.PolicemanService;
import com.junmp.jyzb.service.PubOrgService;
import com.junmp.v2.auth.api.bean.auth.LoginReq;
import com.junmp.v2.auth.api.bean.auth.LoginRes;
import com.junmp.v2.auth.api.bean.login.LoginUser;
import com.junmp.v2.auth.api.exception.AuthException;
import com.junmp.v2.auth.api.exception.AuthExceptionEnum;
import com.junmp.v2.auth.api.password.IStoredEncryptApi;
import com.junmp.v2.auth.sign.AuthContainer;
import com.junmp.v2.common.bean.response.ApiRes;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.sys.api.UserServiceApi;
import com.junmp.v2.sys.api.bean.user.UserLoginInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * <pre>
 *
 * 描述：登录服务
 * 版本：1.0.0
 * 日期：2022/6/7 13:47
 * 作者：ningzp@junmp.com.cn
 * <br>修改记录
 * <br>修改日期        修改人          修改内容
 *
 * </pre>
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class LoginController implements LoginDoc {

    @Resource
    private AuthContainer authContainer;


    @Resource
    private MsgRedisCache goldRedisCache ;
    @Resource
    private UserServiceApi userServiceApi;
    @Resource
    private IStoredEncryptApi iStoredEncryptApi;

    @Resource
    private MsgRedisCache redisCache;

    @Resource
    private PubOrgService pubOrgService;

    @Resource
    private PolicemanService policemanService;

    @PostMapping(name = "用户登录", path = "/auth/login")
    public ApiRes<LoginRes> login(@RequestBody LoginReq req) {
        //如果密码输错次数大于5次，那么直接锁定账号5分钟
        String s = redisCache.get(req.getAccount());
        long currentTime = System.currentTimeMillis();
        long windowDuration = 5 * 60 * 1000;
        String time="";
        if (ObjectUtil.isEmpty(s) || (ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5)){
            UserLoginInfoDto userValidateInfo = this.userServiceApi.getUserLoginInfo(req.getAccount());
            Boolean checkResult = this.iStoredEncryptApi.checkPassword(req.getPassword(), userValidateInfo.getHashUserPassword());
            if (!checkResult) {

                if (ObjectUtil.isEmpty(s)){
                    redisCache.put(req.getAccount(),"1"+(currentTime+windowDuration),(long)(5 * 60));
                }else {
                    String substring = s.substring(0, 1);
                    time = s.substring(1);
                    s=String.valueOf(Integer.parseInt(substring)+1);
                    redisCache.put(req.getAccount(),s+time,(long)(5 * 60));
                }
                //错误次数记录到redis，如果次数超过5次直接报错
                if (ObjectUtil.isEmpty(s) || ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5){

                    throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
                }else {
                    String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
                    throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
                }
            }else {
                if (ObjectUtil.isNotEmpty(s)){
                    redisCache.remove(req.getAccount());
                }
            }
        }else {
            time = s.substring(1);
            String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
            throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
        }
        LoginRes res = authContainer.login(req);
        if (null != res) {
            //配置扩展信息
            String jwt = goldRedisCache.get(JYZBConstant.JYZB_JWT_KEY);
            if(StrUtil.isEmpty(jwt)){
                goldRedisCache.put(JYZBConstant.JYZB_JWT_KEY,res.getToken());
            }
            return ApiRes.success(res);
        } else {
            return ApiRes.failure("登录失败");
        }
    }

    @PostMapping(name = "用户登出", path = "/auth/logout")
    public ApiRes<Boolean> logout(){
        authContainer.logout();
        log.info("登出成功");
        return ApiRes.success();
    }


//    @PostMapping(name = "用户登录", path = "/auth/loginV2")
////    @DecryptionRequired
//    public ApiRes<LoginRes> V2login(@RequestBody LoginV2Req req) {
//        //如果密码输错次数大于5次，那么直接锁定账号5分钟
//        String s = redisCache.get(req.getUsername());
//        long currentTime = System.currentTimeMillis();
//        long windowDuration = 5 * 60 * 1000;
//        String time="";
//        if (ObjectUtil.isEmpty(s) || (ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5)){
//            UserLoginInfoDto userValidateInfo = this.userServiceApi.getUserLoginInfo(req.getUsername());
//            Boolean checkResult = this.iStoredEncryptApi.checkPassword(req.getPassword(), userValidateInfo.getHashUserPassword());
//            if (!checkResult) {
//
//                if (ObjectUtil.isEmpty(s)){
//                    redisCache.put(req.getUsername(),"1"+(currentTime+windowDuration),(long)(5 * 60));
//                }else {
//                    String substring = s.substring(0, 1);
//                    time = s.substring(1);
//                    s=String.valueOf(Integer.parseInt(substring)+1);
//                    redisCache.put(req.getUsername(),s+time,(long)(5 * 60));
//                }
//                //错误次数记录到redis，如果次数超过5次直接报错
//                if (ObjectUtil.isEmpty(s) || ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5){
//
//                    throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
//                }else {
//                    String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
//                    throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
//                }
//            }else {
//                if (ObjectUtil.isNotEmpty(s)){
//                    redisCache.remove(req.getUsername());
//                }
//            }
//        }else {
//            time = s.substring(1);
//            String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
//            throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
//        }
//        LoginReq loginReq = new LoginReq();
//        BeanPlusUtil.copyProperties(req,loginReq);
//        loginReq.setAccount(req.getUsername());
//        LoginRes res = authContainer.login(loginReq);
//        if (null != res) {
//            //配置扩展信息
//            String jwt = goldRedisCache.get(JYZBConstant.JYZB_JWT_KEY);
//            if(StrUtil.isEmpty(jwt)){
//                goldRedisCache.put(JYZBConstant.JYZB_JWT_KEY,res.getToken());
//            }
//            return ApiRes.success(res);
//        } else {
//            return ApiRes.failure("登录失败");
//        }
//    }

    @PostMapping(name = "用户登录", path = "/auth/loginV2")
//    @DecryptionRequired
    public LoginV2Dto V2login(@RequestBody LoginV2Req req) {
        //如果密码输错次数大于5次，那么直接锁定账号5分钟
        String s = redisCache.get(req.getUsername());
        long currentTime = System.currentTimeMillis();
        long windowDuration = 5 * 60 * 1000;
        String time="";
        if (ObjectUtil.isEmpty(s) || (ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5)){
            UserLoginInfoDto userValidateInfo = this.userServiceApi.getUserLoginInfo(req.getUsername());
            Boolean checkResult = this.iStoredEncryptApi.checkPassword(req.getPassword(), userValidateInfo.getHashUserPassword());
            if (!checkResult) {

                if (ObjectUtil.isEmpty(s)){
                    redisCache.put(req.getUsername(),"1"+(currentTime+windowDuration),(long)(5 * 60));
                }else {
                    String substring = s.substring(0, 1);
                    time = s.substring(1);
                    s=String.valueOf(Integer.parseInt(substring)+1);
                    redisCache.put(req.getUsername(),s+time,(long)(5 * 60));
                }
                //错误次数记录到redis，如果次数超过5次直接报错
                if (ObjectUtil.isEmpty(s) || ObjectUtil.isNotEmpty(s) && Integer.parseInt(s.substring(0, 1))<5){

                    throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
                }else {
                    String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
                    throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
                }
            }else {
                if (ObjectUtil.isNotEmpty(s)){
                    redisCache.remove(req.getUsername());
                }
            }
        }else {
            time = s.substring(1);
            String msg="账号或密码错误次数太多，该账号已被锁定，请"+(((Long.parseLong(time)-currentTime)/1000/60)+1)+"分钟后重试";
            throw new JYZBAppException(UserExceptionEnum.USER_ERROR_OVER,msg);
        }
        LoginReq loginReq = new LoginReq();
        BeanPlusUtil.copyProperties(req,loginReq);
        loginReq.setAccount(req.getUsername());
        LoginRes res = authContainer.login(loginReq);
        LoginUser userInfo = res.getUserInfo();
        LoginV2Dto loginV2Dto = new LoginV2Dto();
        loginV2Dto.setId(userInfo.getUserId().toString());
        loginV2Dto.setUsername(userInfo.getAccount());
        loginV2Dto.setEnabled(true);
        PubOrg pubOrg = pubOrgService.PubOrgExist(userInfo.getOrgId());
        if (ObjectUtil.isNotNull(pubOrg)){
            LoginV2Dto.BaseJpOrganizationSmallDto baseJpOrgDto = new LoginV2Dto.BaseJpOrganizationSmallDto();
            baseJpOrgDto.setId(pubOrg.getOrgId().toString());
            baseJpOrgDto.setName(pubOrg.getOrgName());
            baseJpOrgDto.setDName(pubOrg.getDName());
            baseJpOrgDto.setCode(pubOrg.getOrgCode());
            baseJpOrgDto.setFindCode(pubOrg.getFindCode());
            baseJpOrgDto.setLatitude(pubOrg.getLatitude());
            baseJpOrgDto.setLongitude(pubOrg.getLongitude());
            baseJpOrgDto.setShow(pubOrg.getShowState());
            loginV2Dto.setBaseJpOrganization(baseJpOrgDto);

        }
        Policeman policeman = policemanService.getOne(new LambdaQueryWrapper<Policeman>().eq(Policeman::getUserId, userInfo.getUserId()).last("limit 1"));
        if (ObjectUtil.isNotNull(policeman)){
            LoginV2Dto.BaseJpPoliceman baseJpPoliceman = new LoginV2Dto.BaseJpPoliceman();
            baseJpPoliceman.setId(policeman.getId());
            baseJpPoliceman.setName(policeman.getName());
            baseJpPoliceman.setPoliceCode(policeman.getPoliceCode());
            loginV2Dto.setPoliceman(baseJpPoliceman);
        }
        if (null != res) {
            //配置扩展信息
            String jwt = goldRedisCache.get(JYZBConstant.JYZB_JWT_KEY);
            if(StrUtil.isEmpty(jwt)){
                goldRedisCache.put(JYZBConstant.JYZB_JWT_KEY,res.getToken());
            }
            return loginV2Dto;
        } else {
            return new LoginV2Dto();
        }
    }
}
