package com.m2pool.lease.config;

import com.m2pool.common.redis.service.RedisService;
import com.m2pool.lease.annotation.LoginRequired;
import com.m2pool.lease.entity.LeaseUser;
import com.m2pool.lease.exception.AuthException;
import com.m2pool.lease.redis.RedisAuthKey;
import com.m2pool.lease.utils.JwtUtils;
import com.m2pool.lease.utils.UserThreadLocal;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import static com.m2pool.lease.utils.JwtUtils.AUTHENTICATION;
import static com.m2pool.lease.utils.JwtUtils.EXPIRETIME;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        String uri = request.getRequestURI();
        if (uri.contains("/doc.html") || uri.contains("/webjars/")
                || uri.contains("/swagger-resources") || uri.contains("/v2/api-docs")) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 获取方法上的注解
        LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
        // 如果方法上没有注解，获取类上的注解
        if (loginRequired == null) {
            loginRequired = handlerMethod.getBeanType().getAnnotation(LoginRequired.class);
        }

        // 如果没有注解或者注解值为true，则校验token
        if (loginRequired == null || loginRequired.value()) {
            String token = request.getHeader(AUTHENTICATION);
            System.out.println("用户token:"+token);
            if (token == null || !isValidToken(token)) {
                throw new AuthException("用户未登录");
            }
        }

        return true;
    }



    /**
     * 验证token 并刷新token
     */
    private boolean isValidToken(String token) {
        String userEmail = JwtUtils.getUserName(token);
        //1.把userEmail存入ThreadLocal 本地线程变量中
        UserThreadLocal.setUserEmail(userEmail);
        //2.校验token是否过期
        String userKey = RedisAuthKey.getUserLoginKey(userEmail);
        LeaseUser loginUser = redisService.getCacheObject(userKey);
        if (loginUser == null){
            return false;
        }
        //3.刷新token 过期时间
        redisService.setCacheObject(userKey, loginUser, EXPIRETIME, TimeUnit.MINUTES);

        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        UserThreadLocal.remove();
    }
}
