package com.it.rattan.monisuo.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.it.rattan.monisuo.common.Result;
import com.it.rattan.monisuo.context.UserContext;
import com.it.rattan.monisuo.util.JwtUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Token过滤器
 */
@Component
@Order(1)
public class TokenFilter implements Filter {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /** 不需要验证的路径 */
    private static final String[] EXCLUDE_PATHS = {
            "/api/user/register",
            "/api/user/login",
            "/admin/login",
            "/swagger-resources",
            "/v2/api-docs",
            "/webjars/",
            "/swagger-ui.html"
    };

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String uri = httpRequest.getRequestURI();

        // 检查是否排除路径
        for (String excludePath : EXCLUDE_PATHS) {
            if (uri.contains(excludePath)) {
                chain.doFilter(request, response);
                return;
            }
        }

        // 获取Token
        String token = httpRequest.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }

        if (token == null || token.isEmpty()) {
            writeUnauthorized(httpResponse, "请先登录");
            return;
        }

        // 验证Token
        if (!JwtUtil.isValid(token)) {
            writeUnauthorized(httpResponse, "Token已过期，请重新登录");
            return;
        }

        // 设置用户上下文
        UserContext context = new UserContext();
        context.setUserId(JwtUtil.getUserId(token));
        context.setUsername(JwtUtil.getUsername(token));
        context.setType(JwtUtil.getType(token));
        UserContext.set(context);

        try {
            chain.doFilter(request, response);
        } finally {
            UserContext.clear();
        }
    }

    private void writeUnauthorized(HttpServletResponse response, String message) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().write(OBJECT_MAPPER.writeValueAsString(Result.unauthorized(message)));
    }
}
