package com.ssm.filter;

import cn.hutool.extra.servlet.ServletUtil;
import com.google.gson.Gson;
import com.ssm.manage.response.*;
import com.ssm.manage.service.SsmSysRolePowerService;
import com.ssm.manage.utils.Constant;
import com.ssm.manage.utils.SessionHelp;
import com.ssm.manage.utils.StringUtils;
import com.ssm.util.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;

@Slf4j
//@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisClient<UserResponse> redisClient;

    private static final ThreadLocal<StaffResponse> threadLocal = new ThreadLocal<>();

    @Autowired
    private RedisClient<StaffResponse> staffResponseRedisClient;
    @Autowired
    private RedisClient<StaffTemporaryVo> staffTemporaryVoRedisClient;

    @Autowired
    private RedisClient<MemberResponse> memberResponseRedisClient;

    @Autowired
    private SsmSysRolePowerService ssmSysRolePowerService;

    private static String STAFF_KEY = "staffKey";
    private static String USER_KEY = "userKey";
    private static String MEMBER_KEY = "memberKey";
    public static String hduserKey = "hduserKey";


    @Override
    public boolean preHandle(@NotNull HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String clientIP = ServletUtil.getClientIP(request);

        StringBuffer requestURL = request.getRequestURL();
        if (requestURL.toString().contains("error") || requestURL.toString().contains("swagger")) {
            return true;
        }
        HttpSession session = request.getSession();

        String cacheToken = SessionHelp.getToken(session);
        String loginAccount = SessionHelp.getLoginAccount(session);
        String token = request.getHeader("token");

//        //判断session中是否有登录信息
//        if (StringUtils.isNotBlank(loginAccount) && StringUtils.isNotBlank(token) && token.equals(cacheToken)) {
//            return true;
//        }
        if (StringUtils.isBlank(token)){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = null;
            GenericResponse genericResponse = new GenericResponse();
            genericResponse.setCodeAndMsg(ResponseCode.TOKEN_IS_EXPIRED);
            Gson gson = new Gson();
            try {
                out = response.getWriter();
                out.append(gson.toJson(genericResponse));
            } catch (Exception e) {
                log.error("LoginInterceptor.preHandle", e);
            } finally {
                if (out != null) {
                    out.close();
                }
                return false;
            }
        }else {
            //根据token去做验证
            if (redisClient.hasKey(USER_KEY + loginAccount)){
                UserResponse userResponse = redisClient.get(USER_KEY + loginAccount);
                cacheToken = userResponse.getToken();
                if (StringUtils.isNotBlank(cacheToken) && cacheToken.equals(token)){
                    return true;
                }else {
                    //同一个账户 当前请求token和redis中最新的token不一致 销毁当前Session
                    session.invalidate();
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = null;
                    GenericResponse genericResponse = new GenericResponse();
                    genericResponse.setCodeAndMsg(ResponseCode.TOKEN_IS_EXPIRED);
                    Gson gson = new Gson();
                    try {
                        out = response.getWriter();
                        out.append(gson.toJson(genericResponse));
                    } catch (Exception e) {
                        log.error("LoginInterceptor.preHandle", e);
                    } finally {
                        if (out != null) {
                            out.close();
                        }
                        return false;
                    }
                }
            }
            else if (staffResponseRedisClient.hasKey(STAFF_KEY + loginAccount)){
                StaffResponse staffResponse = staffResponseRedisClient.get(STAFF_KEY + loginAccount);
                cacheToken = staffResponse.getToken();
                if (StringUtils.isNotBlank(cacheToken) && cacheToken.equals(token)){
                    threadLocal.set(staffResponse);
                    return true;
                }else {
                    //同一个账户 当前请求token和redis中最新的token不一致 销毁当前Session
                    session.invalidate();
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = null;
                    GenericResponse genericResponse = new GenericResponse();
                    genericResponse.setCodeAndMsg(ResponseCode.TOKEN_IS_EXPIRED);
                    Gson gson = new Gson();
                    try {
                        out = response.getWriter();
                        out.append(gson.toJson(genericResponse));
                    } catch (Exception e) {
                        log.error("LoginInterceptor.preHandle", e);
                    } finally {
                        if (out != null) {
                            out.close();
                        }
                        return false;
                    }
                }
            }
            else if (memberResponseRedisClient.hasKey(MEMBER_KEY + loginAccount)){
                MemberResponse memberResponse = memberResponseRedisClient.get(MEMBER_KEY + loginAccount);
                cacheToken = memberResponse.getToken();
                if (StringUtils.isNotBlank(cacheToken) && cacheToken.equals(token)){
                    return true;
                }else {
                    //同一个账户 当前请求token和redis中最新的token不一致 销毁当前Session
                    session.invalidate();
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = null;
                    GenericResponse genericResponse = new GenericResponse();
                    genericResponse.setCodeAndMsg(ResponseCode.TOKEN_IS_EXPIRED);
                    Gson gson = new Gson();
                    try {
                        out = response.getWriter();
                        out.append(gson.toJson(genericResponse));
                    } catch (Exception e) {
                        log.error("LoginInterceptor.preHandle", e);
                    } finally {
                        if (out != null) {
                            out.close();
                        }
                        return false;
                    }
                }
            }
            else if (staffTemporaryVoRedisClient.hasKey(Constant.staffTemporary  + token)){
                StaffTemporaryVo staffTemporaryVo = staffTemporaryVoRedisClient.get(Constant.staffTemporary + token);
                cacheToken = staffTemporaryVo.getToken();
                if (StringUtils.isNotBlank(cacheToken) && cacheToken.equals(token)){
                    return true;
                }else {
                    //同一个账户 当前请求token和redis中最新的token不一致 销毁当前Session
                    session.invalidate();
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = null;
                    GenericResponse genericResponse = new GenericResponse();
                    genericResponse.setCodeAndMsg(ResponseCode.TOKEN_IS_EXPIRED);
                    Gson gson = new Gson();
                    try {
                        out = response.getWriter();
                        out.append(gson.toJson(genericResponse));
                    } catch (Exception e) {
                        log.error("LoginInterceptor.preHandle", e);
                    } finally {
                        if (out != null) {
                            out.close();
                        }
                        return false;
                    }
                }
            }
            else {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=utf-8");
                PrintWriter out = null;
                GenericResponse genericResponse = new GenericResponse();
                genericResponse.setCodeAndMsg(ResponseCode.NOT_LOGIN);
                Gson gson = new Gson();
                try {
                    out = response.getWriter();
                    out.append(gson.toJson(genericResponse));
                } catch (Exception e) {
                    log.error("LoginInterceptor.preHandle", e);
                } finally {
                    if (out != null) {
                        out.close();
                    }
                    return false;
                }
            }
        }
    }

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

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    // 提供一个静态方法来获取当前线程中的用户信息
    public static StaffResponse getCurrentUserInfo() {
        return threadLocal.get();
    }
    public static void clearThreadLocal() {
        threadLocal.remove();
    }

}
