package com.simuwang.deploy.config;

import cn.hutool.json.JSONUtil;
import com.smppw.common.pojo.ResultVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author wangzaijun
 * @date 2023/8/12 16:39
 * @description 全局的结果处理工具（匿名访问的接口不走这里，还要排查原因）
 */
@RestControllerAdvice
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        // 全部接口都要拦截？
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType,
                                  @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
        if (body instanceof String) {
            // 当响应体是String类型时
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            return JSONUtil.toJsonStr(ResultVo.ok(body));
        }
        if (body instanceof ResultVo<?>) {
            // 已经包装过的结果无需再次包装
            return body;
        }
        if (body instanceof ResponseEntity<?> entity) {
            HttpStatusCode statusCode = entity.getStatusCode();
            if (statusCode.value() == HttpStatus.OK.value()) {
                return ResultVo.ok(entity.getBody());
            }
            this.logger.warn("全局统一数据返回，接口{} 请求错误\n{}", request.getURI(), body);
            return ResultVo.fail(statusCode.value(), "接口请求错误");
        }
        // 对响应体进行包装
        return ResultVo.ok(body);
    }
}
