package middleware

import (
	"context"
	"log/slog"
	"net/http"
	"time"

	"github.com/TaruLab/keluargamart-backend/pkg/logger"
)

func contextWithRequestID(ctx context.Context, id string) context.Context {
	return context.WithValue(ctx, RequestIDKey, id)
}

// requestLogger wraps the ResponseWriter to capture status + bytes.
type requestLogger struct {
	http.ResponseWriter
	status int
	bytes  int64
}

func (rl *requestLogger) WriteHeader(status int) {
	rl.status = status
	rl.ResponseWriter.WriteHeader(status)
}

// WriteHeaderCompat kept for packages writing header before body.
func (rl *requestLogger) Write(b []byte) (int, error) {
	if rl.status == 0 {
		rl.status = http.StatusOK
	}
	n, err := rl.ResponseWriter.Write(b)
	rl.bytes += int64(n)
	return n, err
}

// Logging logs every request with request ID, method, path, status, duration.
func Logging(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		rl := &requestLogger{ResponseWriter: w}
		reqLogger := logger.WithRequestID(slog.Default(), RequestIDFrom(r.Context()))
		ctx := logger.ToContext(r.Context(), reqLogger)
		next.ServeHTTP(rl, r.WithContext(ctx))
		reqLogger.Info("http_request",
			"method", r.Method,
			"path", r.URL.Path,
			"status", rl.status,
			"duration_ms", time.Since(start).Milliseconds(),
			"bytes", rl.bytes,
		)
	})
}
