package httpserver

import (
	"net/http"
	"strings"

	"github.com/go-chi/chi/v5/middleware"

	"nexavpn/backend/internal/apiutil"
	"nexavpn/backend/internal/auth"
	"nexavpn/backend/internal/requestctx"
)

func BaseMiddleware(next http.Handler) http.Handler {
	return middleware.RealIP(middleware.RequestID(middleware.Logger(next)))
}

func AuthMiddleware(jwtSecret string) func(http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			header := r.Header.Get("Authorization")
			if !strings.HasPrefix(header, "Bearer ") {
				apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "missing bearer token")
				return
			}

			claims, err := auth.ParseAccessToken(jwtSecret, strings.TrimPrefix(header, "Bearer "))
			if err != nil {
				apiutil.Error(w, http.StatusUnauthorized, "unauthorized", "invalid access token")
				return
			}

			ctx := requestctx.WithClaims(r.Context(), claims)
			next.ServeHTTP(w, r.WithContext(ctx))
		})
	}
}

func AdminOnly(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		claims, ok := requestctx.ClaimsFromContext(r.Context())
		if !ok || claims.Role != "admin" {
			apiutil.Error(w, http.StatusForbidden, "forbidden", "admin role required")
			return
		}
		next.ServeHTTP(w, r)
	})
}
