package com.mosty.common.token;

import com.mosty.common.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 *  token解析器
 * @author kevin
 * @date 2022/3/21 11:12 PM
 * @since 1.0.0
 */
@Slf4j
@SuppressWarnings("unused")
public class SysUserInterceptor implements HandlerInterceptor {
    public SysUserInterceptor() {
    }

    @PostConstruct
    public void init() {
    }

    public boolean preHandle(@Nullable HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler){
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }else{
            HandlerMethod handlerMethod =(HandlerMethod)handler;
            Method method = handlerMethod.getMethod();
            JwtSysUser sysUser =(JwtSysUser)method.getAnnotation(JwtSysUser.class);

            if(sysUser == null) {
                sysUser = (JwtSysUser) method.getDeclaringClass().getAnnotation(JwtSysUser.class);
            }
            if (sysUser == null) {
                return true;
            }else {
                UserInfo info = this.getUserInfoFromJwtToken(request, sysUser);
                if(info == null){
                    throw new BusinessException(401,"登录过期，请重新登录!!",(Object)null);
                } else {
                    UserInfoManager.set(info);
                    return true;
                }
            }

        }

    }

    public void afterCompletion(@Nullable HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Object handler, Exception ex) {
        UserInfoManager.clear();
    }

    private boolean setUserInfo(UserInfo info, JwtSysUser sysUser) {
//        if (this.mockUserInfo) {
//            return true;
//        }

//        UserInfoResp resp = this.userInfoCache.getUserInfo(info.getUserId(), sysUser.value());
//        if (resp == null) {
//            return false;
//        } else {
//            info.setMerchantId(resp.getMerchantId());
//            info.setMobile(resp.getMobile());
//            info.setUsername(resp.getUsername());
//            info.setAccount(resp.getAccount());
//            info.setStatus(resp.getStatus());
//            info.setEmail(resp.getEmail());
//            info.setSystemType(SystemTypeEnum.toEnum(resp.getSystem()));
//            info.setUserInfoType(UserInfoTypeEnum.toEnum(resp.getType()));
//            return true;
//        }
        return true;
    }

    private UserInfo getUserInfoFromJwtToken(HttpServletRequest request, JwtSysUser sysUser) {
        try {
            String token = request.getHeader("token");
            if (token == null) {
                token = request.getHeader("Authorization");
            }

            if (!StringUtils.isEmpty(token)) {
                return JWTUtil.getUserInfo(token);
            }
        } catch (Exception e) {
            log.error("解析token异常", e);
        }
        return null;
    }

    private void writeNeedLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.assemblyResponse(request, response, "用户未登录!", HttpStatus.UNAUTHORIZED, "BIZ.USER_NOT_LOGIN");
    }

    private void writeException(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.assemblyResponse(request, response, "网络异常,请稍后再试", HttpStatus.OK, "BIZ.BUSSINESS_EXCEPTION");
    }

    private void assemblyResponse(HttpServletRequest request, HttpServletResponse response, String errorMsg, HttpStatus unauthorized, String userNotLogin) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(unauthorized.value());
        String origin = request.getHeader("Origin");
        if (origin == null) {
            response.addHeader("Access-Control-Allow-Origin", "*");
        } else {
            response.addHeader("Access-Control-Allow-Origin", origin);
        }

        response.addHeader("Access-Control-Allow-Headers", "*");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
        PrintWriter writer = response.getWriter();
//        writer.write(JSON.toJSONString(new ResponseResult(userNotLogin, errorMsg)));
        writer.flush();
        writer.close();
    }
}
