package com.example.demo.config;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 请求日志过滤器
 * 用于记录请求和响应的详细信息，特别是在出现 JSON 解析错误时帮助调试
 */
@Component
public class RequestLoggingFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // 包装请求和响应以便读取内容
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);

        try {
            // 继续过滤链
            filterChain.doFilter(wrappedRequest, wrappedResponse);
        } catch (Exception e) {
            // 如果出现异常，记录请求详情
            logRequestDetails(wrappedRequest, e);
            throw e;
        } finally {
            // 记录响应状态
            if (wrappedResponse.getStatus() >= 400) {
                // 只有在出现错误时才记录详细的请求信息
                logRequestDetails(wrappedRequest, null);
            }

            // 复制响应内容到原始响应
            wrappedResponse.copyBodyToResponse();
        }
    }

    private void logRequestDetails(ContentCachingRequestWrapper request, Exception exception) {
        try {
            String uri = request.getRequestURI();
            String method = request.getMethod();

            // 只记录POST/PUT/PATCH请求的详情
            if ("POST".equals(method) || "PUT".equals(method) || "PATCH".equals(method)) {
                logger.error("=== 请求详情 ({}出现问题) ===", exception != null ? "捕获异常" : "响应错误");
                logger.error("URI: {} {}", method, uri);
                logger.error("Content-Type: {}", request.getContentType());
                logger.error("Content-Length: {}", request.getContentLength());

                // 获取请求体内容
                byte[] content = request.getContentAsByteArray();
                if (content.length > 0) {
                    String body = getContentAsString(content, request.getCharacterEncoding());
                    logger.error("请求体内容 (前1000字符):");
                    logger.error("{}", body.length() > 1000 ? body.substring(0, 1000) + "..." : body);

                    // 检查是否包含可疑的反斜杠
                    if (body.contains("\\")) {
                        logger.error("⚠️ 警告：请求体中包含反斜杠字符，这可能导致 JSON 解析错误");
                        // 显示反斜杠周围的上下文
                        int index = body.indexOf("\\");
                        if (index >= 0) {
                            int start = Math.max(0, index - 20);
                            int end = Math.min(body.length(), index + 20);
                            logger.error("反斜杠位置附近的内容: [{}]", body.substring(start, end));
                        }
                    }
                }

                if (exception != null) {
                    logger.error("异常: {}", exception.getMessage());
                }
            }
        } catch (Exception e) {
            logger.error("记录请求详情时出错", e);
        }
    }

    private String getContentAsString(byte[] content, String charset) {
        try {
            return new String(content, charset != null ? charset : "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return "[无法解码内容]";
        }
    }
}
