package middlewares

import (
	"net/http"

	"abuse_registration_poc/internal/handlers"
	"abuse_registration_poc/internal/models"
)

var routePermissions = map[string]map[string][]string{
	"GET": {
		"/api/v1/categories":        {models.RoleReader, models.RoleAdmin},
		"/api/v1/locations":         {models.RoleReader, models.RoleAdmin},
		"/api/v1/registrations":     {models.RoleReader, models.RoleAdmin},
		"/api/v1/registrations/:id": {models.RoleReader, models.RoleAdmin},
	},
	"POST": {
		"/api/v1/registrations": {models.RoleAdmin},
		"/api/v1/reset":         {models.RoleAdmin},
	},
	"PUT": {
		"/api/v1/registrations/:id": {models.RoleAdmin},
	},
	"DELETE": {
		"/api/v1/registrations/:id": {models.RoleAdmin},
	},
}

func DynamicAuthorize(routePattern string, next http.Handler) http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		role, exists := RoleFromContext(request.Context())
		if !exists {
			handlers.WriteJSON(writer, http.StatusForbidden, map[string]string{"message": "Access denied."})
			return
		}

		if !hasPermission(role, request.Method, routePattern) {
			handlers.WriteJSON(writer, http.StatusForbidden, map[string]string{"message": "Access denied to this resource."})
			return
		}

		next.ServeHTTP(writer, request)
	})
}

func Protected(routePattern string, next http.Handler) http.Handler {
	return Authenticate(DynamicAuthorize(routePattern, next))
}

func hasPermission(role string, method string, path string) bool {
	methodPermissions, ok := routePermissions[method]
	if !ok {
		return false
	}
	roles, ok := methodPermissions[path]
	if !ok {
		return false
	}
	for _, allowed := range roles {
		if allowed == role {
			return true
		}
	}
	return false
}
