package auth

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

func contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		authHeader := c.GetHeader("Authorization")
		if !strings.HasPrefix(authHeader, "Bearer ") {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Missing token"})
			return
		}
		tokenStr := strings.TrimPrefix(authHeader, "Bearer ")

		claims, err := ParseJWT(tokenStr)
		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			return
		}

		c.Set("userId", claims.UserID)
		c.Set("email", claims.Email)
		c.Set("role", claims.Role)
		c.Next()
	}
}

func AuthorizeJWT(requiredRole string) gin.HandlerFunc {
	return func(c *gin.Context) {
		//A. Token aus Header holen
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization Header fehlt"})
			return
		}

		// "Bearer " entfernen
		tokenString := strings.TrimPrefix(authHeader, "Bearer ")
		if tokenString == authHeader {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Token Format muss 'Bearer <token>' sein"})
			return
		}

		claims, err := ParseJWT(tokenString)
		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Token ungültig oder abgelaufen"})
		}
		// --- NEUE LOGIK ---
		// Wir prüfen: Hat der User die geforderte Rolle ODER ist er "admin"?
		// (Angenommen "admin" darf alles. Falls nicht, entferne den "admin"-Check)
		userHasRequiredRole := contains(claims.Role, requiredRole)
		userIsAdmin := contains(claims.Role, "admin")

		if !userHasRequiredRole && !userIsAdmin {
			c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "Keine Berechtigung"})
			return
		}

		// User und Rollen im Context speichern (als Interface{}, daher später casten)
		c.Set("userId", claims.UserID)
		c.Set("email", claims.Email)
		c.Set("role", claims.Role)

		c.Next()
	}
}
