package com.winsun.item.modular.intercept;

import com.alibaba.fastjson.JSON;
import com.winsun.auth.core.common.model.ResponseData;
import com.winsun.auth.core.shiro.ShiroUser;
import com.winsun.item.core.shiro.ShiroKit;
import com.winsun.item.core.util.IPUtils;
import com.winsun.item.modular.system.service.IUserService;
import com.winsun.item.util.LoginUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author xuede
 * @Date 2020/2/29 16:07
 * @Version 1.0
 */
@Component
@Slf4j
public class LoginInterceptor extends HandlerInterceptorAdapter {


    //登录验证码标识
    private static String CODE = "getPhoneCode";

    @Autowired
    public StringRedisTemplate stringRedisTemplate;


    //登录验证码标识
    private static String LOGINFLAG="alreadyLoginFlag";

    @Autowired
    private IUserService userService;

    private static String GETPHONECODE = "getPhoneCode";

    //5分钟内有效
    private static long CODETIME = 1000 * 60 * 5;

    //短信验证码错误key
    private static String ERRCODENAME = "ERRCODENAME";
    //短信验证码输入错误次数
    private static int ERRACCOUNT = 10;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        Object openId = request.getParameter("openId");
        if (openId != null) {
            return true;
        }
        Map<String, Object> map = new HashMap<>();
        Object verificationCode = request.getParameter("verificationCode");
        if (verificationCode != null) {
            String str = stringRedisTemplate.opsForValue().get(request.getParameter("username").trim() + GETPHONECODE);
            if (StringUtils.isBlank(str)) {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/html;charset=utf-8");
                PrintWriter writer = response.getWriter();
                log.info("获取redis 手机验证码失败");
                map.put("code", 500);
                map.put("message", "请再次获取手机验证码");
                Object toJSON = JSON.toJSON(map);
                writer.write(toJSON.toString());
                return false;
            } else {
                if (!str.equals(verificationCode.toString())) {
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("text/html;charset=utf-8");
                    PrintWriter writer = response.getWriter();
                    map.put("code", 500);
                    map.put("message", "验证码错误");
                    Object toJSON = JSON.toJSON(map);
                    writer.write(toJSON.toString());
                    return false;
                }
            }
            return true;
        }
        Object username = request.getParameter("username");
        if (username == null) {
            return false;
        }
        //短信验证码
        if (request.getParameter("phonecode") == null) {
            //new ErrorTip(500, "短信验证码不能为空！");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            map.put("code", 500);
            map.put("message", "短信验证码不能为空");
            Object toJSON = JSON.toJSON(map);
            writer.write(toJSON.toString());
            return false;
        }
        String phonecode = request.getParameter("phonecode").trim();
        ResponseData<String> phonecodeDecrypt = LoginUtils.pwdDecrypt(phonecode);
        if (!phonecodeDecrypt.isSuccess()) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //new ErrorTip(500, "短信验证码不能为空！");
            map.put("code", 500);
            map.put("message", "短信验证码不能为空");
            Object toJSON = JSON.toJSON(map);
            writer.write(toJSON.toString());
            return false;
        }

        //存放redis验证码
        String rediscode = stringRedisTemplate.opsForValue().get(username + CODE);
        if (StringUtils.isBlank(rediscode)) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            log.info("获取redis 手机验证码失败");
            //new ErrorTip(500, "请再次获取手机验证码");
            map.put("code", 500);
            map.put("message", "请再次获取手机验证码");
            Object toJSON = JSON.toJSON(map);
            writer.write(toJSON.toString());
            return false;
        }
        phonecode = phonecodeDecrypt.getData();
        if (!rediscode.equals(phonecode)) {
            log.info("获取redis数据和 手机验证码不一致，用户名：{} redis存放验证码: {} 用户输入验证码: {}", username, rediscode, phonecode);
            String errcount = stringRedisTemplate.opsForValue().get(ERRCODENAME + username);
            if (StringUtils.isBlank(errcount)) {
                errcount = "1";
                stringRedisTemplate.opsForValue().set(ERRCODENAME + username, errcount);
            } else if (Integer.valueOf(errcount) < ERRACCOUNT) {
                errcount = String.valueOf(Integer.valueOf(errcount) + 1);
                stringRedisTemplate.opsForValue().set(ERRCODENAME + username, errcount);
            } else if (Integer.valueOf(errcount) == ERRACCOUNT) {
                errcount = String.valueOf(ERRACCOUNT);
                String code = username + CODE;
                stringRedisTemplate.delete(code);
                stringRedisTemplate.delete(ERRCODENAME + username);
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            map.put("code", 500);
            map.put("message", "登录失败,手机验证码第" + errcount + "次不正确");
            Object toJSON = JSON.toJSON(map);
            writer.write(toJSON.toString());
            return false;
        }
        stringRedisTemplate.delete(username + CODE);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {


        ShiroUser shiroUser = ShiroKit.getUser();
        if (shiroUser!=null) {
            //该用户登录ip
            String ipAddr = IPUtils.getIpAddr(request);
            stringRedisTemplate.opsForValue().set(shiroUser.getAccount()+LOGINFLAG,ipAddr);
        }
        super.postHandle(request, response, handler, modelAndView);
    }
}
