package top.continew.admin.config.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import cn.dev33.satoken.stp.StpUtil;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 第三方平台Token校验过滤器
 *
 * @author jiay
 * @since 2025/08/28 00:00
 */
@Slf4j
@Component
public class ThirdPartyTokenFilter implements Filter {

    /**
     * 需要校验的第三方平台接口路径
     */
    private static final List<String> THIRD_PARTY_PATHS = Arrays.asList("/billing/deduct", "/billing/callback");

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("ThirdPartyTokenFilter initialized");
    }

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest)request;
        HttpServletResponse httpResponse = (HttpServletResponse)response;

        String requestURI = httpRequest.getRequestURI();

        // 判断是否是需要校验的第三方平台接口
        boolean isThirdPartyApi = THIRD_PARTY_PATHS.stream().anyMatch(path -> requestURI.contains(path));

        if (isThirdPartyApi) {
            try {
                // 从请求头获取token
                String token = httpRequest.getHeader("Authorization");
                if (token == null || token.isEmpty()) {
                    token = httpRequest.getHeader("token");
                }

                if (token == null || token.isEmpty()) {
                    log.warn("第三方平台请求缺少token, URI: {}", requestURI);
                    sendErrorResponse(httpResponse, "缺少认证token");
                    return;
                }

                if (token.startsWith("Bearer ")) {
                    token = token.substring(7);
                }

                Object loginId = StpUtil.getLoginIdByToken(token);
                if (loginId == null) {
                    log.warn("第三方平台token无效, URI: {}, token: {}", requestURI, token);
                    sendErrorResponse(httpResponse, "token无效或已过期");
                    return;
                }
                log.debug("第三方平台token校验成功, URI: {}, userId: {}", requestURI, loginId);

            } catch (Exception e) {
                log.error("第三方平台token校验异常, URI: {}", requestURI, e);
                sendErrorResponse(httpResponse, "token校验失败");
                return;
            }
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        log.info("ThirdPartyTokenFilter destroyed");
    }

    /**
     * 发送错误响应
     */
    private void sendErrorResponse(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"success\":false,\"message\":\"" + message + "\",\"code\":401}");
    }
}