package org.hzhub.gateway.filter;

import org.reactivestreams.Publisher;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 429 限流响应格式化过滤器
 * Spring Cloud Gateway 的 RequestRateLimiter 调用 setComplete() 返回空响应
 * 此过滤器拦截 429 状态码并注入统一的 JSON 响应体
 */
@Component
public class RateLimitResponseFilter implements WebFilter, Ordered {

    private static final byte[] RATE_LIMIT_JSON =
        "{\"code\":429,\"msg\":\"请求过于频繁，请稍后重试\",\"data\":null}"
            .getBytes(StandardCharsets.UTF_8);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpResponse originalResponse = exchange.getResponse();

        ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {

            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                // 如果限流器返回了空 body 但状态是 429
                if (getRawStatusCode() == HttpStatus.TOO_MANY_REQUESTS.value()) {
                    return writeRateLimitResponse();
                }
                return super.writeWith(body);
            }

            @Override
            public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
                if (getRawStatusCode() == HttpStatus.TOO_MANY_REQUESTS.value()) {
                    return writeRateLimitResponse();
                }
                return super.writeAndFlushWith(body);
            }

            @Override
            public Mono<Void> setComplete() {
                // 限流器完成响应时（空 body），注入 JSON
                if (getRawStatusCode() == HttpStatus.TOO_MANY_REQUESTS.value()) {
                    return writeRateLimitResponse();
                }
                return super.setComplete();
            }

            private Mono<Void> writeRateLimitResponse() {
                getHeaders().setContentType(MediaType.APPLICATION_JSON);
                getHeaders().setContentLength(RATE_LIMIT_JSON.length);
                return getDelegate().writeWith(
                    Mono.just(bufferFactory().wrap(RATE_LIMIT_JSON))
                );
            }
        };

        return chain.filter(exchange.mutate().response(decoratedResponse).build());
    }

    @Override
    public int getOrder() {
        return -200; // 在限流之后执行
    }
}
