package middleware

import (
	"net/http"
	"runtime/debug"

	"{{GO_MODULE}}/pkg/httpcontext"
	"{{GO_MODULE}}/pkg/logging"
)

// Recoverer is middleware that recovers from panics, logs the error with stack trace
// using slog, and returns a 500 Internal Server Error response.
//
// The middleware captures:
//   - request_id: For request correlation
//   - method, path, remote_addr: Request context
//   - panic: The recovered panic value
//   - stack_trace: Full stack trace for debugging
//
// Usage:
//
//	r.Use(middleware.RequestID())
//	r.Use(middleware.RequestLogger(logger))
//	r.Use(middleware.Recoverer(logger))
func Recoverer(logger *logging.Logger) func(next http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			defer func() {
				if rvr := recover(); rvr != nil {
					// Capture stack trace for debugging
					stack := debug.Stack()

					// Get request ID from context
					requestID, _ := httpcontext.GetRequestID(r.Context())

					// Log panic with full context and stack trace
					logger.Error("panic recovered",
						"request_id", requestID,
						"method", r.Method,
						"path", r.URL.Path,
						"remote_addr", r.RemoteAddr,
						"panic", rvr,
						"stack_trace", string(stack),
					)

					// Return 500 Internal Server Error to client
					http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
				}
			}()

			next.ServeHTTP(w, r)
		})
	}
}
