package com.erp.gateway.filter;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 网关API调用量统计过滤器
 * 
 * 使用Micrometer计数器记录每个API的调用量：
 * - 总量计数（api.requests.total）
 * - 按状态码计数（api.requests.{status}）
 * - 按服务计数（api.requests.{service}.total）
 * - 响应时间统计（api.latency）
 * 
 * 暴露指标：通过 /actuator/prometheus 或 /actuator/metrics 访问
 */
@Slf4j
@Component
public class MetricsFilter implements GlobalFilter, Ordered {

    private final MeterRegistry meterRegistry;
    
    /** 按路径+方法的请求计数器（使用ConcurrentHashMap避免内存泄漏） */
    private final ConcurrentHashMap<String, Counter> pathCounters = new ConcurrentHashMap<>();
    
    /** 按状态码的计数器 */
    private final ConcurrentHashMap<String, Counter> statusCounters = new ConcurrentHashMap<>();
    
    /** 按服务的计数器 */
    private final ConcurrentHashMap<String, Counter> serviceCounters = new ConcurrentHashMap<>();
    
    /** 全局请求计时器 */
    private final Timer globalTimer;

    public MetricsFilter(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 全局请求计数器和延迟计时器
        Counter.builder("api.requests.total")
                .description("API请求总数")
                .register(meterRegistry);
        
        this.globalTimer = Timer.builder("api.latency")
                .description("API响应延迟")
                .publishPercentiles(0.5, 0.95, 0.99)
                .register(meterRegistry);
        
        log.info("[MetricsFilter] Micrometer指标收集器初始化完成");
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        String method = request.getMethod().name();
        String service = resolveServiceName(request);
        
        // 跳过actuator和健康检查路径
        if (isSkippablePath(path)) {
            return chain.filter(exchange);
        }
        
        long startTime = System.nanoTime();
        
        return chain.filter(exchange)
                .doFinally(signalType -> {
                    long duration = System.nanoTime() - startTime;
                    int statusCode = getStatusCode(exchange);
                    String statusKey = String.valueOf(statusCode);
                    String serviceKey = service.toLowerCase();
                    
                    // 1. 记录全局请求计数
                    Counter.builder("api.requests.total")
                            .description("API请求总数")
                            .tag("method", method)
                            .register(meterRegistry)
                            .increment();
                    
                    // 2. 记录按状态码的计数
                    statusCounters.computeIfAbsent(statusKey, k ->
                            Counter.builder("api.requests.status")
                                    .description("按状态码统计的请求数")
                                    .tag("status", statusKey)
                                    .register(meterRegistry)
                    ).increment();
                    
                    // 3. 记录按服务的计数
                    serviceCounters.computeIfAbsent(serviceKey, k ->
                            Counter.builder("api.requests.service")
                                    .description("按目标服务统计的请求数")
                                    .tag("service", serviceKey)
                                    .register(meterRegistry)
                    ).increment();
                    
                    // 4. 记录路径级计数（带方法）
                    String pathKey = method + ":" + path;
                    pathCounters.computeIfAbsent(pathKey, k ->
                            Counter.builder("api.requests.path")
                                    .description("按路径统计的请求数")
                                    .tag("path", truncatePath(path, 50))
                                    .tag("method", method)
                                    .register(meterRegistry)
                    ).increment();
                    
                    // 5. 记录延迟
                    globalTimer.record(duration, TimeUnit.NANOSECONDS);
                    
                    Timer.builder("api.latency.path")
                            .description("按路径统计的响应延迟")
                            .tag("path", truncatePath(path, 50))
                            .tag("method", method)
                            .publishPercentiles(0.5, 0.95, 0.99)
                            .register(meterRegistry)
                            .record(duration, TimeUnit.NANOSECONDS);
                    
                    log.debug("[Metrics] {} {} -> {} ({}ms) [{}]",
                            method, path, service,
                            TimeUnit.NANOSECONDS.toMillis(duration),
                            statusCode);
                });
    }

    /**
     * 从请求中解析目标服务名
     */
    private String resolveServiceName(ServerHttpRequest request) {
        String path = request.getURI().getPath();
        
        // 从路径中提取服务名，如 /order-service/api/v1/orders -> order-service
        if (path.startsWith("/")) {
            String[] segments = path.substring(1).split("/");
            if (segments.length > 0) {
                String firstSegment = segments[0];
                // 去掉可能的版本前缀如 api/v1
                if (firstSegment.equals("api") && segments.length > 2) {
                    return segments[1];
                }
                return firstSegment;
            }
        }
        return "unknown";
    }

    /**
     * 获取HTTP状态码
     */
    private int getStatusCode(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        if (response.getStatusCode() != null) {
            return response.getStatusCode().value();
        }
        return 0;
    }

    /**
     * 跳过不需要统计的路径
     */
    private boolean isSkippablePath(String path) {
        return path.startsWith("/actuator") ||
               path.startsWith("/swagger") ||
               path.startsWith("/v3/api-docs") ||
               path.equals("/health") ||
               path.equals("/favicon.ico");
    }

    /**
     * 截断过长的路径标签（Micrometer对高基数标签有限制）
     */
    private String truncatePath(String path, int maxLen) {
        if (path.length() <= maxLen) {
            return path;
        }
        // 保留前半部分 + 省略号
        return path.substring(0, maxLen - 3) + "..";
    }

    @Override
    public int getOrder() {
        return -80; // 在日志过滤器之后执行
    }
}
