package com.pharmacopoeia.config;

import com.pharmacopoeia.dto.ApiResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 对标记了 {@link UnifiedResponse} 的 Controller / 方法，
 * 自动将返回值包装为统一的 {@link ApiResponse} 格式：
 * {@code {code: 200, message: "ok", data: <原返回值> }}。
 *
 * <ul>
 *   <li>已经是 ApiResponse → 不包装</li>
 *   <li>流式（Flux / SSE）→ 不会进入此 Advice</li>
 * </ul>
 */
@RestControllerAdvice
public class UnifiedResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType,
                           Class<? extends HttpMessageConverter<?>> converterType) {
        // 类或方法上有 @UnifiedResponse 才包装
        if (returnType.getMethodAnnotation(UnifiedResponse.class) != null) {
            return true;
        }
        return returnType.getContainingClass().getAnnotation(UnifiedResponse.class) != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof ApiResponse) {
            return body;
        }
        return ApiResponse.success(body);
    }
}
