// Package observability provides tracer, metrics, and structured logging
// initialization for the api-gateway.
package observability

import (
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
)

// 业务指标（W5 裁决：7 个业务 metrics）
var (
	httpRequestsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "api_gateway_http_requests_total",
		Help: "Total number of HTTP requests processed by the gateway.",
	}, []string{"method", "endpoint", "status"})

	httpRequestDurationSeconds = promauto.NewHistogramVec(prometheus.HistogramOpts{
		Name:    "api_gateway_http_request_duration_seconds",
		Help:    "HTTP request processing duration in seconds.",
		Buckets: prometheus.DefBuckets,
	}, []string{"method", "endpoint"})

	circuitBreakerState = promauto.NewGaugeVec(prometheus.GaugeOpts{
		Name: "api_gateway_circuit_breaker_state",
		Help: "Circuit breaker state by service: 1=active state, 0=inactive.",
	}, []string{"service", "state"})

	rateLimitedTotal = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "api_gateway_rate_limited_total",
		Help: "Total number of rate-limited requests.",
	}, []string{"ip"})

	proxyUpstreamDurationSeconds = promauto.NewHistogramVec(prometheus.HistogramOpts{
		Name:    "api_gateway_proxy_upstream_duration_seconds",
		Help:    "Upstream proxy response duration in seconds.",
		Buckets: prometheus.DefBuckets,
	}, []string{"upstream"})

	jwksRefreshTotal = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "api_gateway_jwks_refresh_total",
		Help: "Total number of JWKS cache refresh attempts.",
	}, []string{"result"})

	authFailuresTotal = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "api_gateway_auth_failures_total",
		Help: "Total number of authentication failures.",
	}, []string{"reason"})
)

// Metrics 返回 HTTP 请求统计中间件（W5 裁决）。
// 记录请求总数（method/endpoint/status）与请求延迟（method/endpoint）。
// endpoint 使用 gin 路由模式（c.FullPath()）避免高基数。
func Metrics() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		c.Next()

		duration := time.Since(start).Seconds()
		status := strconv.Itoa(c.Writer.Status())
		endpoint := c.FullPath()
		if endpoint == "" {
			endpoint = "unknown"
		}
		httpRequestsTotal.WithLabelValues(c.Request.Method, endpoint, status).Inc()
		httpRequestDurationSeconds.WithLabelValues(c.Request.Method, endpoint).Observe(duration)
	}
}

// IncAuthFailure 递增鉴权失败计数器。
func IncAuthFailure(reason string) {
	authFailuresTotal.WithLabelValues(reason).Inc()
}

// IncRateLimited 递增限流计数器。
func IncRateLimited(ip string) {
	rateLimitedTotal.WithLabelValues(ip).Inc()
}

// IncJWKSRefresh 递增 JWKS 刷新计数器（result: success/failure）。
func IncJWKSRefresh(result string) {
	jwksRefreshTotal.WithLabelValues(result).Inc()
}

// SetCircuitBreakerState 更新熔断器状态 gauge。
func SetCircuitBreakerState(service, state string, value float64) {
	circuitBreakerState.WithLabelValues(service, state).Set(value)
}

// ObserveProxyUpstreamDuration 记录上游代理响应延迟。
func ObserveProxyUpstreamDuration(upstream string, duration time.Duration) {
	proxyUpstreamDurationSeconds.WithLabelValues(upstream).Observe(duration.Seconds())
}
