package handlers

import (
	"net/http"
	"strings"
)

// mapPlaylistError mappe les erreurs techniques vers des messages utilisateur clairs
// T0502: Create Playlist Error Handling Improvements
func mapPlaylistError(err error) (string, int) {
	if err == nil {
		return "Une erreur inconnue s'est produite", http.StatusInternalServerError
	}

	errStr := err.Error()

	// Erreurs de validation
	if strings.Contains(errStr, "invalid") || strings.Contains(errStr, "validation") {
		if strings.Contains(errStr, "title") {
			return "Le titre de la playlist est requis et doit contenir entre 1 et 200 caractères", http.StatusBadRequest
		}
		if strings.Contains(errStr, "description") {
			return "La description ne peut pas dépasser 1000 caractères", http.StatusBadRequest
		}
		return "Les données fournies sont invalides. Veuillez vérifier vos informations", http.StatusBadRequest
	}

	// Erreurs de permissions
	if strings.Contains(errStr, "forbidden") || strings.Contains(errStr, "access denied") {
		return "Vous n'avez pas la permission d'effectuer cette action sur cette playlist", http.StatusForbidden
	}
	if strings.Contains(errStr, "unauthorized") {
		return "Vous devez être connecté pour effectuer cette action", http.StatusUnauthorized
	}

	// Erreurs de ressources non trouvées
	if strings.Contains(errStr, "not found") {
		if strings.Contains(errStr, "playlist") {
			return "Cette playlist n'existe pas ou a été supprimée", http.StatusNotFound
		}
		if strings.Contains(errStr, "track") {
			return "Ce morceau n'existe pas ou n'est pas accessible", http.StatusNotFound
		}
		if strings.Contains(errStr, "user") {
			return "Cet utilisateur n'existe pas", http.StatusNotFound
		}
		return "La ressource demandée est introuvable", http.StatusNotFound
	}

	// Erreurs de conflit
	if strings.Contains(errStr, "already exists") || strings.Contains(errStr, "duplicate") {
		return "Cette ressource existe déjà", http.StatusConflict
	}

	// Erreurs réseau/base de données
	if strings.Contains(errStr, "network") || strings.Contains(errStr, "timeout") || strings.Contains(errStr, "connection") {
		return "Une erreur réseau s'est produite. Veuillez réessayer dans quelques instants", http.StatusServiceUnavailable
	}
	if strings.Contains(errStr, "database") || strings.Contains(errStr, "failed to") {
		return "Une erreur de base de données s'est produite. Veuillez réessayer plus tard", http.StatusInternalServerError
	}

	// Erreurs de quota/limite
	if strings.Contains(errStr, "quota") || strings.Contains(errStr, "limit") {
		return "Vous avez atteint la limite autorisée. Veuillez supprimer certaines ressources pour continuer", http.StatusForbidden
	}

	// Erreur par défaut
	return "Une erreur s'est produite lors du traitement de votre demande. Veuillez réessayer", http.StatusInternalServerError
}

// getPlaylistErrorStatusCode retourne le code de statut HTTP approprié pour une erreur de playlist
// T0502: Create Playlist Error Handling Improvements
func getPlaylistErrorStatusCode(err error) int {
	_, statusCode := mapPlaylistError(err)
	return statusCode
}

// getPlaylistErrorMessage retourne un message d'erreur utilisateur-friendly pour une erreur de playlist
// T0502: Create Playlist Error Handling Improvements
func getPlaylistErrorMessage(err error) string {
	message, _ := mapPlaylistError(err)
	return message
}

// isRetryableError détermine si une erreur peut être retentée
// T0502: Create Playlist Error Handling Improvements
func isRetryableError(err error) bool {
	if err == nil {
		return false
	}

	errStr := err.Error()

	// Erreurs non retryables
	if strings.Contains(errStr, "not found") ||
		strings.Contains(errStr, "forbidden") ||
		strings.Contains(errStr, "unauthorized") ||
		strings.Contains(errStr, "invalid") ||
		strings.Contains(errStr, "validation") ||
		strings.Contains(errStr, "already exists") ||
		strings.Contains(errStr, "duplicate") {
		return false
	}

	// Erreurs retryables (réseau, timeout, base de données temporaire)
	if strings.Contains(errStr, "network") ||
		strings.Contains(errStr, "timeout") ||
		strings.Contains(errStr, "connection") ||
		strings.Contains(errStr, "database") ||
		strings.Contains(errStr, "temporary") {
		return true
	}

	// Par défaut, les erreurs 5xx sont retryables
	return false
}
